在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() +"处理完成处理..."); } } } } }