Netty学习之TCP的拆包与粘包

什么是TCP粘包和拆包

TCP是流协议,就像河里的水,它们是连成一片的,TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上任务,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能将多个小包封装成大包发送。这就是所谓的TCP粘包和拆包问题.

具体以一幅图说明:
tcp.png
假设发送两个包 D1和D2 服务器读取情况可能是:

  • 分两次收到两个数据包,没有进行粘包和拆包
  • 一次收到两个数据包, D1和D2粘合到一起,这就是粘包
  • 分两次接受两个包,第一次接受完整的D1和部分D2,第二次收到剩余的部分D2,这就是TCP拆包
  • 与第三种情况相反,也是拆包的表现
  • 更复杂的情况,可能会发生多次拆包

TCP拆包粘包的原因

知其然知其所以然 产生的原因有

  • 应用程序wirte的字节大小 > 套接字发送缓冲区大小
  • 进行 MSS大小的TCP分段
  • 以太网帧的payload > MTU 进行IP分片

解决策略

  • 消息定长, 例如每个报文大小固定长度200字节,如果不够,空位不空格
  • 在包尾增加回车换行进行分割 如FTP协议
  • 将消息分为消息头和消息体,消息头包含消息总长度(或者消息体的长度)的字段,通常设计思路为消息头的第一个字段使用int32来表示消息的总长度
坚持原创技术分享,您的支持将鼓励我继续创作!