TCP的粘包问题及解决办法

什么是粘包?

TCP本身面向字节流的协议,它本身就没有“包”的概念,所以说粘包也不能说是它的缺陷,这是必然会出现的情况。

传输过程中出现的情况:
在这里插入图片描述
情况1:
数据包1和数据包2正常发送过去,没有发送粘包现象。
情况2:
数据包1和数据包2组成一个数据包被发送了过去,出现了粘包现象。
情况3:
数据包2被分成了两块,一块和数据包1粘在一起发送了过去,另一块和数据包3粘在一起发送了过去。

举个例子

比如说我们要发送“abc” ,"edf”

按照第一种情况:
正常发送了过去
接收方知道了对方想发送两个字符,一个是"abc",一个是"def"。

按照第二种情况:

发送过去后则就变成
“abcdef” ,接收端也不知道对方想发送的是什么?
是“abcdef”呐,还是“a” "bcdef"呐,还是“ab” “cdef” 等等(情况有很多)。

按照第三种情况
假如说之后要发送数据包是"hjk"。
则发送过去就变成了
“abcde” “fhjk”。
和上面一样,接收端也不知道发送端发送的具体是什么。

为什么会出现粘包的问题?

对于发送端:

1.因为数据包还包含报头信息,所以为了提高传输效率 ,发送方往往会收集到足够的数据才会把数据一次发送过去。
2.因为协议的原因,有MSS的限制,数据包过长就会分开传输。

对于接收端:
若接收端没有及时从缓冲区取走数据,等到下个数据包到达时,也就会存储到缓冲区,这样和之前的数据包混在一起,也就发生了粘包现象。

本质原因就是接收端并不知道每个包具体的大小,或者是每个包的边界。

UDP为什么没有粘包?

因为UDP不是流式传输,而是面向消息传输的,它每次都只传输一条消息,所以不会出现粘包的情况。

解决办法

1.发生定长数据包。
如果消息的长度都是一样的话,那么接收方只要计算消息的长度,当达到该定长时,就把它划做一个消息。
2.包尾部加上标记。
如在包尾加上\r\n,但是这种有一个问题,假如说消息的内容中有\r\n,则此处将会被当作消息的尾部,所以我们要避免这种情况。
3.在包头中加上包的长度
当对方收到后,按照包的长度进行读取则就可以了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值