Netty笔记——粘包和拆包

  • 粘包和拆包
  • 发生原因
  • 业界解决策略
  • Netty提供的策略
    • LineBasedFrameDecoder
    • DelimiterBasedFrameDecoder
    • FixLengthFrameDecoder

1. 粘包和拆包

假设客户端分别发送了两个数据包D1和D2给服务端,由于服务端一次读取到字节数是不确定的,故可能存在以下四种情况:

  • 服务端分两次读取到了两个独立的数据包,分别是D1和D2,没有粘包和拆包
  • 服务端一次接受到了两个数据包,D1和D2粘合在一起,称之为TCP粘包
  • 服务端分两次读取到了数据包,第一次读取到了完整的D1包和D2包的部分内容,第二次读取到了D2包的剩余内容,这称之为TCP拆包
  • 服务端分两次读取到了数据包,第一次读取到了D1包的部分内容D1_1,第二次读取到了D1包的剩余部分内容D1_2和完整的D2包。
  • 特别要注意的是,如果TCP的接受滑窗非常小,而数据包D1和D2比较大,很有可能会发生第五种情况,即服务端分多次才能将D1和D2包完全接受,期间发生多次拆包。


2. 发生原因

(1)UDP协议是否会发生粘包或者拆包问题

  • 答:不会。UDP是基于报文发送的,在UDP首部采用了16bit来指示UDP数据报文的长度,因此在应用层能很好的将不同的数据报文区分开

(2)TCP发生粘包和拆包的原因

通俗的讲:有两点原因

  • TCP是基于字节流的,TCP把报文数据块看成一连串无结构的字节流,没有边界
  • 在TCP的首部没有表示数据长度的字段

具体的讲:有三个原因

  • 3滑动窗口:为了防止客户端发送过快,TCP有滑动窗口机制,服务端和客户端都设立了缓存区
    • 拆包情况1:如果发送方的窗口只剩128,而要发包的大小256,那么就会拆包
    • 粘包情况1:如果发送方的窗口为500,TCP将多次写入缓冲区的数据一次发送出去(256 + 244),将会发生粘包
    • 粘包情况2:接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包
  • MSS / MTU限制
    • MSS:表示TCP报文中data部分的最大长度,根据MSS计算得出,MSS长度=MTU长度-IP Header-TCP Header
    • MTU:链路层对一次可以发送的最大数据的限制,默认1500个字节
    • 当需要传输的数据大于MSS或者MTU时,数据会被拆分成多个包进行传输
  • Nagle算法
    • 见Reference

3. 解决策略

解决策略

  • 消息定长,例如每个报文固定200字节,如果不够,空位补空格

  • 在包尾增加回车换行符进行分割,如FTP协议

  • 将消息分为消息头和消息体,消息头中包含消息的长度,字段等信息 。通常消息头第一个字段用int32表示消息总长度

  • 更复杂的应用层协议


4. Netty解决策略:

  • LineBasedFrameDecoder:将回车换行符作为消息结束符

  • DelimiterBasedFrameDecoder:将固定字符作为分割依据

ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes());
//单条消息最大长度为1024,用"$_"分割
ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, delimiter));
  • FixLengthFrameDecoder:固定长度

ch.pipeline().addLast(new FixLengthFrameDecoder(20));    //以20为长度

Reference

https://www.cnblogs.com/yaochunhui/p/14175396.html

https://blog.csdn.net/john1337/article/details/102806307

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值