Netty——解决TCP粘包、拆包

 我来答
没文化的大脑袋CU
2022-06-06 · TA获得超过2698个赞
知道小有建树答主
回答量:556
采纳率:100%
帮助的人:79.1万
展开全部

TCP是面向连接的,面向流的,提供高可靠性服务。收发两端(客户端和服务器端)都要有一一成对的socket,因此,发送端为了将多个发给接收端的包,更有效的发给对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包。这样做虽然提高了效率,但是接收端就难于分辨出完整的数据包了,因为面向流的通信是无消息保护边界的。

由于TCP无消息保护边界, 需要在接收端处理消息边界问题,也就是我们所说的粘包、拆包问题。

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

特别要注意的是,如果TCP的接受滑窗非常小,而数据包D1和D2比较大,很有可能会发生第五种情况,即服务端分多次才能将D1和D2包完全接受,期间发生多次拆包。

解决问题的根本手段就是找出消息的边界

Netty提供了以下三种方式解决TCP粘包和拆包问题:

DelimiterBasedFrameDecoder是通过发送方每条报文结束都添加特殊符号( $_ ) 作 为 报 文 分 隔 符,接收方通过特殊符号( $_ )对报文进行切割。

发送方需要自行编码,添加分隔符,编码如下:

接收方的解码如下:

缺点:发送的内容本身可能会出现分隔符,需要对发送的内容进行扫描并转义,接收到的内容也要进行反转义。

一种解决策略是,发送方对需要发送的内容预先进行base64编码,由于base64编码只包含64个字符:0-9、a-z、A-Z、+、/,我们可以选择这64个字符之外的特殊字符作为分隔符。

DelimiterBasedFrameDecoder提供了多个构造方法,最终调用的都是以下构造方法:

参数说明:

LineBasedFrameDecoder可以当成是一种特殊的DelimiterBasedFrameDecoder,其分隔符为\n或者\r\n。

发送方的编码如下:

接收方的解码如下:

FixedLengthFrameDecoder是通过发送方固定每条报文长度均为n个字节,接收方也通过n个字节长度切分报文。

发送方需要自行补齐长度,编码如下:

接收方的解码如下:

缺点:如果发送的内容比较小,需要补齐长度,空间浪费,如果要发送的内容突然变大,需要调整发送方和接收方的长度。

LengthFieldBasedFrameDecoder的构造方法如下:

参数说明:

参考:
https://www.cnblogs.com/Leo_wl/p/10297113.html

https://www.cnblogs.com/sidesky/p/6913109.html

https://blog.csdn.net/u022812849/article/details/107254239

https://www.jianshu.com/p/c90ec659397c

https://network.51cto.com/art/201910/604438.htm

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式