MQTT 数据包结构

固定报头(Fixed Header)

每个 MQTT 数据包都由固定报头开始,结构如下:

Bit 7-4 Packet Type
Bit 3-0 Flags
Byte 2+ Remaining Length

报文类型(Packet Type)

类型 说明
CONNECT1客户端请求连接
CONNACK2连接确认
PUBLISH3发布消息
PUBACK4QoS 1 确认
PUBREC5QoS 2 收到(第一步)
PUBREL6QoS 2 释放(第二步)
PUBCOMP7QoS 2 完成(第三步)
SUBSCRIBE8订阅请求
SUBACK9订阅确认
UNSUBSCRIBE10取消订阅
UNSUBACK11取消订阅确认
PINGREQ12心跳请求
PINGRESP13心跳响应
DISCONNECT14断开连接

剩余长度编码(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

构建示例:发送温度数据

假设我们要发布一条温度消息:

# 字节流构建过程

# 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