串口、TCP 等流式传输 会出现粘包、拆包、等传输错误;需要用状态机解析字节流,输出完整消息帧

串口、TCP 这类流式接口没有消息边界,读取字节和完整消息不存在一一对应:一次读取可能只拿到部分帧数据,剩余部分在下一次读取,还可能夹杂下一帧开头,也就是常见的粘包、拆包问题。

解决方案采用逐字节驱动的组帧状态机:先处于等待帧头状态,匹配到帧头后读取长度字段,再按长度接收负载数据。半包时保存状态等待后续数据;数据收齐后执行帧完整性校验。

容易踩坑:负载数据碰巧出现帧头字节、传输损坏长度字段,都会造成帧头误识别,状态机按错误长度接收,破坏后续报文。可在帧头 + 长度后增加头部 CRC32 校验:头部校验通过才接收负载;负载数据再独立做 CRC 校验。提前拦截头部误匹配,避免污染后续帧。

校验成功向上交付完整帧;校验失败、长度越界、超时则丢弃残帧,回到搜寻帧头状态。缓存残留字节继续解析下一帧。依靠状态机持续处理字节流并容错,即可把无边界字节流可靠解析为完整消息。

图 1 组帧状态机将连续字节流解析为完整消息帧