前言

有一天小明高兴的去面试,突然间面试官抛出一个问题:什么是TCP粘包?这下子好了,小明脑袋搜索了TCP的内容,发现只搜索到TCP和UDP的区别,流量控制,拥塞控制,和三握四挥这几个内容,小明尴尬的说:我不知道。于是回来恶补了TCP粘包的内容

关键词:TCP粘包、拆包

什么是TCP粘包

现在假设客户端连续发了两个数据包给服务端,用pack1和pack2来表示,那么就有以下几种情况:

  1. 接收端正常收到了两个数据包,没有发生异常
  2. 接收端只收到一个数据包,因为TCP不会丢包所以这个数据包包含了发送端发送的两个数据包,这就是粘包。服务端不知道怎么划分这两个数据包所以很难处理。
  3. 接收端收到两个数据包,但它们都不完整。这种情况下可能是pack1丢了一点到pack2,也有可能是pack2丢了一点到pack1,此时发生了粘包拆包

为什么会发生粘包拆包

原因如下:

  1. 本身套接字缓冲区大小不足,一次写入的数据多了,就发生了拆包
  2. 本身套接字缓冲区过大,多次写入数据,就发生了粘包
  3. TCP连接复用,本来单独的连接中双方规定好了数据格式,但是因为复用导致多个进程以及不同的数据格式传输,就造成了粘包
  4. 接收方没及时接收数据,就发生了粘包

解决方法

解决方法就是处理这个边界问题。

  1. 尾部标识法:通过协商的尾部标记,比如\n\t\r等来说明这是边界
  2. 头部标记法:不是不知道长度吗?直接在TCP头部加上标识数据长度
  3. 定长发送法:发送端封装数据包为指定长度发送