Java NIO(异步IO)Socket通信例子
简要说明下:使用java nio开发网络通讯 是比较快速和方面的。因为他可以不用阻塞的方式侦听客户端的连接 ,在java nio中可以使用基于事件的机制进行非阻塞通讯,当有新的事
件进行注册时 我们只需要通过事件侦听机制 获取新的事件
简单的说就是 java nio中里面有一个selector 异步 I/O 中的核心对象名为 Selector。Selector 就是您注册对各种 I/O 事件的兴趣的地方,而且当那些事件发生时,就是这个对象告诉
您所发生的事件。
我们先给出一个例子把:
package org.web.niotest; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Set; /** * java NIO 服务器端例子 * @author user * */ public class Server { //服务器端通道 ServerSocketChannel ssc; public void start(){ try { //异步IO的核心对象名selector 具有事件侦听的效果 //selector就是您注册对各种io事件的兴趣的地方 而且当那些事件发生时 就是这个对象告诉您所发生的事情 Selector selector=Selector.open(); //打开一个serversocketchannel通道 ServerSocketChannel ssc=ServerSocketChannel.open(); //设为异步 ssc.configureBlocking(false); //绑定端口 ServerSocket ss=ssc.socket(); InetSocketAddress address=new InetSocketAddress(5555); ss.bind(address); //注册事件 regisiter的第一个参数总是selector 第二个总是op_accept 这里他指定我们要监听accept事件 //也就是当有新的链接进来是发生的事件 ssc.register(selector,SelectionKey.OP_ACCEPT); System.out.println("端口注册完成"); while(true){ //select()这个方法会阻塞 直到有一个已注册的事件发生 当一个或者更多的事件注册进来的时候 这个会返回事件的数量 selector.select(); //调用selectedKeys()会返回事件对象集合 Set<SelectionKey> selectionKeys=selector.selectedKeys(); //然后我们迭代处理每一个事件 Iterator<SelectionKey> iter=selectionKeys.iterator(); ByteBuffer echoBuffer=ByteBuffer.allocate(20); SocketChannel sc; while(iter.hasNext()){ SelectionKey key=iter.next(); //判断事件类型 if((key.readyOps()&SelectionKey.OP_ACCEPT)==SelectionKey.OP_ACCEPT) { ServerSocketChannel nssc=(ServerSocketChannel)key.channel(); sc=nssc.accept(); //设为非阻塞 sc.configureBlocking(false); sc.register(selector, SelectionKey.OP_READ); iter.remove(); System.out.println("有新的链接"+sc); }else if((key.readyOps()&SelectionKey.OP_READ)==SelectionKey.OP_READ) { sc=(SocketChannel)key.channel(); while(true){ echoBuffer.clear(); int a=sc.read(echoBuffer); if(a==-1) break; if(a>0){ byte[] b=echoBuffer.array(); System.out.println("接收数据: "+new String(b)); echoBuffer.flip(); sc.write(echoBuffer); System.out.println("返回数据: "+new String(b)); } } sc.close(); System.out.println("连接结束"); System.out.println("============================="); iter.remove(); } } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String args[]){ new Server().start(); } } 客户端的代码 package org.web.niotest; import java.net.*; import java.nio.*; import java.nio.channels.*; public class Client { public void start() { try { SocketAddress address = new InetSocketAddress("localhost", 5555); SocketChannel client = SocketChannel.open(address); client.configureBlocking(false); String a = "asdasdasdasddffasfas"; ByteBuffer buffer = ByteBuffer.allocate(20); buffer.put(a.getBytes()); buffer.clear(); int d = client.write(buffer); System.out.println("发送数据: " + new String(buffer.array())); while (true) { buffer.flip(); int i = client.read(buffer); if (i > 0) { byte[] b = buffer.array(); System.out.println("接收数据: " + new String(b)); client.close(); System.out.println("连接关闭!"); break; } } } catch (Exception e) { e.printStackTrace(); } } public static void main(String args[]){ new Client().start(); } }