1. 粘包的原因
1.1 应用层的问题
- 接收方ByteBuffer设置太大(netty默认1024字节),导致将socket缓冲区中多个包放进了ByteBuffer中。
1.2 TCP的问题
- 接收方的滑动窗口足够大,而且来不及处理,导致接收方的socket缓冲区缓冲了多个报文,从而导致了粘包
- Nagle算法:发送方会将小的报文合并在一起发送给接收方,会造成粘包。
2. 半包的原因
2.1 应用层的问题
- 接收方ByteBuf设置过小,导致只能从socket缓冲区中读取半个数据包到ByteBuf中去
2.2 TCP的问题
- 接收方的剩余窗口过小,则发送方只能选择发送半个包给接收方
- MSS限制:当数据包超过MSS限制后,会自动将数据切分发送,可能会造成半包。
3. 问题总结
- TCP是流式协议,消息无边界。
4. 粘包解决方案
4.1 短链接
- 发一个包建立一个连接。
- 连接建立到连接断开就是消息的边界。
- 效率比较低
4.2 每个消息采取固定长度
- 短的切断,长的填充
- 浪费空间
4.3 每个消息采用特殊起始和结束边界
- 如使用\n作为结束标志
- 缺点是需要转义
4.4 记录消息的长度
- 每条消息分为head和body,head中包含body的长度
- 一般head格式固定