Java NIO框架-Netty-7 TCP粘包/拆包

为什么会有这样的问题?

TCP是一个面向字节流的协议,所谓字节流就是没有界限的一串数据。要想从这个混沌的流中获取数据并解析含义必须经过:

分割读取-->解码 这两个基本过程。

其中我们将分割读取后获得的一段一段有含义的数据叫做包。

很显然,从TCP流中读取数据之初,我们并不知道包有多大,界限在哪里,因此我们常常会借助于一个一定大小的缓存区读取进行数据读取。也就是说每次读取缓存获得的数据可能包含一个整包,也可能包含包的一部分数据(这个就是半包)。我们需要将整包分割出来,这就是拆包,需要将不完整的包亲前后拼接起来,这就是粘包。

怎样解决?

定义界限

定长边界

例如FixedLengthFrameDecoder

变长边界,定义分割标志

例如通用的DelimiterBasedFrameDecoder,或者最常见的换行分割LineBasedFrameDecoder

残包缓冲

示例

以换行为分割标志的字符数据LineBasedFrameDecoder+StringDecoder

LineBasedFrameDecoder会遍历ByteBuf(定长缓冲区),如果遇到“\n”或者“\r\n”就认为是一个包界限,进行拆包/粘包操作。如果在定常缓冲区内没有找到这个界限就抛弃之前读到的码流并抛出异常。

StringDecoder的作用是将码流转换成字符串。

LineBasedFrameDecoder+StringDecoder可实现按换行分割的文本解码器,它常常用于TCP的粘包和拆包,但需要注意的是,单个包(每行数据)大小不能超出LineBasedFrameDecoder规定的缓冲区大小。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值