粘包与消息边界
TCP 是字节流,不保留应用层的消息边界:一次读取可能只拿到半个消息,也可能一次拿到一条半消息,这就是常说的「粘包」现象。它属于应用层要处理的问题,解决办法是定界——用长度前缀、固定长度或特殊分隔符,并在解析时同时处理半包与合并两种情况。
基本信息
| 本质 | TCP 是字节流,不维护消息边界 |
|---|---|
| 常见现象 | 一次读取对应多段报文,或多条消息被合并 |
| 解决办法 | 长度前缀、固定长度、特殊分隔符 |
| 抓包观察 | Follow Stream 查看两个方向的完整字节序列 |
| 关键认识 | 传输层不会替应用恢复边界 |
典型使用场景
- 自研协议频繁出现解析异常,怀疑边界处理有误
- 对接第三方系统时确认双方的定界规则是否一致
- 排查大数据包被拆分后解析失败的问题
- 为协议设计选择更稳妥的定界方案
- 定位偶发的「消息不完整」告警
判读要点
判读要点
同方向连续多段拼出完整消息 # 属于正常分段
一条报文包含多条应用消息 # 合并发送
定界字符出现但消息不完整 # 定界规则不一致
大消息被切成多个小段 # 受发送缓冲与路径限制现象与处理
| 现象 | 原因方向 | 处理 |
|---|---|---|
| 一次读到多条消息 | 发送端连续写入 | 按长度或分隔符切分 |
| 消息被拆成多次读到 | 缓冲与路径分段 | 实现半包拼接逻辑 |
| 边界错乱 | 对端写入与刷新策略 | 调整写入与刷新方式 |
| 数据完整但解析失败 | 定界规则不一致 | 核对双方协议实现 |
在抓包里看到的报文分段与应用读取到的边界没有直接对应关系,不能据报文分段推断应用层的读取结果。
修复必须在应用协议层完成,传输层本身不提供消息边界保证。
补充要点
- 用流视图把完整字节序列拿出来看,能判断定界字符是否真的出现
- 协议设计阶段优先选择长度前缀,解析实现更简单且边界清晰
- 对端不同实现的定界规则差异是高频问题,联调时先核对这一项
- 把异常会话的流视图导出,是给开发同学定位解析问题最直接的材料
把边界问题与丢包问题分开处理:前者数据完整但解析失败,后者数据根本缺失。