粘包/拆包

现象

  • 客户端发送两个数据包,p1,p2。服务端接收分三种情况

    • 一:正常image.png
    • 二:只接收到一个数据包,由于Tcp不会出现丢包,所以一个李米娜包含了两个的信息,即为粘包,接后端不知道怎么分割。
    • image.png
    • 三:接收端接收到两个,但是两个要么不完整,要么多了。就会发生粘包拆包。

      1. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12844611/1630040895416-5aa31f62-3c79-4337-b1c6-d65219de2361.png#clientId=uf22e8807-1393-4&from=paste&id=u28d199a3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=91&originWidth=550&originalType=url&ratio=1&size=23219&status=done&style=none&taskId=u8f3c732a-adb6-4572-a15b-71ab359952a)

      产生原因

  • 写入的数据大小大于套接字缓存大小,会发生拆包。

  • 写入数据小于套接字缓冲区大小,网卡将应用多次写入的数据发送到网络上,将发生粘包。
  • 进行MSS(最大报文长度)大小的TCP分段,当TCP报恩长度 - TCP头部长度 > MSS的时候发生拆包。
  • 接收方不及时读取套接字缓冲区数据,将发生粘包。

    解决

  • 在报文末尾增加换行符表明一条完整的消息,这样在接收端可以根据这个换行符来判断消息是否完整。

  • 将消息分为消息头、消息体。可以在消息头中声明消息的长度,根据这个长度来获取报文(比如 808 协议)。
    规定好报文长度,不足的空位补齐,取的时候按照长度截取即可。