欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

netty实现Socket NIO服务器

程序员文章站 2022-07-13 17:07:36
...
package org.liufei.dccserver;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.apache.log4j.Logger;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.liufei.dccserver.ui.ServerManager;

public class Server {
	
	private static final Server server = new Server() ;
	
	private Channel channel = null ;
	
	/**
	 * dcc server
	 */
	private Server() {
	}
	
	public static Server getInstance() {
		return server ;
	}
	
	/**
	 * 启动一个服务并返回当前服务实例
	 * @return
	 */
	public void start(){
		ServerConfig config = ServerConfig.getInstance() ;
		
		String host = "localhost" ;
		int port = 8080 ;
		
		try {
			host = config.host() ;
			port = config.port() ;
			
			ServerBootstrap BOOTSTRAP = new ServerBootstrap(new NioServerSocketChannelFactory(Executors
					.newCachedThreadPool(), Executors.newCachedThreadPool()));
			
			BOOTSTRAP.setPipelineFactory(new ServerPipelineFactory());

			BOOTSTRAP.setOption("child.tcpNoDelay", true);
			BOOTSTRAP.setOption("child.keepAlive", true);
			
			channel = BOOTSTRAP.bind(new InetSocketAddress(host, port));
			
			START_FLAG.set(START_SUCCESS) ;
			logger.debug("\r\nDCC SERVER start success on host [ " + host + " ], port [ " + port + " ] .\r\n") ;
			
		} catch (Exception e) {
			START_FLAG.set(START_ERROR) ;
			logger.debug("\r\nDCC SERVER start error on host [ " + host + " ], port [ " + port + " ] .\r\n") ;
			logger.error("start error message.", e) ;
			ServerManager manager = ServerManager.getInstance() ;
			manager.setEnabledTrue() ;
		}
	}
	
	public void shutdown() {
		if(channel != null) {
			channel.unbind() ;
			channel.disconnect() ;
			channel.close() ;
		}
	}
	
	/**
	 * 是否已启动成功
	 * @return
	 */
	public boolean isStarted() {
		Integer start_flag = START_FLAG.get() ;
		if(start_flag == START_SUCCESS)
			return true ;
		else if(start_flag == START_ERROR)
			return false ;
		else 
			return false ;
	}

	private static final Logger logger = Logger.getLogger(Server.class) ;
	
	private static final ThreadLocal<Integer> START_FLAG = new ThreadLocal<Integer>() ;
	
	/**
	 * 启动成功
	 */
	public static final Integer START_SUCCESS = 1 ;
	
	/**
	 * 启动失败
	 */
	public static final Integer START_ERROR = 0 ;
}

package org.liufei.dccserver;

import java.io.IOException;
import java.net.InetAddress;
import java.util.Date;
import org.apache.log4j.Logger;
import org.dom4j.DocumentException;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;

public class ServerHandler extends SimpleChannelUpstreamHandler {
	private static final Logger logger = Logger.getLogger(ServerHandler.class);

	@Override
	public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e)
			throws Exception {
		if (e instanceof ChannelStateEvent) {
			logger.info("\r\n" + e.toString() + "\r\n");
		}
		super.handleUpstream(ctx, e);
	}

	@Override
	public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
			throws Exception {
		e.getChannel().write(
				"\r\nWelcome to " + InetAddress.getLocalHost().getHostName()
						+ "!\r\n");
		e.getChannel().write("\r\nIt is " + new Date() + " now.\r\n");
	}

	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
		ServerConfig config = ServerConfig.getInstance();
		String key_value = "";
		String dccserver_echo = "" ;
		try {
			key_value = config.requestKey() + "=" + config.requestValue();
			dccserver_echo = config.dccServerEcho() ;
			logger.debug("\r\nkey value mapping : " + key_value + "\r\n");
		} catch (DocumentException e1) {
			logger.error("\r\nReading XML Config Error ! ", e1);
		}

		Object message = e.getMessage();
		logger.info("\r\nSocket ChannelBuffer Reading.\r\n");
		ChannelBuffer buffer = (ChannelBuffer) message;
		StringBuffer request = new StringBuffer();
		while (buffer.readable()) {
			byte b = buffer.readByte();
			request.append(((char) b));
		}

		if (key_value.length() != 0) {
			if (request.toString().indexOf(key_value) > -1) {
				logger.info("request success.");
				logger.debug("start echo cmd ...") ;
				Runtime runtime = Runtime.getRuntime() ;
				try {
					Process process = runtime.exec(dccserver_echo) ;
					logger.debug("start echo cmd success.") ;
					process.waitFor() ;
					logger.debug("wait for echo cmd...") ;
					if(process.exitValue() == 0) 
						logger.debug("run over echo cmd success.") ;
					else 
						logger.debug("run echo cmd error.") ;
				} catch (IOException e1) {
					logger.debug("start echo cmd error.") ;
					logger.error("start echo cmd error message .", e1) ;
				} catch (InterruptedException e2) {
					logger.debug("start echo cmd error.") ;
					logger.error("start echo cmd error message .", e2) ;
				}
			} else {
				logger.info("request error.");
			}
		}

		ChannelFuture future = e.getChannel().write(request.toString());

		logger.info("\r\nrequest message \r\n " + request.toString() + "\r\n");

		logger.debug("request Channel is closed.");
		future.addListener(ChannelFutureListener.CLOSE);
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
		logger.error("\r\nIgnore Unexpected Exception From Downstream.\r\n", e
				.getCause());
		e.getChannel().close();
	}
}
package org.liufei.dccserver;

import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
import org.jboss.netty.handler.codec.frame.Delimiters;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.codec.string.StringEncoder;

public class ServerPipelineFactory implements ChannelPipelineFactory {

	public ChannelPipeline getPipeline() throws Exception {
		ChannelPipeline pipeline = pipeline();

		pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192,
				Delimiters.lineDelimiter()));
		pipeline.addLast("decoder", new StringDecoder());
		pipeline.addLast("encoder", new StringEncoder());

		pipeline.addLast("handler", new ServerHandler());

		return pipeline;
	}

	private ChannelPipeline pipeline() {
		return Channels.pipeline(new ServerHandler());
	}
}
package org.liufei.dccserver.ui;

import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Insets;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;

import org.apache.log4j.Logger;
import org.liufei.dccserver.Server;
import org.pushingpixels.substance.api.SubstanceLookAndFeel;

import com.sun.awt.AWTUtilities;

public class ServerManager extends MyJFrame implements ActionListener, MouseListener{
	private static final Logger logger = Logger.getLogger(ServerManager.class) ;
	private static final long serialVersionUID = 1L;
	private static final ServerManager manager = new ServerManager("DCC SERVER") ;

	private JButton start = new JButton("启动") ;
	private JButton restart = new JButton("重新启动") ;
	private JButton min = new JButton("最小化到任务栏") ;
	
	private PopupMenu pop = new PopupMenu();
    private MenuItem open = new MenuItem("打开");
    private MenuItem restartItem = new MenuItem("重新启动") ;
    private TrayIcon trayicon;
    
    private final static Server server = Server.getInstance() ;
	
	/**
	 * @param title
	 * @throws HeadlessException
	 */
	private ServerManager(String title) throws HeadlessException {
		super(title);
		this.initComponents() ;
		
		Container container = getContentPane();
		container.setLayout(new BorderLayout()) ;
		this.setResizable(false) ;
		this.setVisible(false) ;
		this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		this.setCursor(new Cursor(0));
		
		this.setUndecorated(true) ;
		this.setAlwaysOnTop(true) ;
		
		Toolkit tool = getToolkit() ;
		Dimension dim = tool.getScreenSize() ;
		
		/**
		 * 获取屏幕的边界
		 */
		Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(this.getGraphicsConfiguration());
		/**
		 * 获取底部任务栏高度
		 */
		int taskBarHeight = screenInsets.bottom; 
		
		this.setBounds(dim.width - 320 - 1, dim.height - taskBarHeight - 100 - 1, 320, 100) ;
		Image image=tool.getImage(this.getClass().getResource("/image/LOGO.png"));
		this.setIconImage(image);
		
		JLabel titlebottom1 = new JLabel(new ImageIcon(this.getClass().getResource("/image/panel-title-bg.gif"))) ;
		JLabel titlebottom2 = new JLabel(new ImageIcon(this.getClass().getResource("/image/panel-title-bg.gif"))) ;
		
		container.add(titlebottom1, BorderLayout.NORTH) ;
		container.add(initButton(), BorderLayout.CENTER);
		container.add(titlebottom2, BorderLayout.SOUTH);
		
		this.setCursor(Cursor.getPredefinedCursor(12)) ;
		this.setContentPane(container) ;
		this.validate() ;
	}
	
	/**
	 * 
	 * @return
	 * 	ServerManager
	 */
	public static ServerManager getInstance() {
		return manager ;
	}
	
	private void initComponents() {
		open.addActionListener(this) ;
		restartItem.addActionListener(this) ;
		
		pop.add(open);
        pop.add(restartItem);
        if(SystemTray.isSupported()){
        	SystemTray tray = SystemTray.getSystemTray();
        	Image icon = this.getToolkit().getImage(this.getClass().getResource("/image/tubiao.gif"));
        	
        	trayicon = new TrayIcon(icon,"DCC SERVER",pop);
        	trayicon.addMouseListener(this) ;
        	
        	try {
				tray.add(trayicon);
			} catch (AWTException e) {
				JOptionPane.showMessageDialog(this, "系统不支持托盘!", "系统提示", JOptionPane.ERROR_MESSAGE) ;
			}
        }
	}
	
	private Box initButton() {
		start.addActionListener(this) ;
		restart.addActionListener(this) ;
		min.addActionListener(this) ;

		start.setCursor(Cursor.getPredefinedCursor(12)) ;
		restart.setCursor(Cursor.getPredefinedCursor(12)) ;
		min.setCursor(Cursor.getPredefinedCursor(12)) ;
		Box box = Box.createHorizontalBox() ;
		box.setBorder(BorderFactory.createTitledBorder(new LineBorder(Color.black), "DCC SERVER", TitledBorder.LEADING, TitledBorder.TOP, new Font("Dialog", Font.BOLD, 10), new Color(51, 51, 51))) ;
		box.add(Box.createHorizontalStrut(10)) ;
		box.add(start) ;
		box.add(Box.createHorizontalStrut(5)) ;
		box.add(restart) ;
		box.add(Box.createHorizontalStrut(5)) ;
		box.add(min) ;
		box.add(Box.createHorizontalStrut(10)) ;
		return box ;
	}
	
	/**
	 * show dcc server
	 */
	public static void showDccServer(final boolean start) {
		JDialog.setDefaultLookAndFeelDecorated(true);
		SwingUtilities.invokeLater(new Runnable(){
			ServerManager manager = ServerManager.getInstance() ;
			@Override
			public void run() {
				try {
					SubstanceLookAndFeel.setSkin("org.pushingpixels.substance.api.skin.MistSilverSkin");
					if(!manager.isVisible())
						manager.setVisible(true) ;
					AWTUtilities.setWindowOpacity(manager, 0.75F);
					if(start) {
						server.start() ;
						boolean flag = server.isStarted() ;
						logger.debug("DCC SERVER " + (flag ? "已启动" : "未启动"));
						if(flag) {
							manager.setEnabledFalse() ;
							hideDccServer() ;
						}
					}
				} catch (HeadlessException e) {
					JOptionPane.showMessageDialog(manager, "系统初始化失败!", "系统提示", JOptionPane.ERROR_MESSAGE) ;
				}
			}}) ;
	}
	
	/**
	 * 设置按钮不可见按钮
	 */
	private void setEnabledFalse(){
		this.start.setEnabled(false);
	}
	
	/**
	 * 设置按钮可见按钮
	 */
	public void setEnabledTrue(){
		this.start.setEnabled(true);
	}
	
	/**
	 * hide dcc server
	 */
	public static void hideDccServer() {
		ServerManager manager = ServerManager.getInstance() ;
		if(manager.isVisible())
			manager.setVisible(false) ;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		Object eventObject = e.getSource() ;
		if(eventObject == start) {
			showDccServer(true) ;
		}
		else if(eventObject == restart) {
			server.shutdown() ;
			showDccServer(true) ;
		}
		else if(eventObject == min) {
			hideDccServer() ;
		}
		else if(eventObject == open) {
			showDccServer(false) ;
		}
		else if(eventObject == restartItem) {
			server.shutdown() ;
			showDccServer(true) ;
		}
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		if(e.getClickCount() == 2)
			showDccServer(false) ;
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		if(e.getClickCount() == 2)
			showDccServer(false) ;
	}

	@Override
	public void mouseExited(MouseEvent e) {
		if(e.getClickCount() == 2)
			showDccServer(false) ;
	}

	@Override
	public void mousePressed(MouseEvent e) {
		if(e.getClickCount() == 2)
			showDccServer(false) ;
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		if(e.getClickCount() == 2)
			showDccServer(false) ;
	}
}
package org.liufei.dccserver.ui;

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.HeadlessException;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.AbstractButton;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;

import org.apache.log4j.Logger;

public class MyJFrame extends JFrame {
	private static final long serialVersionUID = 102400L;
	protected Logger logger = Logger.getLogger(getClass()) ;

	private int X ;//接受鼠标事件
	private int Y ;
	
	private boolean isDraging ;//判断鼠标是否正在移动
	
	public MyJFrame() throws HeadlessException {
		super();
		this.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				isDraging = true;
				X = e.getX();
				Y = e.getY();
			}

			public void mouseReleased(MouseEvent e) {
				isDraging = false;
			}
		});
		this.addMouseMotionListener(new MouseMotionAdapter() {
			public void mouseDragged(MouseEvent e) {
				if (isDraging) {
					int left = getLocation().x;
					int top = getLocation().y;
					setLocation(left + e.getX() - X, top + e.getY() - Y);
				}
			}
		});
	}
	
	public static void setButtonIcon(AbstractButton... buttons) {
		for (AbstractButton button : buttons) {
			/**
			 * 设置按钮的翻转图标。
			 */
			button.setRolloverIcon(new BoxIcon(Color.cyan, 3));
			/**
			 * 设置按钮的按下图标。
			 */
			button.setPressedIcon(new BoxIcon(Color.yellow, 3));
			
			button.setHorizontalTextPosition(JButton.LEFT) ;
		}
	}
	
	private static class BoxIcon implements Icon {
		private Color color;

		private int borderWidth;

		BoxIcon(Color color, int borderWidth) {
			this.color = color;
			this.borderWidth = borderWidth;
		}

		public int getIconWidth() {
			return 20;
		}

		public int getIconHeight() {
			return 20;
		}

		public void paintIcon(Component c, Graphics g, int x, int y) {
			g.setColor(Color.black);
			g.fillRect(x, y, getIconWidth(), getIconHeight());
			g.setColor(color);
			g.fillRect(x + borderWidth, y + borderWidth, getIconWidth() - 2
					* borderWidth, getIconHeight() - 2 * borderWidth);
		}
	}

	public MyJFrame(GraphicsConfiguration gc) {
		super(gc);
		this.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				isDraging = true;
				X = e.getX();
				Y = e.getY();
			}

			public void mouseReleased(MouseEvent e) {
				isDraging = false;
			}
		});
		this.addMouseMotionListener(new MouseMotionAdapter() {
			public void mouseDragged(MouseEvent e) {
				if (isDraging) {
					int left = getLocation().x;
					int top = getLocation().y;
					setLocation(left + e.getX() - X, top + e.getY() - Y);
				}
			}
		});
	}

	public MyJFrame(String title, GraphicsConfiguration gc) {
		super(title, gc);
		this.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				isDraging = true;
				X = e.getX();
				Y = e.getY();
			}

			public void mouseReleased(MouseEvent e) {
				isDraging = false;
			}
		});
		this.addMouseMotionListener(new MouseMotionAdapter() {
			public void mouseDragged(MouseEvent e) {
				if (isDraging) {
					int left = getLocation().x;
					int top = getLocation().y;
					setLocation(left + e.getX() - X, top + e.getY() - Y);
				}
			}
		});
	}

	public MyJFrame(String title) throws HeadlessException {
		super(title);
		this.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				isDraging = true;
				X = e.getX();
				Y = e.getY();
			}

			public void mouseReleased(MouseEvent e) {
				isDraging = false;
			}
		});
		this.addMouseMotionListener(new MouseMotionAdapter() {
			public void mouseDragged(MouseEvent e) {
				if (isDraging) {
					int left = getLocation().x;
					int top = getLocation().y;
					setLocation(left + e.getX() - X, top + e.getY() - Y);
				}
			}
		});
	}

}
package org.liufei.dccserver.util;

import org.apache.log4j.Logger;
import org.dom4j.DocumentException;
import org.liufei.dccserver.ServerConfig;

import com.ice.jni.registry.NoSuchKeyException;
import com.ice.jni.registry.NoSuchValueException;
import com.ice.jni.registry.RegStringValue;
import com.ice.jni.registry.Registry;
import com.ice.jni.registry.RegistryException;
import com.ice.jni.registry.RegistryKey;

/**
 * java 操作注册表
 * 
 * @author 刘飞
 */
public class RegeditTool {
	private static final Logger logger = Logger.getLogger(RegeditTool.class);

	/**
	 * 把信息存储到注册表HKEY_LOCAL_MACHINE下的某个节点的某一变量中,有则修改,无则创建
	 * 
	 * @param folder
	 * @param subKeyNode
	 * @param subKeyName
	 * @param subKeyValue
	 * @return
	 */
	public static boolean setValue(String folder, String subKeyNode,
			String subKeyName, String subKeyValue) {
		try {
			RegistryKey software = Registry.HKEY_LOCAL_MACHINE
					.openSubKey(folder);
			RegistryKey subKey = software.createSubKey(subKeyNode, "");
			subKey
					.setValue(new RegStringValue(subKey, subKeyName,
							subKeyValue));
			subKey.closeKey();
			return true;
		} catch (NoSuchKeyException e) {
			logger.error("No Such Key.", e);
		} catch (NoSuchValueException e) {
			logger.error("No Such Value.", e);
		} catch (RegistryException e) {
			logger.error("Registry Error.", e);
		}
		return false;
	}

	/**
	 * 删除注册表中某节点下的某个变量
	 * 
	 * @param folder
	 * @param subKeyNode
	 * @param subKeyName
	 * @return
	 */
	public static boolean deleteValue(String folder, String subKeyNode,
			String subKeyName) {

		try {
			RegistryKey software = Registry.HKEY_LOCAL_MACHINE
					.openSubKey(folder);
			RegistryKey subKey = software.createSubKey(subKeyNode, "");
			subKey.deleteValue(subKeyName);
			subKey.closeKey();
			return true;
		} catch (NoSuchKeyException e) {
			logger.error("No Such Key.", e);
		} catch (NoSuchValueException e) {
			logger.error("No Such Value.", e);
		} catch (RegistryException e) {
			logger.error("Registry Error.", e);
		}
		return false;
	}

	/**
	 * 删除注册表中某节点下的某节点
	 * 
	 * @param folder
	 * @param subKeyNode
	 * @return
	 */
	public static boolean deleteSubKey(String folder, String subKeyNode) {
		try {
			RegistryKey software = Registry.HKEY_LOCAL_MACHINE
					.openSubKey(folder);
			software.deleteSubKey(subKeyNode);
			software.closeKey();
			return true;
		} catch (NoSuchKeyException e) {
			logger.error("No Such Key.", e);
		} catch (NoSuchValueException e) {
			logger.error("No Such Value.", e);
		} catch (RegistryException e) {
			logger.error("Registry Error.", e);
		}
		return false;
	}

	/**
	 * 打开注册表项并读出相应的变量名的值
	 * 
	 * @param folder
	 * @param subKeyNode
	 * @param subKeyName
	 * @return
	 */
	public static String getValue(String folder, String subKeyNode,
			String subKeyName) {
		String value = "";
		try {
			RegistryKey software = Registry.HKEY_LOCAL_MACHINE
					.openSubKey(folder);
			RegistryKey subKey = software.openSubKey(subKeyNode);
			value = subKey.getStringValue(subKeyName);
			subKey.closeKey();
		} catch (NoSuchKeyException e) {
			logger.error("No Such Key.", e);
		} catch (NoSuchValueException e) {
			logger.error("No Such Value.", e);
		} catch (RegistryException e) {
			logger.error("Registry Error.", e);
		}
		return value;
	}

	public static void regeditDccServer() throws DocumentException {
		setValue(
				"SOFTWARE", 
				"Microsoft\\Windows\\CurrentVersion\\Run",
				ServerConfig.getInstance().regeditKey(), 
				ServerConfig.getInstance().regeditValue()
				);
	}
}
package org.liufei.dccserver;

import java.io.File;

import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class ServerConfig {

	private static final String DCCSERVER_ECHO = "dccserver-echo";

	private static final String SERVICE_REQUEST = "service-request";

	private static final String REGISTRY = "registry";

	private static final String VALUE = "value";

	private static final String KEY = "key";

	private static final String PORT = "port";

	private static final String HOST = "host";

	private static final ServerConfig SERVER_CONFIG = new ServerConfig() ;
	
	private static final String XML_CONFIG = "config/server.xml" ;
	
	private static final SAXReader SAR_READER = new SAXReader();

	private ServerConfig() {
		super();
	}
	
	public String host() throws DocumentException {
		return this.rootElement().element(HOST).getTextTrim().trim() ;
	}
	
	public int port() throws DocumentException {
		return Integer.parseInt(this.rootElement().element(PORT).getTextTrim().trim()) ;
	}
	
	public String dccServerEcho() throws DocumentException {
		return this.rootElement().element(DCCSERVER_ECHO).element(VALUE).getTextTrim().trim() ;
	}
	
	public String regeditKey() throws DocumentException {
		return regedit().element(KEY).getTextTrim().trim() ;
	}
	
	public String regeditValue() throws DocumentException {
		return regedit().element(VALUE).getTextTrim().trim() ;
	}
	
	private Element regedit() throws DocumentException {
		return this.rootElement().element(REGISTRY) ;
	}
	
	public String requestKey() throws DocumentException {
		Element service_request = this.serviceRequest() ;
		return service_request.element(KEY).getTextTrim().trim() ;
	}
	
	public String requestValue() throws DocumentException {
		Element service_request = this.serviceRequest() ;
		return service_request.element(VALUE).getTextTrim().trim() ;
	}
	
	private final Element rootElement() throws DocumentException {
		return SAR_READER.read(new File(XML_CONFIG)).getRootElement();
	}
	
	private Element serviceRequest() throws DocumentException {
		return this.rootElement().element(SERVICE_REQUEST) ;
	}
	
	public static ServerConfig getInstance() {
		return SERVER_CONFIG ;
	}
}
package org.liufei.dccserver;

import java.io.File;
import java.io.IOException;

import org.apache.log4j.Logger;
import org.dom4j.DocumentException;
import org.liufei.dccserver.ui.ServerManager;
import org.liufei.dccserver.util.AddJavaLibraryPath;
import org.liufei.dccserver.util.FileCopyUtils;
import org.liufei.dccserver.util.RegeditTool;

public class ServerRunner {
	private static final Logger logger = Logger.getLogger(ServerRunner.class) ;
	public static void main(String[] args) {
		try {
			if(ServerConfig.getInstance().regeditAuto()) {
				setAutoStart() ;
				logger.debug("set auto start success.") ;
			}
		} catch (Exception e) {
			logger.debug("set auto start error.") ;
			logger.error("set auto atart error message.", e) ;
		}
		logger.debug("show dcc server manager.") ;
		ServerManager.showDccServer(true) ;
		logger.debug("show dcc server manager end.") ;
	}
	
	public static void setAutoStart() throws DocumentException, IOException {
		if(ServerConfig.getInstance().isCopyDLL())
			FileCopyUtils.copy(new File("lib/ICE_JNIRegistry.dll"), new File(ServerConfig.getInstance().copyDLLDest())) ;
		String JAVA_LIBRARY_PATH = System.getProperty("java.library.path") ;
		
		printLibrary("JAVA_LIBRARY_PATH", JAVA_LIBRARY_PATH) ;
		
		String ADD_DLL_PATH = new File("lib/ICE_JNIRegistry.dll").getAbsolutePath() + File.pathSeparator + JAVA_LIBRARY_PATH ;
		
		System.setProperty("java.library.path", ADD_DLL_PATH) ;
		
		printLibrary("After Add DLL LIB JAVA_LIBRARY_PATH", System.getProperty("java.library.path")) ;
		
		AddJavaLibraryPath.addDir(new File("lib").getAbsolutePath()) ;
		
		loadLibrary() ;
		
		RegeditTool.regeditDccServer() ;
	}
	
	private static void loadLibrary() {
		try {
			System.loadLibrary( "ICE_JNIRegistry" );
			}
		catch ( UnsatisfiedLinkError e )
			{
			System.err.println
				( "ERROR You have not installed the DLL named '"
					+ "ICE_JNIRegistry.DLL'.\n\t" + e.getMessage() );
			}
		catch ( SecurityException e )
			{
			System.err.println
				( "ERROR You do not have permission to load the DLL named '"
					+ "ICE_JNIRegistry.DLL'.\n\t" + e.getMessage() );
			}
	}
	
	public static String printLibrary(String message, String java_library_path) {
		String java_library_path_temp = java_library_path ;
		StringBuffer buffer = new StringBuffer() ;
		
		String[] libs = java_library_path_temp.split(File.pathSeparator) ;
		for (String lib : libs) {
			buffer.append(lib + "\n") ;
		}
		logger.debug(message + " : \n" + buffer.toString()) ;
		return buffer.toString() ;
	}
}
package org.liufei.dccserver.util;

import java.io.IOException;
import java.lang.reflect.Field;

/**
 * 动态加载增加java.library.path属性
 * 
 * @author 刘飞
 * 
 */
public class AddJavaLibraryPath {

	/**
	 * 通过反射实现动态增加java.library.path 本方法和jvm加联,用到了ClassLoader里的usr_paths。
	 * 
	 * @param s
	 * @throws IOException
	 */
	public static void addDir(String s) throws IOException {
		try {
			Field field = ClassLoader.class.getDeclaredField("usr_paths");
			field.setAccessible(true);
			String[] paths = (String[]) field.get(null);
			for (int i = 0; i < paths.length; i++) {
				if (s.equals(paths[i])) {
					return;
				}
			}
			String[] tmp = new String[paths.length + 1];
			System.arraycopy(paths, 0, tmp, 0, paths.length);
			tmp[paths.length] = s;
			field.set(null, tmp);
		} catch (IllegalAccessException e) {
			throw new IOException(
					"Failed to get permissions to set library path");
		} catch (NoSuchFieldException e) {
			throw new IOException(
					"Failed to get field handle to set library path");
		}
	}
}
package org.liufei.dccserver.util;

public class AppUtil {

	public static void main(String[] args) {
		System.out.println(getAppPath(AppUtil.class));
	}
	
	/**
	 * -----------------------------------------------------------------------
	 * getAppPath需要一个当前程序使用的Java类的class属性参数,它可以返回打包过的
	 * Java可执行文件(jar,war)所处的系统目录名或非打包Java程序所处的目录
	 * 
	 * @param cls为Class类型
	 * @return 返回值为该类所在的Java程序运行的目录
	 */
	public static String getAppPath(Class<?> cls) {
		/**
		 * 检查用户传入的参数是否为空
		 */
		if (cls == null)
			throw new java.lang.IllegalArgumentException("参数不能为空!");
		ClassLoader loader = cls.getClassLoader();
		/**
		 * 获得类的全名,包括包名
		 */
		String clsName = cls.getName() + ".class";
		/**
		 * 获得传入参数所在的包
		 */
		Package pack = cls.getPackage();
		String path = "";
		/**
		 * 如果不是匿名包,将包名转化为路径
		 */
		if (pack != null) {
			String packName = pack.getName();
			/**
			 * 此处简单判定是否是Java基础类库,防止用户传入JDK内置的类库
			 */
			if (packName.startsWith("java.") || packName.startsWith("javax."))
				throw new java.lang.IllegalArgumentException("不要传送系统类!");
			/**
			 * 在类的名称中,去掉包名的部分,获得类的文件名
			 */
			clsName = clsName.substring(packName.length() + 1);
			/**
			 * 判定包名是否是简单包名,如果是,则直接将包名转换为路径,
			 */
			if (packName.indexOf(".") < 0)
				path = packName + "/";
			else {
				/**
				 * 否则按照包名的组成部分,将包名转换为路径
				 */
				int start = 0, end = 0;
				end = packName.indexOf(".");
				while (end != -1) {
					path = path + packName.substring(start, end) + "/";
					start = end + 1;
					end = packName.indexOf(".", start);
				}
				path = path + packName.substring(start) + "/";
			}
		}
		/**
		 * 调用ClassLoader的getResource方法,传入包含路径信息的类文件名
		 */
		java.net.URL url = loader.getResource(path + clsName);
		/**
		 * 从URL对象中获取路径信息
		 */
		String realPath = url.getPath();
		/**
		 * 去掉路径信息中的协议名"file:"
		 */
		int pos = realPath.indexOf("file:");
		if (pos > -1)
			realPath = realPath.substring(pos + 5);
		/**
		 * 去掉路径信息最后包含类文件信息的部分,得到类所在的路径
		 */
		pos = realPath.indexOf(path + clsName);
		realPath = realPath.substring(0, pos - 1);
		/**
		 * 如果类文件被打包到JAR等文件中时,去掉对应的JAR等打包文件名
		 */
		if (realPath.endsWith("!"))
			realPath = realPath.substring(0, realPath.lastIndexOf("/"));
		/**
		 *ClassLoader的getResource方法使用了utf-8对路径信息进行了编码,
		 * 当路径中存在中文和空格时,他会对这些字符进行转换,这样,
		 * 得到的往往不是我们想要的真实路径,在此,调用了URLDecoder的decode方法进行解码, 以便得到原始的中文及空格路径
		 */
		try {
			realPath = java.net.URLDecoder.decode(realPath, "utf-8");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return realPath;
	}
	/**
	 * getAppPath定义结束
	 */
}
<?xml version="1.0" encoding="UTF-8"?>

<dccserver>
	<!-- 配置主机地址 -->
	<host>172.16.3.53</host>
	<!-- 配置服务端口 -->
	<port>8080</port>
	
	<!-- 定义请求映射键值 -->
	<service-request>
		<key>name</key>
		<value>start</value>
	</service-request>
	
	<!-- 为开机启动服务配置 -->
	<registry>
		<!-- 设置是否由程序设置注册表来实现自动启动, 有时候JNI使用的ICE_JNIRegistry.dll无法加载 , 此时最好用bat或手动处理-->
		<app-auto-registry>true</app-auto-registry>
		<key>dccserver</key>
		<value>D://Program Files/dccserver/dccserver.exe</value>
	</registry>
	
	<!-- 是否拷贝DLL到指定目录 -->
	<jni>
		<isCopy>false</isCopy>
		<!-- 拷贝到指定目录供系统加载使用 -->
		<dest>C:/WINDOWS/system32</dest>
	</jni>
	
	<!-- 获取请求时要执行的动作 -->
	<dccserver-echo>
		<value>D:/Program Files/Gerber生成系统/Gerber生成系统 1.2 beta.exe</value>
	</dccserver-echo>
</dccserver>