在java的套接字编程中,大部分一般使用阻塞IO套接字编程。套接字的读取和写入会阻塞(也就是说不管现在有没有写入/读出数据 调用read和write方法将会阻塞)。而NIO将I/O事件注册,当特定的注册I/O事件到达时会通知您。不需要轮询,也不需要创建大量的线程下面一个例子:下载
Server代码
package simple.socket; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.nio.ByteBuffer; import java.nio.channels.*; import java.util.Iterator; import java.util.Set; /** * Created by banxia on 16/10/12. */ public class UseNioSocket { public static void main(String[] args) throws IOException { // 创建一个selector 对象 Selector selector = Selector.open(); ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.configureBlocking(false); ssc.socket().bind(new InetSocketAddress(8888)); ssc.register(selector, SelectionKey.OP_ACCEPT); ByteBuffer buffer = ByteBuffer.allocate(1024); System.out.println("服务已经启动端口:" + 8888); while (true) { int selectNum = selector.select(); System.out.println("selectNum=" + selectNum); if (selectNum <= 0) { continue; } // 获取 Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey key = it.next(); if (key.readyOps() == SelectionKey.OP_ACCEPT) { // 接收 accept ServerSocketChannel channel = (ServerSocketChannel) key.channel(); SocketChannel accept = channel.accept(); accept.configureBlocking(false); System.out.println("接收客户端:" + accept.socket().getInetAddress().getHostAddress() + ":" + accept.socket().getPort()); accept.register(selector, SelectionKey.OP_READ); it.remove(); } else { SocketChannel sc = (SocketChannel) key.channel(); System.out.println("接收客户端:" + sc.socket().getInetAddress().getHostAddress() + ":" + sc.socket().getPort() +"开始处理..."); while (true) { buffer.clear(); long l = sc.read(buffer); if (l <= 0) { break; } System.out.print("."); buffer.flip(); sc.write(buffer); } System.out.print("\n"); it.remove(); System.out.println("接收客户端:" + sc.socket().getInetAddress().getHostAddress() + ":" + sc.socket().getPort() +"处理完成处理..."); } } } } }