Non-Blocking I/O 或 New I/O,开始与JDK1.4 服务于高并发网络服务器
NIO网络模型
NIO核心
Channel:通道Buffer:缓冲区Selector:选择器 或者 多路复用器特性
双向性非阻塞操作唯一性:基于字节块操作,只能通过Buffer实现
文件类:FileChannelUDP类:DatagramChannelTCP类:ServerSocketChannel / SocketChannelSocket回顾 服务端代码
/** *1. 监听端口 */ ServerSocket ServerSocket = new ServerSocket(port:8000); while(true) { // 2. 接受请求,建立连接 Socket socket = serverSocket.accept(); // 3. 数据交换 new Thread(new BIOServerHandler(socket)).start(); } /** *4. 关闭资源 */ serverSocket.close();客户端代码
/** *1. 建立连接 */ Socket socket = new Socket("127.0.0.1", port:8000); /** * 获取输入输出流 */ InputStream inputStream = socket.getInputStream(); OutputStream outputStream = socket.getOutputStram();Channel使用
/** *代码片段1: 服务器端通过服务端socket创建channel */ ServerSocketChannel ServerSocketChannel = ServerSocketChannel.open(); /** * 代码片段2:服务器端绑定端口 */ ServerSocketChannel.bind(new InetSocketAddress(8000); /** * 代码片段3:服务器端监听客户端连接,建立socketChannel连接 */ SocketChannel socketChannel = serverSocketChannel.accept(); /** * 代码片段4:客户端连接远程主机及端口 */ SocketChannel socketChannel = SocketChannel.open( new InetSocketAdress("127.0.0.1", 8000));作用:读取Channel中的数据 本质:一块内存区域 Buffer属性:
Capacity:容量Position:位置Limit:上限Mark:标记Buffer的使用
/** *初始化长度为10的byte类型buffer */ ByteBuffer.allocate(10); /** * 向byteBuffer中写入三个字节 */ byteBuffer.put("abc".getBytes(Charset.forName("UTF-8"))); /** *将byteBuffer从写模式切换为读模式 */ byteBuffer.flip(); /** * 从byteBuffer中读取一个字节 */ byteBuffer.get(); /** * 调用mark方法记录当前position的位置 */ byteBuffer.mark(); /** *调用clear方法,将所有的属性重置 */ byteBuffer.clear();作用:I/O就绪选择,能够检测1到N个通道,并能知道通道是否为读写做好准备的组件,通过它,一个单独的线程就能管理多个Channel,从而管理多个网络连接 地位:NIO网络编程的基础 Selector使用
/** * 代码片段1:创建Selector */ Selector selector = Selector.open(); /** * 代码片段2:将channel注册到selector上,监听读就绪事件 */ SelectionKey selectionKey = chennel.register(selector, SelectionKey.OP_READ); /** * 代码片段3:阻塞等待channel有就绪事件发生 */ int selectNum = selector.select(); /** * 代码片段4:获取发生就绪事件的channel集合 */ Set<SelectionKey> selectedKeys = selector.selectedKeys();SelectionKey简介
四种就绪状态常量:Connected,Accept,Read , Write有价值的属性