# Nio NIO指非阻塞式I/O.

JDKNIOSocketServerSocket 提供了 SocketChannelServerSocketChannel两种不同的套接字通道实现。支持阻塞和非阻塞两种操作。

4.1.1.3. NIO 类库简介

4.1.1.3.1. 缓冲区Buffer

  • NIO 库中,所有的操作都是用缓冲区处理的(读写)
  • 缓冲区实质上是一个数组。通常是ByteBuffer,JDK基本数据类型(除Boolean)都有对应的缓冲区实现。
  • 提供对数据结构化访问以及维护读写位置(limit)等信息

除了ByteBuffer外,其他的实例都有完全一样的操作。ByteBuffer方便网络的读写

4.1.1.3.2. 通道 Channel

Channel 像自来水管一样,网络数据通过Channel读取和写入

  • 通道是双向的(流是单向的且必须是InputStream和OutputStream的子类),读写可同时进行
  • 全双工的;能更好的映射系统API,如UNIX网络模型中,底层操作系统的通道都是全双工的。同时支持读写操作。

前三层几乎上都是接口定义Channel功能。可分为两大类:

  • SelectableChannel : 网络读写
  • FileChannel : 文件读写

4.1.1.3.3. 多路复用器 Selector

多路复用是NIO的基础,非常重要!

  • 提供选择已经就绪的任务的能力

    简单来说:Selector会不断轮训注册在其上的Channel,如果某个Channel上面发送读或则写事件,这个Channel就处于就绪状态,会被Selector轮询出来,然后通过SelectorKey可以获取就绪Channel的集合,进行后续的I/O操作

  • 一个多路复用Selector可同时轮训多个Channel.JDK使用eplll()实现select,所以可以用一个线程负责Selector的轮训,就可以接入成千上万的客户端。

4.1.1.3.4. 服务端通信序列图

  1. 打开sock通道
  2. 绑定监听端口,并设置链接为非阻塞模式
  3. 创建多路复用器,并启动线程
  4. 将通道注册到 线程的多路复用器上,并监听accept事件
  5. 多路复用器在线程run方法中无线轮询准备就绪的Key
  6. 多路复用器监听到有新的客户端接入,处理新的接入请求,完成TCP三次握手,建立物理链路
  7. 设置客户端链路为非阻塞模式
  8. 将新接入的客户端链接注册到 多路复用器上,监听 读 操作。读取客户端的信息
  9. 异步读取客户端请求信息到缓冲区
  10. 对ByteBuff进行编码,如果有半包消息指针 reset。继续读取后续报文
  11. 调用SocketChannel的异步write,将消息异步发送给客户端。

注意: 如果发送区TCP缓冲区满,会导致写半包,次数,需要注册监听写操作位,循环写,直到整包消息写入TCP缓冲区中。 这些内容Netty中有处理策略。

4.1.1.3.5. 客户端通信序列图

© All Rights Reserved            updated 2017-02-15 22:36:40

results matching ""

    No results matching ""