`
liufei.fir
  • 浏览: 687186 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

netty实现Socket NIO服务器

阅读更多
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>
分享到:
评论
1 楼 hch1011 2012-03-07  
代码不全,缺import org.liufei.dccserver.util.FileCopyUtils;

相关推荐

    spring boot 整合的netty 实现的socket的服务端和客户端

    以下将详细讲解如何实现Spring Boot整合Netty的Socket服务端和客户端。 首先,我们来看服务端的实现。在`netty_server`项目中,我们需要创建一个`ServerBootstrap`实例,它是Netty服务器的核心。通过`...

    基于netty编写的socket服务端

    综上所述,基于Netty编写的socket服务端利用了Java的NIO特性,通过事件驱动和处理器链的方式,实现了高效的网络通信。开发者可以根据需求定制自己的业务处理器,处理各种复杂的网络协议,实现高性能的网络服务。在...

    Android-netty和socket通信的demo

    在“netty-socket-master”这个压缩包中,可能包含了服务器端和客户端的代码实现,包括Bootstrap的配置、ChannelHandler的定义、数据传输的逻辑等。通过对这些代码的学习和分析,开发者可以深入理解Netty在Android上...

    netty与socket交互实例

    例如,我们可以使用NioServerSocketChannel作为服务器通道类型,并实现一个简单的ByteToMessageDecoder和MessageToByteEncoder来处理数据的编码和解码。 2. **绑定端口**:使用ServerBootstrap的bind方法将服务器...

    netty5实现的socket服务器

    在本文中,我们将深入探讨如何使用 Netty 5 实现一个 Socket 服务器,以及它在公司实际项目中的应用,特别是为 APP 提供长连接功能。 首先,我们需要了解 Socket 基础。Socket 是一种网络通信机制,它允许两个网络...

    用Netty实现NIO Socket聊天系统示例

    在本示例中,我们将深入探讨如何利用Netty实现一个基于NIO(非阻塞I/O)的Socket聊天系统。NIO是一种I/O模型,它允许Java程序在不阻塞线程的情况下处理多个输入/输出流,从而提高并发性能。 首先,Netty的核心组件...

    netty-socket实时在线人数统计

    本文将深入探讨如何使用SpringBoot 2.0与Netty-socket来实现一个实时在线人数统计的功能,并涉及到WebSocket协议的相关知识。 **SpringBoot 2.0** SpringBoot是Spring框架的一个轻量级容器,它简化了Spring应用...

    Socket 之 BIO、NIO、Netty 简单实现

    在Java中,Socket通信涉及三种不同的模型:BIO(Blocking I/O)、NIO(Non-blocking I/O)和Netty,这些都是实现高并发、高性能网络服务的重要手段。 **1. Socket基础** Socket,通常被称为套接字,是网络通信的...

    基于Netty实现的文件上传

    Netty中的NioSocketChannel和NioServerSocketChannel就是对Socket的封装,通过它们,我们可以轻松创建客户端和服务端,实现数据的双向传输。 至于"基于UDP协议通信的源码",UDP(用户数据报协议)是另一种传输层...

    netty_socket_demo.rar

    在本示例 "netty_socket_demo" 中,我们很可能会看到如何使用 Netty 实现基于 Socket 的通信。Socket 是互联网编程的基础,它提供了一种进程间通信(IPC)的方式,允许两个网络应用进行双向通信。 Netty 的核心概念...

    aio.zip_netty_netty-socket

    在本文中,我们将深入探讨 Netty 的核心概念、特性以及它在网络编程中的应用,特别是针对多Socket服务器集成的优势。 首先,Netty 的核心特性包括其基于NIO(非阻塞I/O)的异步事件驱动模型。这种模型使得 Netty ...

    采用NIO实现一个Socket服务器

    本篇将基于给定的标题“采用NIO实现一个Socket服务器”来详细阐述如何使用NIO进行Socket服务端的开发。 首先,理解NIO的核心概念: 1. **通道(Channel)**:通道是连接到I/O设备的途径,可以读取或写入数据。常见的...

    netty-socket.zip

    在"netty-socket.zip"这个压缩包中,很可能是包含了一个基于Netty 5版本实现的Socket通信示例。Netty 5虽然不是最新的版本(当前最新为Netty 4.x),但仍然具备上述提到的优点。开发者可以通过分析其中的代码,学习...

    netty socketio 在线聊天程序

    1. **服务器端**:使用Netty作为基础网络框架,创建一个监听特定端口的服务器,处理客户端的连接请求,并实现Socket.IO的服务器端逻辑。 2. **客户端**:在网页中引入Socket.IO的JavaScript库,通过WebSocket或其他...

    Netty的Socket编程详解-搭建服务端与客户端并进行数据传输示例代码.rar

    在本文中,我们将深入探讨Netty如何利用Socket编程实现服务端与客户端的通信,并通过示例代码来展示其具体实现过程。 首先,Socket编程是网络通信的基础,它提供了进程间的通信能力,允许不同计算机上的程序之间...

    netty基于http socket websocke及心跳包机制t的demo

    通过使用Netty的NIO(非阻塞I/O)和EPOLL(在Linux系统上的高效I/O)事件模型,可以构建高并发、低延迟的网络应用。Socket在Netty中通常用于构建自定义的通信协议,或者作为HTTP之外的另一种网络通信方式。 ...

    socket-nio-single-reactor.zip

    1. **ServerBootstrap**:这是Netty框架(或者可能是自定义实现)中的一个类,用于配置服务器并启动监听端口。 2. **Selector**:NIO的核心组件,负责监听和注册通道上的事件。它会监控哪些通道准备好了进行读写...

    Java NIO Socket基本

    NIO在实际开发中常用于构建高性能的网络服务器,如Tomcat、Netty等框架就大量使用了NIO技术。通过合理使用NIO,开发者可以编写出更加高效、可扩展的服务端代码。了解和掌握Java NIO对于提升Java程序员在服务器端编程...

    基于Netty实现了dubbo rpc

    Netty基于IO多路复用模型,如Java的NIO(Non-blocking IO)或epoll,通过selector监听多个通道,实现高效的并发处理。其核心组件包括Bootstrap(引导类)、Channel(通道)、Pipeline(处理链)等,这些组件协同工作...

    Android使用Netty网络框架实践(客户端、服务端)

    在服务端实现上,我们需要创建一个ServerBootstrap,配置它来使用NioEventLoopGroup(非阻塞I/O事件循环组)以及对应的服务器通道实现,如NioServerSocketChannel。然后,我们可以通过bind()方法指定监听的端口,...

Global site tag (gtag.js) - Google Analytics