一、拆包,粘包问题产生原因
粘包和拆包是 TCP 协议在数据传输中常见的问题,因为 TCP 是基于字节流传输的协议,不会维护消息或数据包的边界。
拆包:待发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包。待发送数据大于MSS(TCP报文长度 - TCP头部长度 > MSS最大报文长度),TCP在传输前将根据MSS大小进行拆包分段发送。
粘包:待发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据包合并为一次发送,将发生粘包(Nagle算法)。
粘包拆包带来的问题:数据边界不明确可会导致出现问题的概率变大(解析时间,重传机制)。
二、拆包,粘包问题解决方案
- 包头标识协议:在数据包前加上固定长度的包头,包头中包含数据包的长度信息,接收端根据包头信息来识别数据包边界。
- 固定长度包协议:每个数据包都具有固定的长度,接收端按照固定长度读取数据。
- 分隔符协议:使用特定的分隔符(例如换行符、特殊字符)来标识数据包的边界,接收端根据分隔符来拆分数据包。
三、为什么UDP没有粘包?
- UDP有消息保护边界,从UDP的帧结构可以看出,在UDP首部采用了 16位UDP长度字段来指示UDP数据报文的长度,因此在应用层能很好的将不同的数据报文区分开,从而避免粘包和拆包的问题。
- UDP发送的时候,不经过Nagle算法优化,不会将多个小包合并一次发送出去。