网络编程03

AIO NIO和BIO的区别

  • BIO,NIO和AIO是Java网络编程的三种模型

    • BIO:同步并阻塞,服务实现模式为一个连接对应一个线程,即客户端发送一个连接,服务端要有一个线程来处理。如果连接多了,线程数量不够,就只能等待,即会发生阻塞。
    • NIO:同步非阻塞,服务实现模式是一个线程可以处理多个连接,即客户端发送的连接都会注册到多路复用器上,然后进行轮询连接,有I/O请求就处理
    • AIO:异步非阻塞,引入了异步通道,采用的是proactor模式,特点是:有效的请求才启动线程,先有操作系统完成在通知服务端
  • 应用场景:

    • BIO:适用连接数目比较小且固定的架构,对服务器要求比较高,并发局限于应用中
    • NIO:适用连接数目多且连接比较短的架构,如:聊天服务器,弹幕系统等,编程比较复杂
    • AIO:适用连接数目多且连接长的架构,如相册服务器
  • 粘包处理

NIO Socket是非阻塞的通讯模式,与IO阻塞式的通讯不同点在于NIO的数据要通过Channel放到一个缓存池ByteBuffer中,然后再从这个缓存池中读出数据,而 IO 的模式是直接从InputStream中read。所以对于NIO,由于存在缓存池的大小限制和网速的不均匀会造成一次读的操作放入缓存池中的数据不完整,便形成了断包问题。同理,如果一次性读入两个及两个以上的数据,则无法分辨两个数据包的界限问题,也就造成了粘包。

粘包问题主要是由于数据包界限不清,最好的解决办法就是在发送数据包前事先发送一个int型数据,该数据代表将要发送的数据包的大小,这样接收端可以每次触发OP_READ的时候先接受一个int大小的数据段到缓存池中,然后,紧接着读出后续完整的大小的包,这样就会处理掉粘包问题。因为channel.read()方法不能给读取数据的大小的参数,所以无法手动指定读取数据段的大小。但每次调用channel.read()返回的是实际读取的大小。

  • 常见的解决粘包、拆包的思路有:分隔符、固定消息长度、TLV格式消息等

解决思路:首先调整缓存池的大小固定为要读出数据段的大小,这样保证不会过量读出。由于OP_READ和OP_WRITE不是一一对应的,所以一次OP_READ可以while循环调用channel.read()不停读取Channel中的数据到缓存池,并捕获其返回值,当返回值累计达到要读取数据段大小时break掉循环,这样保证数据读取充足。所以这样就完美解决粘包问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值