Tommy

Tommy

写代码是热爱,但也是生活 !
github

什么是粘包?为什么出现?怎么解决呢?

前言#

什么是粘包?为什么出现?怎么解决呢?

1. 什么是粘包#

  1. 粘包出现在传输层和应用层之间,虽然他们之间的传输是一块一块的,但是 TCP 将这些一块块的数据看成无结构的字节流,没有边界
  2. 从 TCP 的帧结构可以看出,其首部没有表示数据长度的字段

从上面可看出,粘包就是一个数据包包含了两个数据包的信息
接收端收到了两个数据包,但是这两个数据包要么是不完整的,要么就是多出来一块,这种情况即发生了拆包和粘包。拆包和粘包的问题导致接收端在处理的时候会非常困难,因为无法区分一个完整的数据包。

2. 为什么会出现粘包#

粘包现象出现在传输层 TCP 中

  1. 发送端出现粘包
    当客户端和服务器之间传输采取 TCP 协议保持长连接状态时(当然,第一次连接发第一次请求不会出现粘包),但当发送的数据包过于的小时,那么 TCP 协议默认的会启用 Nagle 算法,将这些较小的数据包进行合并发送(缓冲区数据发送是一个堆压的过程);这个合并过程就是在发送缓冲区中进行的,也就是说数据发送出来它已经是粘包的状态了。
  2. 接收端出现粘包
    接收方采用 TCP 协议接收数据时的过程是这样的:数据到接收方,从网络模型的下方传递至传输层,传输层的 TCP 协议处理是将其放置接收缓冲区,然后由应用层来主动获取,这时会出现一个问题,就是我们在程序中调用的读取数据函数不能及时的把缓冲区中的数据拿出来,而下一个数据又到来并有一部分放入的缓冲区末尾,等我们读取数据时就是一个粘包。(放数据的速度 > 应用层拿数据速度)

3. 怎么解决拆包和粘包#

分包机制一般有两个通用的解决方法:

  • 特殊字符控制
  • 在包头首都添加数据包的长度。

如果使用 netty 的话,就有专门的编码器和解码器解决拆包和粘包问题了。

注意:UDP 没有粘包问题,但是有丢包和乱序。不完整的包是不会有的,收到的都是完全正确的包。传送的数据单位协议是 UDP 报文或用户数据报,发送的时候既不合并,也不拆分。

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。