TCP粘包拆包问题解决之道

1. TCP粘包/拆包问题

在这里插入图片描述
假设客户端分别发送了两个数据包D1和D2,由于服务端一次读取到的字节数是不确定的,故存在以下四种情况。

  • 服务端分两次读取到了两个独立的数据包,分别是D1和D2,没有发生粘包和拆包。
  • 服务端一次接收到了两个数据包,D1和D2粘在一起,被称为TCP粘包。
  • 服务端分两次读取到了两个数据包,第一次读取到了完整的D1包和D2包的部分内容,第二次读取到了D2包的剩余内容,这被称为TCP拆包
  • 服务端分两次读取到了两个数据包,第一次读取到了D1包的内容D1_1,第二次读取到了D1包的包的剩余内容D1_2和D2的整包。

如果此时服务端的TCP的接受滑窗非常小,而数据包D1和D2比较大,很有可能会发生第五种可能,即服务端分多次才能将D1和D2包的接收完全,期间发生多次拆包。

2. TCP粘包/拆包发生的原因

主要有三种原因:

  • 应用程序write写入的字节大小大于套接字接口的发生缓冲区大小
  • 进行MSS大小的TCP分段
  • 以太网帧的payload大于MTU进行了IP分片

在这里插入图片描述

3. TCP粘包解决策略

由于地层的TCP无法理解上层的业务数据,所以在底层是无法保证数据包不被拆分和重组的,这个问题只能通过上层的应用协议栈设计来解决,根据业界主流的协议的解决方案可以归纳如下:

  • 消息定长,例如每个报文固定长度200字节,如果不够,空位补空格
  • 在包尾添加回车换行符进行分割,例如FTP协议
  • 将消息分为消息头和消息体,消息头中包含表示消息总长度的字段
  • 更复杂的应用层协议
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值