TCP原理 粘包分包现象

参考:
云栖社区:就是要你懂 TCP– 最经典的TCP性能问题

粘包现象产生的原因

由于TCP协议本身的机制(三次握手)客户端与服务器会维持一个连接(Channel),数据在连接不断开的情况下,可以持续不断地将多个数据包发往服务器,但是如果发送的网络数据包太小,那么他本身会启用Nagle算法(可配置是否启用)对较小的数据包进行合并(基于此,TCP的网络延迟要UDP的高些)然后再发送(超时或者包大小足够)。

客户端Send:hello
客户端Send:csdn
服务端Recv:hellocsdn

多个数据包被合并在一起发送。客户端发送两次数据,服务端只响应一次接收。

分包现象产生的原因

  • 可能是IP分片传输导致的。
  • 可能是传输过程中丢失部分包导致出现的半包 。
  • 可能是一个包可能被分成了两次传输,在取数据的时候,先取到了一部分。
  • 还可能与接收的缓冲区大小有关系。

客户端Send:hellocsdn
服务端Recv:hello
服务端Recv:csdn

 一个数据包被分成了多次接收。客户端发送一次数据,服务端收到两个包。

粘包与分包的解决办法

  • 一个是采用分隔符的方式,即我们在封装要传输的数据包的时候,采用固定的符号作为结尾符(数据中不能含结尾符),这样我们接收到数据后,如果出现结尾标识,即人为的将粘包分开,如果一个包中没有出现结尾符,认为出现了分包,则等待下个包中出现后 组合成一个完整的数据包,这种方式适合于文本传输的数据,如采用/r/n之类的分隔符;

  • 另一个是采用在数据包中添加长度的方式,即在数据包中的固定位置封装数据包的长度信息(或可计算数据包总长度的信息),服务器接收到数据后,先是解析包长度,然后根据包长度截取数据包(此种方式常出现于自定义协议中),但是有个小问题就是如果客户端第一个数据包数据长度封装的有错误,那么很可能就会导致后面接收到的所有数据包都解析出错(由于TCP建立连接后流式传输机制),只有客户端关闭连接后重新打开才可以消除此问题,可以在处理这个问题的时候对数据长度做校验,会适时的对接收到的有问题的包进行人为的丢弃处理(客户端有自动重发机制,故而在应用层不会导致数据的不完整性);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章