前文介绍了传统IO的WEB经典服务器 reactor模式前序:传统IO的WEB服务器设计
下面看看JAVA NIO的WEB服务器设计
NIO是基于事件驱动的,对于NIO来说,重要组件是Selector,其服务器代码为:
/* * 流程总结: * 1.初始时,只对accept事件感兴趣,selectionkey只有accept事件 * 2.当有连接进来时,处理完accept之后,对读事件感兴趣,selectionkey增加键read * 3.不断循环selectionkey的键集合 */ Selector selector = Selector.open(); ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); // 设置为非阻塞 // 绑定监听端口号 serverSocketChannel.bind(new InetSocketAddress(8899)); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); // 对连接事件感兴趣 while (true) { Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> iterator = keys.iterator(); while(iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); if(selectionKey.isAcceptable()) { ServerSocketChannel serverSocketChannel1 = (ServerSocketChannel) selectionKey.channel(); SocketChannel socketChannel = serverSocketChannel1.accept(); // 此处阻塞 socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); iterator.remove(); } else if(selectionKey.isReadable()) { // 完成功能:从客户端接收数据并且原样返回给客户端 SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); while (true) { ByteBuffer byteBuffer = ByteBuffer.allocate(512); byteBuffer.clear(); int read = socketChannel.read(byteBuffer); if(read <= 0) { break; // 数据已接收完毕 } byteBuffer.flip(); socketChannel.write(byteBuffer); } iterator.remove(); } } }