原作地址:http://hi.baidu.com/yhzhw2121/blog/item/ba7b76552b30045d564e00e2.html
程序主要分为SERVER端和CLINET端
SERVER由MINA实现,CLINET端由JAVA的普通UDP链接(MINA也可以实现CLINET端)
SERVER端代又分为两部分,一部分为监听端,另一部分为处理端(MINA用到的其他JAR包有slf4j-jdk,slf4j-api)
监听端代码: public class MemoryMonitorTest { private static final long serialVersionUID = 1L; public static final int PORT = 8080; public MemoryMonitorTest() throws IOException { NioDatagramAcceptor acceptor = new NioDatagramAcceptor();//创建一个UDP的接收器 acceptor.setHandler(new YourHandler());//设置接收器的处理程序 Executor threadPool = Executors.newFixedThreadPool(1500);//建立线程池 acceptor.getFilterChain().addLast("exector", new ExecutorFilter(threadPool)); acceptor.getFilterChain().addLast("logger", new LoggingFilter()); DatagramSessionConfig dcfg = acceptor.getSessionConfig();//建立连接的配置文件 dcfg.setReadBufferSize(4096);//设置接收最大字节默认2048 dcfg.setReceiveBufferSize(1024);//设置输入缓冲区的大小 dcfg.setSendBufferSize(1024);//设置输出缓冲区的大小 dcfg.setReuseAddress(true);//设置每一个非主监听连接的端口可以重用 acceptor.bind(new InetSocketAddress(PORT));//绑定端口 } public static void main(String[] args) throws IOException { new MemoryMonitorTest(); } server建立连接后,server端--》filter--》handler 处理端代码: public class YourHandler extends IoHandlerAdapter { //messageSent是Server响应给Clinet成功后触发的事件 @Override public void messageSent(IoSession session, Object message) throws Exception { if (message instanceof IoBuffer) { IoBuffer buffer = (IoBuffer) message; byte[] bb = buffer.array(); for (int i = 0; i < bb.length; i++) { System.out.print((char) bb[i]); } } } //抛出异常触发的事件 @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { cause.printStackTrace(); session.close(true); } //Server接收到UDP请求触发的事件 @Override public void messageReceived(IoSession session, Object message) throws Exception { System.out.println("messageReceived"); if (message instanceof IoBuffer) { IoBuffer buffer = (IoBuffer) message; // byte[] bb = buffer.array(); // for(int i=0;i<bb.length;i++) { // System.out.print((char)bb[i]); // } IoBuffer buffer1 = IoBuffer.wrap("11".getBytes());//返回信息给Clinet端 session.write(buffer1); //声明这里message必须为IoBuffer类型 } } //连接关闭触发的事件 @Override public void sessionClosed(IoSession session) throws Exception { System.out.println("Session closed..."); } //建立连接触发的事件 @Override public void sessionCreated(IoSession session) throws Exception { System.out.println("Session created..."); SocketAddress remoteAddress = session.getRemoteAddress(); System.out.println(remoteAddress); } //会话空闲 @Override public void sessionIdle(IoSession session, IdleStatus status) throws Exception { System.out.println("Session idle..."); } //打开连接触发的事件,它与sessionCreated的区别在于,一个连接地址(A)第一次请求Server会建立一个Session默认超时时间为1分钟,此时若未达到超时时间这个连接地址(A)再一次向Server发送请求即是sessionOpened(连接地址(A)第一次向Server发送请求或者连接超时后向Server发送请求时会同时触发sessionCreated和sessionOpened两个事件) @Override public void sessionOpened(IoSession session) throws Exception { System.out.println("Session Opened..."); SocketAddress remoteAddress = session.getRemoteAddress(); System.out.println(remoteAddress); } Client端代码:Client端代码不做解释 public void send(String host, int port) { try { InetAddress ia = InetAddress.getByName(host); DatagramSocket socket = new DatagramSocket(9999); socket.connect(ia, port); byte[] buffer = new byte[1024]; buffer = ("22") .getBytes(); DatagramPacket dp = new DatagramPacket(buffer, buffer.length); System.out.println(dp.getLength()); DatagramPacket dp1 = new DatagramPacket(new byte[22312], 22312); socket.send(dp); socket.receive(dp1); byte[] bb = dp1.getData(); for (int i = 0; i < dp1.getLength(); i++) { System.out.print((char) bb[i]); } } catch (Exception e) { e.printStackTrace(); } }
注意:UDP为无连接协议,因此Clinet向Server发送请求得到响应后会立即断开,Server端中的Session一定要设置超时系统默认为一分钟,如果需要保持连接可以让Client设置心跳(Clinet心跳时间<=Server端Session超时时间)
参考资料:
http://blog.csdn.net/junhuo/archive/2008/10/20/3106260.aspx http://amozon.javaeye.com/blog/326169
http://mina.apache.org/udp-tutorial.html
http://topic.csdn.net/u/20080910/12/9538228d-0b18-40f3-96b8-c2221ac9f9cc.html
以及MINA包中的练习和MINA源代码。