三段结构
固定头第一个字节同时携带报文类型与标志位,紧接着是剩余长度字段;可变头的内容随报文类型变化,例如发布报文里是主题名与报文标识符;载荷则承载应用数据,订阅报文里的载荷是主题过滤器列表。所有报文的长度都通过剩余长度字段界定,因此解析的起点就是它。
主要控制包
| 控制包 | 方向 | 作用 |
|---|---|---|
| 连接与确认 | 客户端到服务端 / 返回 | 协商协议版本、会话、保活与身份 |
| 发布 | 双向 | 承载主题与业务载荷,标志位含重发、QoS 与保留 |
| 发布确认系列 | 双向 | QoS 1 用一次确认,QoS 2 用接收、释放、完成三步 |
| 订阅与订阅确认 | 客户端到服务端 / 返回 | 提交主题过滤器与请求等级,返回授权等级 |
| 退订与确认 | 客户端到服务端 / 返回 | 移除订阅关系 |
| 心跳请求与响应 | 双向 | 在无其他报文时维持连接活性 |
| 断开 | 客户端到服务端 | 正常断开,不触发遗嘱消息 |
| 认证(5.0) | 双向 | 增强认证的挑战应答交换 |
固定头解析要点
固定头解析要点
# 第 1 字节:高 4 位为报文类型,低 4 位为类型相关标志
# 剩余长度:每字节低 7 位有效,最高位为延续标志,最多 4 字节
# 长度 127 编码为单字节 0x7F
# 长度 128 编码为 0x80 0x01,共两字节
# 理论最大剩余长度约 256 MB,但服务端通常另设上限
# 发布报文的标志位含重发、QoS 等级与保留标记典型使用场景
- 协议排查:抓包后按固定头逐字段核对,判断是客户端还是服务端行为异常
- 自研轻量客户端:在资源受限设备上只实现所需的少数控制包
- 压测与分析:根据报文大小与数量估算带宽与内存占用
- 网关解析:把非 MQTT 数据映射为主题与载荷时需要理解报文边界
发布报文的标志位里包含重发标志,接收方据此就能识别出这是重发的消息,这也是实现去重时最直接的线索之一。
自己实现解析时如果不严格校验剩余长度与报文边界,畸形报文可能引发越界读取,属于典型的安全隐患。