关于粘包的解决方法

Posted 看,未来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于粘包的解决方法相关的知识,希望对你有一定的参考价值。

什么是粘包?

不知道。
不知道还点进来了,看来是真爱了。

就是字面意思,网络通信中数据包粘在一起了。


为什么会产生粘包?

对于TCP:一次一个小包太慢了吧!!! 大包也就算了,小包还一次一个。合在一起凑够缓冲区一起发吧。所以TCP叫流式数据传输啊!
对于UDP:不会使用块的合并优化算法,采用了链式结构来记录每一个到达的UDP包。所以不会粘包。所以UDP叫报文数据传输啊。

TCP为用户提供了高可靠性的网络传输服务,但可靠性保障措施也影响了传输效率。因此,在实际工程应用中,只有关键数据的传输才采用TCP,而普通数据的传输一般采用高效率的UDP。


那就任由UDP这样子“逍遥法外”吗?
我一个缓冲区假设1K,你一个包给我发100字节数据算怎么肥四?那我一次明明可以发你10个包的,不能给我把十个包凑一凑一并发了?
所以那就一并发了吧。。。


什么时候会出现TCP粘包?

长连接 + 不定长包。


解决粘包的方案

我突然就想起来老师跟我们说用定长包的好处之一就是不会粘包。。。

这里面就包含了一个解决方案:
定长

此定长非彼定长。彼定长,怕不是每次都只发送某个固定长度的包吧,那就没意思了。我的定长的意思是,在包头里面预留四个字节的空间,用来在封包的时候加上包的长度,收包的时候这样收:

1、recv,return n;
2、读取包头,长度 m;
3、解析包头,获取整包(或包体)长度k
4、读取包体(4)
5、读取包尾
	6、若包正常,标兵位置后移 m+k+4,相应n减小。返回步2,直到n为07、若包不正常,那完了,一整串全没了。开玩笑,只要正常找到包尾就好了,向前向后遍历,不过就很麻烦,会丢一个包,至少一个。
8、一般不会不正常吧,TCP检测很严格的,包破了怎么能正常通信哈哈。

原来曾经就使用过,但是不知道解决方法竟然在身边。不过我后面做不定长包那个确实是没有拆包的。。。


一种比较周全的对策是:接收方创建一预处理线程,对接收到的数据包进行预处理,将粘连的包分开。对这种方法我将进行实验处理,可行的话我就不说了,不可行的话回头发评论区。

以上是关于关于粘包的解决方法的主要内容,如果未能解决你的问题,请参考以下文章

关于TCP粘包的Netty处理的方法

解决Socket通信中,经常遇到的问题——数据粘包的两种方法

峰哥解决粘包的方式

c# socket 客户端 循环发包 服务器端粘粘包严重!求高手给我个解决粘包的例子!

透过现象看本质,我找到了Netty粘包与半包的这几种解决方案。

关于TCP粘包和拆包的终极解答