NIO网络编程

2020-03-08  本文已影响0人  蓬莱辰

1. NIO请求过程:

  1. 服务端:Selector 组件,循环检测注册事件就绪情况,(负责管理客户端与服务端建立的连接,监听注册到其上的事件);
    首先服务端的 Selector 注册建立连接事件,
  2. 客户端发送建立连接请求;
  3. Selector监听到后,启动建立连接事件处理器 Acceptor Handler;
  4. Acceptor Handler 创建与客户端连接;
  5. 服务端 Acceptor Handler 响应客户端建立连接请求;
  6. 服务端 Acceptor Handler 向selector 注册连接可读事件;
  7. 客户端发送数据请求;
  8. Selector 监听到后,启动读写处理器 Read&Write Handler;
  9. 读写处理器处理客户端读写业务;
  10. 响应客户端请求;
  11. 注册连接可读事件。


    image.png

2. 相比BIO,NIO的优点:

2.1. 基于非阻塞式IO模型;
2.2. 弹性伸缩能力强:不是多个线程,而是一个线程处理所有请求,服务器端的线程数与客户端的接入数不是1:1;
2.3. 单线程节省资源:线程的频繁创建和销毁,线程上下文之间的额切换。

3. Java中的实现

3.1 Channel 通道

特点:

  1. 双向性:读写可用一个channel;
  2. 非阻塞性;
  3. 操作唯一性。
    Channel实现:
  4. 文件类:FileChannel;
  5. UDP类:DatagramChannel ;
  6. TCP 类:ServerSocketChannel / SocketChannel

3.2 ByteBuffer

作用:读写Channel中的数据;
实质:一块内存;
Capacity:容量
Position:位置,max:capacity-1
Limit:上限;
Mark:标记,存储position位置

/*
 * 创建一个新的 ByteBuffer
 * position:0
 * limit:10
 * capacity:10
 */
ByteBuffer byteBuffer = ByteBuffer.allocate(10);

/*
 * 向byteBuffer中写入三个字节
 *  position:3
 * limit:10
 * capacity:10
 */
byteBuffer.put("abc".getBytes(StandardCharsets.UTF_8));

/*
 * 将byteBuffer从写模式切换到读模式
 * position:0
 * limit:3 最多能读取的数量
 * capacity:10
 */
byteBuffer.flip();

// 读取一个字节
byteBuffer.get();

// 调用mark方法,记录当前position的位置
byteBuffer.mark();

/**
 * 先调用get方法,读取下一个字节,position=2,
 * 调用reset方法,position重置到mark位置
 */
byteBuffer.get();
byteBuffer.reset();

// 将所有属性重置
byteBuffer.clear();

3.3 Selector 多路复用器

// 创建selector
Selector selector = Selector.open();
// 将通道channel注册到selector上,监听连接事件
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
// 获取发生就绪事件的(可用)channel集合
Set<SelectionKey> selectionKeys = selector.selectedKeys();

4. NIO编程实现步骤

  1. 创建Selector;
  2. 创建ServerSocketChannel,并绑定监听端口;
  3. 将channel设置为非阻塞模式;
  4. 将channel注册到Selector上,并监听连接事件;
  5. 循环调用Selector的select方法,检测就绪情况;
    int readyChannelNum = selector.select();
  6. 调用Selector的selectedKeys方法获取就绪channel集合;
  7. 判断就绪事件的种类(连接事件 or 读事件),调用业务处理方法;
  8. 根据业务需求判断是否再次注册监听事件,重复第3步操作;

5.实战

简单聊天室功能:
源码:https://github.com/sliumhh/nio-bio

上一篇 下一篇

猜你喜欢

热点阅读