TCP底层的粘包/拆包机制
其实很多熟悉TCP编程的小伙伴们都知道,无论是客户端还是服务端,当我们读取或者发送数据的时候,都需要去考虑TCP粘包和拆包的问题,本身TCP是一种流协议,所谓的流呢就是没有界限。TCP底层不了解上层程序的含义,所以只能根据TCP的缓冲区实际情况进行划分,所以存在上层一个业务数据包被TCP拆分成很多个包进行发送,可能大的数据包进行拆分成很多个小的数据包或者也有可能很多小的数据包被合并成一个大的数据包。
举个例子吧,我现在需要一个5个字节的数据包,结果给我分了7个数据包或者4个数据包,这就是所谓的拆包/粘包问题
分析TCP粘包、拆包问题产生的原因:
应用程序write写入的字节大小大于套接口发送缓冲区的大小
进行MSS大小的TCP分段、以太网帧的payload大于MTU进行IP分片等
那么对于粘包拆包问题的解决方案,根据业界主流协议,有以下三种方案:
1、消息定长,例如每个报文的大小固定为200个字节,假如报文只有179字节,那么剩余的21字节可以使用空格补位
2、在包尾部增加特殊字符进行分割,例如加回车等
3、消息分为消息头和消息体,在消息头包含表示消息总长度的字段,然后进行业务处理