Java UDP를 이용한 Magic Packet Sender

개인적으로 쓰려고 Java UDP를 이용하여 Magic Packet을 전송하는 프로그램을 만들어봤다.

실행 화면

Java Magic Packet Sender
Java Magic Packet Sender







관련 소스



import java.io.*;
import java.net.*;
import java.util.*;

public class Main extends javax.swing.JFrame
{

 public Main()
 {
  initComponents();
 }

 private void initComponents()
 {
  this.setTitle(“Java Magic Packet Sender”);
  bTrans = new javax.swing.JButton();
  bClose = new javax.swing.JButton();
  mac_address = new javax.swing.JTextField();
  mac_address.setText(“”);
  mac_address.setColumns(20);
  bClose.setText(“닫기”);
  bClose.addActionListener(new java.awt.event.ActionListener()
  {
   public void actionPerformed(java.awt.event.ActionEvent evt)
   {
    ExitActionPerformed(evt);
   }
  });
  bTrans.setText(“전송”);
  bTrans.addActionListener(new java.awt.event.ActionListener()
  {
   public void actionPerformed(java.awt.event.ActionEvent evt)
   {
    TransActionPerformed(evt);
   }
  });
  getContentPane().add(“East”, bTrans);
  getContentPane().add(“South”, bClose);
  getContentPane().add(“Center”, mac_address);
  setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
  pack();
 }

 private boolean parseMacAddress(String text)
 {
  boolean result = true;
  if (text.equals(“”))
   return false;
  try
  {
   int minus = text.indexOf(“-“);
   int colon = text.indexOf(“:”);
   if (minus >= 0)
   {
    StringTokenizer token = new StringTokenizer(text, “-“, false);
    int count = token.countTokens();
    mac = new byte[count];
    for (int i = 0; i < count; i++)
    {
     String to = token.nextToken();
     byte temp = (byte)(Integer.parseInt(to, 16));
     mac[i] = temp;
    }
   }
   else if (colon >= 0)
   {
    StringTokenizer token = new StringTokenizer(text, “:”, false);
    int count = token.countTokens();
    mac = new byte[count];
    for (int i = 0; i < count; i++)
    {
     String to = token.nextToken();
     byte temp = (byte)(Integer.parseInt(to, 16));
     mac[i] = temp;
    }
   }
   else
   {
    result = false;
   }

  }
  catch (Exception e)
  {
   result = false;
  }
  return result;
 }

 private void TransActionPerformed(java.awt.event.ActionEvent evt)
 {

  if (mac_address.getText() != null && !mac_address.getText().equals(“”))
  {
   if (parseMacAddress(mac_address.getText()))
   {
    try
    {
     int total_length = header.length + (mac.length * 16);
     message = new byte[total_length];
     for (int i = 0; i < header.length; i++)
     {
      message[i] = header[i];
     }
     int count = header.length;
     for (int j = 0; j < 16; j++)
     {
      for (int i = 0; i < mac.length; i++)
      {
       message[count++] = mac[i];
      }
     }
     InetAddress group = InetAddress.getByName(“255.255.255.255”);
     DatagramSocket ds = new DatagramSocket(6);
     DatagramPacket dsheaer = new DatagramPacket(message, message.length, new InetSocketAddress(“255.255.255.255”, 6));
     ds.send(dsheaer);
     ds.close();
    }
    catch (Exception e)
    {
     e.printStackTrace();
    }
   }
  }
 }

 private void ExitActionPerformed(java.awt.event.ActionEvent evt)
 {
  this.dispose();
 }

 public static void main(String args[])
 {

  if (args != null && args.length > 1)
  {

  }
  java.awt.EventQueue.invokeLater(new Runnable()
  {
   public void run()
   {
    new Main().setVisible(true);
   }
  });
 }

 private byte[] header = { (byte)255, (byte)255, (byte)255, (byte)255, (byte)255, (byte)255 };
 private byte[] mac;
 private byte[] message;
 private javax.swing.JButton bTrans;
 private javax.swing.JButton bClose;
 private javax.swing.JTextField mac_address;

}

JDK1.6 DOM을 이용한 간단 XML 파싱

import java.io.File;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.apache.log4j.Logger;


public class XMLReader {
    private static final Logger logger = Logger.getLogger(com.msc.sdm.ic.pub.SmgrDbObjectReader.class);
    private String szXMLFileName;
    private File xmlFile;
    private Document doc = null;
    public SmgrDbObjectReader(){
        szXMLFileName = “”;
        xmlFile = null;               
    }
   
    public void setXMLFile(File file){
        xmlFile = file;
    }
   
    public void readXMLFile(){
       
        if(xmlFile != null && xmlFile.exists() == true){
           try{
           DocumentBuilderFactory docBuilderFactory =
   DocumentBuilderFactory.newInstance();
           DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
           doc = docBuilder.parse(xmlFile);
           Element elem = doc.getDocumentElement();
           String root_node = elem.getNodeName();
           NodeList node_list = elem.getChildNodes();
          
           int leng = node_list.getLength();
  for (int i = 0; i < leng; i++) {
                    Node node = node_list.item(i);
                    if(node.getNodeType() == node.ELEMENT_NODE){
                        //logger.warn(“Node Type : ” + node.getNodeType());
                        NodeList childList = node.getChildNodes();                   
                        logger.warn(“Node Name :”+node.getNodeName());
                        for( int  j = 0 ;  j < childList.getLength(); j++){
                            Node child = childList.item(j);
                            if(child.getNodeType() == child.ELEMENT_NODE){
                                //logger.warn(“Child Type   : “+ child.getNodeType());
                                logger.warn(“Child Node   : “+ child.getNodeName());
                                logger.warn(“Child Content: “+ child.getTextContent());
                                NamedNodeMap attrmap = childList.item(j).getAttributes();
                                if(attrmap != null)
                                    for( int  k = 0 ;  k < attrmap.getLength(); k++){
                                        Node attr_node = attrmap.item(k);
                                        logger.warn(“Attribute Node   : “+ attr_node.getNodeName());
                                        logger.warn(“Attribute Content: “+ attr_node.getTextContent());
                                    }
                            }
                        }
                    }
  }
           }catch(Exception e){
               e.printStackTrace();
           }
        }
    }                  
}

Table용 Page Util

package kr.or.struts.util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * <p>Title: PageUtil </p>
 * <p>Description: Table Page Util </p>
 * <p>Copyright: Copyright (c) 2007 Maxoft.Inc</p>
 * <p>Company: Maxoft.Inc </p>
 * @author Kim sooki
 * @version 1.0
 */
public class PageUtil {
 // 객체없이 사용하는 utitlity클래스
 private PageUtil(){
 }
 
 private static Log logger = LogFactory.getLog(PageUtil.class);
 
// 글의 갯수만큼 입력받아 모든페이지의 링크를 생성
// String page : page이름
// int total : 전체 글 갯수
// int showLine : 한페이지에 표시될 글의 갯수
// int current : 현재페이지
 public static String getAllPageLink(String page,int total, int showLine,int current){
  if(total == 0)
   return “”;
  StringBuffer buffer = new StringBuffer();  
  int count = 1;  
  for(int i = 1; i <= total; i=i+showLine){
   buffer.append(“<a href=”);
   buffer.append(page);
   buffer.append(“PageNo=”);  
   buffer.append(Integer.toString(count));
   buffer.append(“>”);
   if(count == current){
     buffer.append(“<strong>”);
    buffer.append(Integer.toString(count));
     buffer.append(“</strong>”);  
   } else

   buffer.append(Integer.toString(count));
   buffer.append(“</A>&nbsp;&nbsp;”);  
   count++;
  }
  return buffer.toString();
 }
 
 // 전체 글수와 현재페이지수를 입력하여 전체 페이지수를 구함
 public static int getMaxPage(int total, int showLine){
  if(total <= 0){
   return 0;
  }
  int temp = total / showLine;
  int mode = total % showLine;
  if(mode != 0){
   temp++;
  }
  return temp;
 }
 
 // 페이지에서 시작되는 가장 나중번호를 구한다.
 public static int getRowStart(int total, int showLine,int currentPage){
  if(total <= showLine){
   return total;
  }
  int temp = showLine * (currentPage-1);
  temp = total – temp;
  if(temp < 0){
   temp = 0;
  }
  return temp;
 }
 // 페이지에서 시작되는 가장 적은 번호를 구한다.
 public static int getRowEnd(int total, int showLine,int currentPage){
  if(total <= showLine){
   return 0;
  }
  int temp = (showLine * (currentPage -1)) + showLine;
  temp = total – temp;
  if(temp < 0 ){
   temp = 0;
  } 
  return temp;
 }
}

Property Facade

Property Facade를 작성하여 여러 Property설정파일을 읽어들여  세팅하도록 해봤다.


public class PropertiesFacade
{


    public PropertiesFacade()
    {
    }


    public void loadProperties(String fileName)
    {
        if(properties == null)
            try
            {
                String localFilePath = “resources/config/”;
                String jarFilePath = “/config/”;
                URL url = getClass().getResource(jarFilePath + fileName);
                InputStream fileIn;
                if(url == null)
                    fileIn = new FileInputStream(localFilePath + fileName);
                else
                if(url.getFile().toString().indexOf(“!”) != -1)
                {
                    JarURLConnection jarConn = (JarURLConnection)url.openConnection();
                    fileIn = jarConn.getInputStream();
                } else
                {
                    fileIn = new FileInputStream(url.getPath());
                }
                properties = new Properties();
                properties.load(fileIn);
                fileIn.close();
            }
            catch(Exception e)
            {


                e.printStackTrace();
               


            }
    }


    public Properties getProperties()
    {
        return properties;
    }


    public String getProperty(String name)
    {
        if(properties.getProperty(name) != null)
            return properties.getProperty(name);
        else
            return “null”;
    }



    private Properties properties;


}


  getProperties()나 getProperty(name)을 이용하여 설정된 프로퍼티를 가져올수 있다.



 A class extends PropertiesFacade 처럼 상속하여 추가기능으로 사용하도록 만들었다..

String localFilePath = “resources/config/”;
String jarFilePath = “/config/”;
의 path를 적절히 바꾸어 사용하면 된다.

Key Mapped DBCP







 해쉬코드를 키값으로 하는 DBConnection Pool을 한번 만들어 보았다..



/**
 * <p>Title: ConnectionPool</p>
 * <p>Description: ConnectionPool</p>
 * <p>Copyright: Copyright (c) 2005 Maxoft.Inc</p>
 * <p>Company: Maxoft.Inc </p>
 * @author Kim sooki
 * @version 1.0
 */
package net.maxoft.center.controller;



import com.mysql.jdbc.Statement;
import java.io.*;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.*;
import net.maxoft.model.GlobalsFactory;
import org.apache.log4j.Logger;

public class ConnectionPool extends Thread {
 


  public static synchronized ConnectionPool getInstance(){
    if(instance == null){
      instance = new ConnectionPool();
    }
    return instance;
  }

 private ConnectionPool() {
    use = 0;
    close = false;
    available = 0;
   
    pool = new HashMap();
    keyMap = new HashMap();
   
    try{
      makeConnections();
    }catch(Exception e){
      e.printStackTrace();
      running = false;
      logger.debug(“Connection pool create fail!!”);
    }
    logger.info(“Connection Pool created!!”);  
 } 

 private void makeConnections() throws SQLException{
   
    for(int i = 0 ; i < ConnectionPool.MAX_ALIVE; i++){       
      try{
        Class.forName(GlobalsFactory.getGlobals().getProperty(“jdbcDriverClass”)).newInstance();
        String URL = GlobalsFactory.getGlobals().getProperty(“jdbcConnectionUrl”);
        Connection connection = DriverManager.getConnection(URL,”root”,”****”);
        int hash = connection.hashCode();
        pool.put(new Integer(hash), connection);
        keyMap.put(new Integer(hash), new Integer(hash));
        logger.debug(“Make connection  : “+ connection + ” / ” + hash + ”  / ” + available);
        available++;
       
      }catch(Exception e){
        e.printStackTrace();       
      }    
    }
   
    if( pool.size() == 0){
      throw new SQLException(“Create fail Connection!!!”);
    }
    logger.debug(“Connection : ” + available + ” created!”);
 }
 
  private Connection addConnection() throws SQLException {
    try{
      Class.forName(GlobalsFactory.getGlobals().getProperty(“jdbcDriverClass”)).newInstance();
      String URL = GlobalsFactory.getGlobals().getProperty(“jdbcConnectionUrl”);
      Connection connection = DriverManager.getConnection(URL,”root”,”****”);  
      logger.debug(connection);
      return connection;
     
    }catch(Exception e){
      e.printStackTrace();    
      throw new SQLException(“Connection create fail!”);
    }      
  }
 
  private void closeAllConnection(){
   
    Iterator iter = pool.keySet().iterator();
    while(iter.hasNext()){
      Integer hash = (Integer)iter.next();
      Connection con = null;
      try{
        con = (Connection)pool.remove(hash);
        con.close();
        available–;
       
      }catch(Exception e){
        e.printStackTrace();       
      }finally {
        if(con != null){
          try{
            con.close();
          }catch(Exception e){
          } // inner try – catch;
        }  // if(con != null)    
      } // outter try – catch;     
    } // while – iterator
    logger.debug(“Connection all closed!!”); 
  }
 
  protected void finalize() throws Throwable {
    if(close != false){
      close();     
    }
    super.finalize();
  } 



  public synchronized void close(){
    if(close == true)
      return;
    close = true;
    closeAllConnection();
    pool = null;
  }
 
  public synchronized void releaseConnection(Connection con) throws SQLException { 
    if(con == null){
      throw new SQLException(“Connection is null!!”);
    }
     
    synchronized(pool){
      int hash = con.hashCode();
      if(keyMap.containsKey(new Integer(hash))){
        pool.put(new Integer(hash), con);
        available++;
        use–;
      } else {
        try{
          con.close();
        }catch(Exception e){
          logger.debug(“Close connection error!”);
          e.printStackTrace();
          throw new SQLException(“Close connection error!”);
        }
      }
    }
  }
 
  public synchronized Connection getConnection() throws SQLException {       
     
    if(use > 50){
      throw new SQLException(“MAX Connection Alive!!”);
    }       
    synchronized(pool){
      if(pool.size() > 0){
        Iterator iter = pool.keySet().iterator();
        if(!iter.hasNext())
          logger.debug(“key not exist!!”);
         
        Integer hash = (Integer)iter.next();
        Connection con = (Connection)pool.remove(hash);
        available–;
        use++;       
        return con;
      }      
    }  
    return addConnection();   
  } 
 
 
  public void run(){
    // 시간마다 avaliable connection의 상태를 점검
    // 연결이 닫혔으면 map에서 삭제하고 다시 연결한뒤 저장
    // Connection에러가 발생하여 0개의 conn이 유효한경우 종료
    // running = false 인경우 종료
  }
 
 
  private Connection con; 
  private boolean running = true;
  private static final int MAX_ALIVE = 10;
  private int available;
  private int use;
  private HashMap pool;
  private HashMap keyMap; 
  private static ConnectionPool instance;
  private boolean close;
  private static final Logger logger;
   
  static
  {
      logger = Logger.getLogger(net.maxoft.center.controller.ConnectionPool.class);
  }
 


}

Connection Pool 자체를 Thread로 설정하여 일정주기동안 Managed connection의 validate를 check 하도록 추가해 주어야 한다.



MAX_ALIVE의 갯수를 넘어서는 Connection요청은 Connection을 생성후 반납시 close()하도록 되어 있다.



드라이버이름과 URL은 Pref를 구현한 클래스로부터 얻어오도록 되어 있으므로 Prefs를 직접구현하도록 한다.

XMLEncoder/Decoder 이용하기







java.beans 패키지에 포함된 XMLEncoder를 이용하면 자바객체를 xml데이터로 저장할 수 있다.



– Object를 xml로 저장 –


Object object;


XMLEncoder output = new XMLEncoder(new FileOutputStream(“c:\test.xml”));
output.writeObject(object);


output2.flush();


output.close();



– xml에서 객체 생성 –


try{
 input = new XMLDecoder(new FileInputStream(“c:\test.xml”));
     
} catch(Exception e){}
Object o = input.readObject();
input.close();

Axis 에서 Map사용하기







 Axis에서는 배열형태나 Vector형태는 기본적으로 전송을 지원하지만 Map같은 Collection형태는 지원해주지 않는다.


wsdl2java를 이용하면 Map에 대응하는 java파일을 얻을수 있다.


– service.wsdl –


..


<complexType name=”mapItem”>
    <sequence>
     <element name=”key” nillable=”true” type=”xsd:anyType”/>
     <element name=”value” nillable=”true” type=”xsd:anyType”/>
    </sequence>
   </complexType>
   <complexType name=”Map”>
    <sequence>
     <element maxOccurs=”unbounded” minOccurs=”0″ name=”item” type=”apachesoap:mapItem”/>
    </sequence>
   </complexType>



– wsdl2java 로 얻어진 MapItem.java –


/**
 * MapItem.java
 *
 * This file was auto-generated from WSDL
 * by the Apache Axis 1.3 Oct 05, 2005 (05:23:37 EDT) WSDL2Java emitter.
 */


package org.apache.xml.xml_soap;


public class MapItem  implements java.io.Serializable {
    private java.lang.Object key;


    private java.lang.Object value;


    public MapItem() {
    }


    public MapItem(
           java.lang.Object key,
           java.lang.Object value) {
           this.key = key;
           this.value = value;
    }



    /**
     * Gets the key value for this MapItem.
     *
     * @return key
     */
    public java.lang.Object getKey() {
        return key;
    }



    /**
     * Sets the key value for this MapItem.
     *
     * @param key
     */
    public void setKey(java.lang.Object key) {
        this.key = key;
    }



    /**
     * Gets the value value for this MapItem.
     *
     * @return value
     */
    public java.lang.Object getValue() {
        return value;
    }



    /**
     * Sets the value value for this MapItem.
     *
     * @param value
     */
    public void setValue(java.lang.Object value) {
        this.value = value;
    }



}


– deploy.wsdl에 추가된 beanMapping –


<beanMapping
        xmlns:ns=”http://xml.apache.org/xml-soap
        qname=”ns:mapItem”
        languageSpecificType=”java:org.apache.xml.xml_soap.MapItem” 
       ENCODINGStyle=”http://schemas.xmlsoap.org/soap/ENCODING/
      />


– wsdl에서 Map의 참조방법 –


<element name=”customFields” nillable=”true” type=”apachesoap:Map”/>

Vector는 Object의 배열로 처리할수 있는것처럼 Map은 key와 value의 Pair인 MapItem배열을 통해 전송할 수있다.

JXL라이브러리를 이용한 액셀 다루기


 jxl라이브러리를 이용하면 excel문서를 읽고쓰는것이가능하다.



자세한 내용은 http://www.andykhan.com/ 에서 확인해 볼수 있다..



이번프로젝트에서는 csv파일을 이용하기때문에 라이브러리의 모든기능은 사용하지 않지만, excel 읽어서 csv로 저장해보았다.



File file = new File(c:\text.xls”);


String ENCODING = “KSC5601”;
              boolean hide = false;
               Workbook w = Workbook.getWorkbook(file);
               FileOutputStream fos = new FileOutputStream(outFile);
                           
               OutputStreamWriter osw = new OutputStreamWriter(fos, ENCODING);
               BufferedWriter bw = new BufferedWriter(osw);               
               for (int sheet = 0; sheet < w.getNumberOfSheets(); sheet++)
               {
                  Sheet s = w.getSheet(sheet);
               
                  if (!(hide && s.getSettings().isHidden()))
                  {
                    Cell[] row = null;
                   
                    for (int i = 0 ; i < s.getRows() ; i++)
                    {
                      row = s.getRow(i);
                     
                      if (row.length > 0)
                      {
                        if (!(hide && row[0].isHidden()))
                        {
                          bw.write(row[0].getContents());
                          // Java 1.4 code to handle embedded commas
                          // bw.write(“”” + row[0].getContents().replaceAll(“””,””””) + “””);
                        }
                       
                        for (int j = 1; j < row.length; j++)
                        {
                          bw.write(‘,’);
                          if (!(hide && row[j].isHidden()))
                            {
                            bw.write(row[j].getContents());
                            // Java 1.4 code to handle embedded quotes
                            //  bw.write(“”” + row[j].getContents().replaceAll(“””,””””) + “””);
                          }
                        }
                      }
                      bw.newLine();
                    }
                  }
                }
                bw.flush();
                bw.close();
   
               fos.close();
               w.close();


– 참고 –


jxl.Demo , jxl.CSV