为什么会有粘包拆包问题
当我们使用TCP这种面向流的协议,网络传输像流水一样没有边界,可能会出现多次发送数据被合并成一个数据包,也有可能会一次发送数据被拆成多个数据包,
例如你发送两次数据,分别是hello 和world,那么接收端有可能会收到helloworld、he、lloworld
当然像UDP这种面向报文的协议不存在粘包拆包的问题
常见场景
下面是出现粘包和拆包的场景
- 粘包场景:连续发送多条小消息,底层合并发送
- 拆包场景:一条较大消息超过缓冲区,被分成多次接收
常见的触发条件:消息体不定长、没有包头标识、接收方没有按照边界读取数据
解决方案
下面是几种解决粘包拆包问题的方案
- 定长协议:每条消息的长度固定,例如每条128字节,优点是简单高效,缺点是浪费带宽难以应对变长消息
- 分隔符协议:使用特定的字符分割消息,如|等
- 添加消息头:常见消息格式是
[消息头] [消息体],接收端先读取消息头,从消息头中获取消息体大小
开发实践
在实际开发过程中,可以关注以下几点
- 大包处理:在处理大数据包的时候要注意内存限制、以及大数据包攻击
- 异常处理:粘包解码错误要及时关闭连接
- 加密通信:加密前后消息会发生变化,注意协议封装层次