MQTT 数据包结构
固定报头(Fixed Header)
每个 MQTT 数据包都由固定报头开始,结构如下:
Bit 7-4
Packet Type
Bit 3-0
Flags
Byte 2+
Remaining Length
报文类型(Packet Type)
| 类型 | 值 | 说明 |
|---|---|---|
| CONNECT | 1 | 客户端请求连接 |
| CONNACK | 2 | 连接确认 |
| PUBLISH | 3 | 发布消息 |
| PUBACK | 4 | QoS 1 确认 |
| PUBREC | 5 | QoS 2 收到(第一步) |
| PUBREL | 6 | QoS 2 释放(第二步) |
| PUBCOMP | 7 | QoS 2 完成(第三步) |
| SUBSCRIBE | 8 | 订阅请求 |
| SUBACK | 9 | 订阅确认 |
| UNSUBSCRIBE | 10 | 取消订阅 |
| UNSUBACK | 11 | 取消订阅确认 |
| PINGREQ | 12 | 心跳请求 |
| PINGRESP | 13 | 心跳响应 |
| DISCONNECT | 14 | 断开连接 |
剩余长度编码(Variable Byte Integer)
MQTT 使用可变长度编码表示剩余长度,最多 4 字节,可表示 0 到 268,435,455 的长度。
值范围
字节数
示例
0 - 127
1
0x00 - 0x7F
128 - 16,383
2
0x80 0x01 = 128
16,384 - 2,097,151
3
0x80 0x80 0x01 = 16384
2,097,152 - 268,435,455
4
0x80 0x80 0x80 0x01
📐 编码规则
- 每个字节的最高位(bit 7)是延续位:1 表示还有后续字节,0 表示最后一个字节
- 低 7 位(bit 0-6)存储数据
- 采用小端序(Little Endian)
PUBLISH 报文详解
PUBLISH 报文用于向主题发送消息,结构最为复杂:
Byte 1
Fixed Header
Type=3, DUP, QoS, RETAIN
Byte 2+
Remaining Length
Variable
Topic Length
2 bytes
Variable
Topic Name
QoS > 0
Packet ID
2 bytes
Variable
Payload
Byte 1 标志位详解
76543210
0
0
1
1
DUP
QoS
QoS
RETAIN
Packet Type = 3
Flags
构建示例:发送温度数据
假设我们要发布一条温度消息:
- Topic:
sensors/temperature - Payload:
{"temp": 25.5, "unit": "C"} - QoS: 1
- Packet ID: 100
- Retain: false
# 字节流构建过程
# Byte 1: Packet Type (3) + Flags (QoS=1, DUP=0, Retain=0)
# 0011 0010 = 0x32
byte1 = 0x32
# Topic: "sensors/temperature" (20 字节)
topic = b'sensors/temperature'
topic_length = len(topic) # 20 = 0x0014
# Packet Identifier (QoS 1 需要)
packet_id = 100 # 0x0064
# Payload
payload = b'{"temp": 25.5, "unit": "C"}'
# 计算 Remaining Length
# 2 (topic length) + 20 (topic) + 2 (packet id) + 26 (payload) = 50
remaining_length = 50 # 0x32
# 完整报文
packet = bytes([0x32, 0x32]) # Fixed header
packet += (topic_length).to_bytes(2, 'big') # Topic length
packet += topic # Topic
packet += (packet_id).to_bytes(2, 'big') # Packet ID
packet += payload # Payload
# 十六进制输出
print(packet.hex())
# 输出:3232001473656e736f72732f74656d706572617475726500647b2274656d70223a2032352e352c2022756e6974223a202243227d
CONNECT 报文结构
Byte 1
0x10
CONNECT
Byte 2+
Remaining Length
Variable
Protocol Name
Length + "MQTT"
1 Byte
Protocol Level
0x04=3.1.1
1 Byte
Connect Flags
U P W Q W C
2 Bytes
Keep Alive
Variable
Payload
ClientID, Will, User, Pass
Connect Flags 字节
76543210
0
U
P
W.R
W.Q
W.Q
W
C
Reserved
User Flag
Pass Flag
Will Retain
Will QoS
Will Flag
Clean Session