粘包问题

流协议与粘包

TCP是个流协议

  • TCP是基于字节流传输的,只能维护发出去多少,确认多少,没有维护消息与消息之间的边界,因此可能导致粘包问题。
  • 粘包问题解决方法是在应用层维护消息边界。

这里写图片描述
如图反应了包在网络中的传输情况。我们无法预知TCP接收缓冲区中收到的数据原本的边界是什么。

产生原因

这里写图片描述

TCP是一个字节流、无边界的。对于客户端和服务端来说,一次读操作,不保证能读完数据。接收的数据包个数也是不确定的。

产生粘包问题的原因分析:
1、SQ_SNDBUF 套接字本身有缓冲区 (发送缓冲区、接受缓冲区)
2、tcp传送的端 mss大小限制
3、链路层也有MTU大小限制,如果数据包大于>MTU要在IP层进行分片,导致消息分割。
4、tcp的流量控制和拥塞控制,也可能导致粘包
5、tcp延迟发送机制 等等
结论:tcp/ip协议,在传输层没有处理粘包问题。

解决方案

本质:上是要在应用层维护消息与消息的边界

两种方式

  • 包尾加\n
    • \n作为协议的边界
    • recv()使用MSG_PEEK标志
  • 包头加上包体长度
    • 发报文时,前四个字节长度(转成网络字节序)+包体
    • 收报文时,先读前四个字节,求出长度;根据长度读数据

猜你喜欢

转载自blog.csdn.net/xiaoyutao96/article/details/79204817