一、使用 NIO 完成网络通信的三个核心: 1. 通道(Channel):负责连接 java.nio.channels.Channel 接口: |--SelectableChannel |--SocketChannel |--ServerSocketChannel |--DatagramChannel |--Pipe.SinkChannel |--Pipe.SourceChannel 2. 缓冲区(Buffer):负责数据的存取 3. 选择器(Selector):是 SelectableChannel 的多路复用器。用于监控 SelectableChannel 的 IO 状况
二、服务端开发流程
获取通道切换非阻塞模式绑定连接获取选择器将通道注册到选择器上, 并且指定“监听接收事件”轮询式的获取选择器上已经“准备就绪”的事件获取当前选择器中所有注册的“选择键(已就绪的监听事件)”获取准备“就绪”的是事件判断具体是什么事件准备就绪若“接收就绪”,获取客户端连接客户端链接切换非阻塞模式将该通道注册到选择器上获取当前选择器上“读就绪”状态的通道读取数据三、客户开发流程
获取通道切换非阻塞模式分配指定大小的缓冲区发送数据给服务端四、代码实例
package cn.com.github.nio.file; import java.io.IOException; import java.net.InetSocketAddress; 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; /** * 类的描述信息 * * @author panzhuowen * @version 1.0.1 */ public class Server { public static void main(String[] args) throws IOException { ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); serverSocketChannel.bind(new InetSocketAddress(8089)); Selector selector = Selector.open(); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while (selector.select() > 0) { Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); while (iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); if (selectionKey.isAcceptable()) { SocketChannel socketChannel = serverSocketChannel.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); } else if (selectionKey.isReadable()) { SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); ByteBuffer byteBuffer = ByteBuffer.allocate(1024); int len = 0; while((len = socketChannel.read(byteBuffer)) > 0 ){ byteBuffer.flip(); System.out.println(new String(byteBuffer.array(), 0, len)); byteBuffer.clear(); } } } iterator.remove(); } } }