NIO基本知识

NIO

NIO网络编程模型

NIO简介

NIO:Non-blocking I/O 或 New I/O

编程模型

  • 模型:对事物共性的抽象
  • 编程模型:对编程共性的抽象

BIO网络模型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RktlvAr7-1619948977392)BIO模型

缺点

大量并发的情况下,接入的客户端接收过多就会出现问题。

  • 阻塞式I/O模型(主要缺点)
  • 弹性伸缩性能力差
  • 多线程耗资源

NIO网络模型

  • 非阻塞IO
  • 弹性伸缩能力强
  • 单线程节约资源NIO模型

核心Selector

接收所有客户端selector链接,并且监听它们关心的事件,当事件发生之后,就会调用相应的事件处理器,来处理这个事件

NIO网络实现步骤

NIO核心

  • Channel:通道
  • Buffer:缓冲区
  • Selector:选择器(多路复用器)

Channel

简介

  • 双线性
  • 非阻塞性
  • 操作唯一性(buffer)

实现

  • 文件类:FileChannel
  • UDP:DatagramChannel
  • TCP:ServerSocketChannel / SocketChannel
//服务器通过服务端socket创建channel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

//Server bind port
serverSocketChannel.bind(new InetSocketAddress(8000));

//Server 监听 Client link, creat socketchannel link
SocketChannel SocketChannel = SocketChannel.accept();

//Client link distance host and port.
SocketChannel SocketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",8000));

Buffer

简介

  • 作用:读写Channel中数据
  • 本质:一个内存区域

属性

  • Capacity:容量(超过需要清空,才能继续)
  • Position:位置(表示当前位置,最大可谓Capaciyu - 1,当读取数据时,buffer会从写模式转发为读模式,position会重置为0,读取数据时,position会向后可读位置)
  • Limit:上限(表示最多可以读写多少数据)
  • Mark:标记

使用

//初始化长度为10的byte类型的buffer
ByteBuffer.allocate(10);
/*
*position:0
*limit:10
*capacity:10
*/

//向byteBuffer中写入三个字节
byteBuffer.put("abc".getBytes(Charset.forName("UTF-8")));
/*
*position:3
*limit:10
*capacity:10
*/

//将byteBuffer从写模式切换成读模式
byteBuffer.flip();
/*
*position:0
*limit:3
*capacity:10
*/

//从byteBuffer中读取一个字节
byteBuffer.get();
/*
*position:1
*limit:3
*capacity:10
*/

//调用mark方法记录下当前position位置
byteBuffer.mark();
/*
*mark:1
*position:1
*limit:3
*capacity:10
*/

//1. 调用get方法读取下一个字节
//2. 调用reset方法将position重置到mark位置
byteBuffer.get();
byteBuffer.reset();
/*
*mark:1
*position:1
*limit:3
*capacity:10
*/

// 调用clear方法,将所有属性重置
byteBuffer.clear();
/*
*position:0
*limit:10
*capacity:10
*/

Selecot

简介

  • 作用:IO就绪选择
  • 地位:NIO网络编程基础

使用

//创建Selector
Selector selector = Selector.open();

//将channel注册到selector上,监听读就绪事件
SelectionKey selectionKey = channel.register(selector, selectionKey);

//阻塞等待channel有就绪事件发生
int selectNum = selector.select();

//获取发生就绪事件的channel集合
set<SelectionKey> selectedKeys = selector.selectedKeys();

SelectionKey简介

  • 四个就绪状态常量
  • 有价值的属性

NIO编程实现步骤

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

NIO缺点

  • 麻烦:NIO类库和API繁杂
  • 心累:可靠性能力补齐,工作量和难度大
  • 有坑:Selector空轮询,导致CPU100%
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xingpeng-zhuang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值