mqtt数据包举例
MQTT 数据包由 固定报头(Fixed Header)、可变报头(Variable Header) 和 有效载荷(Payload) 组成,以下通过常见的 PUBLISH
(发布)报文和 CONNECT
(连接)报文举例说明:
1. PUBLISH
报文(发布消息)
假设场景:向主题 test/topic
发送 QoS 1 的消息 hello
。
- 固定报头:
- 第 1 字节:
0x31
(二进制0011 0001
)- 高 4 位
0011
:表示PUBLISH
类型(编码值 3)。 - 低 4 位
0001
:表示 QoS 等级 1(第 3-4 位01
),无保留标志。
- 高 4 位
- 第 2 字节:
0x0D
(剩余长度13
,计算:主题长度 2 + 主题名 6 + 报文标识符 2 + 载荷 5 = 15?哦不,重新算:主题长度 2(0x0006
) + 主题名test/topic
6 字节 + 报文标识符 2(0x0001
) + 载荷hello
5 字节 → 总计2+6+2+5=15
,但剩余长度编码是0x0F
?等等,前面例子有误,重新计算:
固定报头 2 字节,可变报头部分:主题长度 2 + 主题 6 + 报文 ID 2 → 10 字节,载荷 5 → 总长度 2+10+5=17。剩余长度 17 用变长编码:17 < 128 → 0x11。所以固定报头第 2 字节是0x11
。
修正后:
固定报头:0x31 0x11
(第 1 字节0011 0001
,第 2 字节0x11
)。
- 第 1 字节:
- 可变报头:
- 主题长度:
0x00 0x06
(表示主题名长度为 6 字节)。 - 主题名:
0x74 0x65 0x73 0x74 0x2F 0x74 0x6F 0x70
(test/topic
的 ASCII 码)。 - 报文标识符:
0x00 0x01
(QoS ≥1 时必须有,用于消息确认)。
- 主题长度:
- 有效载荷:
- 消息内容:
0x68 0x65 0x6C 0x6C 0x6F
(hello
的 ASCII 码)。
- 消息内容:
完整数据包:
0x31 0x11 0x00 0x06 0x74 0x65 0x73 0x74 0x2F 0x74 0x6F 0x70 0x00 0x01 0x68 0x65 0x6C 0x6C 0x6F
。
2. CONNECT
报文(客户端连接)
假设场景:客户端请求连接到 MQTT 服务器,使用清洁会话(Clean Session = 1),心跳时间 60 秒。
- 固定报头:
- 第 1 字节:
0x10
(二进制0001 0000
),表示CONNECT
类型(编码值 1)。 - 第 2 字节:剩余长度,计算可变报头 + 载荷长度。
- 协议名
MQTT
长度 4 + 协议版本 1 + 连接标志 1 + 心跳 2 → 总计 8 字节。 - 剩余长度
8
编码为0x08
,固定报头为0x10 0x08
。
- 协议名
- 第 1 字节:
- 可变报头:
- 协议名:
0x00 0x04 0x4D 0x51 0x54 0x54
(MQTT
的 ASCII 码,长度 4)。 - 协议版本:
0x04
(MQTT 3.1.1 版本)。 - 连接标志:
0x02
(二进制0000 0010
,表示清洁会话1
,无遗嘱消息,密码和用户名不使用)。 - 心跳时间:
0x00 0x3C
(60 秒)。
- 协议名:
- 有效载荷(可选):
- 客户端 ID:假设为
0x63 0x6C 0x69 0x65 0x6E 0x74 0x5F 0x31
(client_1
的 ASCII 码)。
- 客户端 ID:假设为
完整数据包:
0x10 0x08 0x00 0x04 0x4D 0x51 0x54 0x54 0x04 0x02 0x00 0x3C 0x63 0x6C 0x69 0x65 0x6E 0x74 0x5F 0x31
。
通过以上示例可以看出,MQTT 数据包通过固定报头标识类型和基本属性,可变报头携带主题、标识符等上下文信息,载荷包含实际传输的数据。实际应用中,数据包结构会根据具体报文类型(如 SUBSCRIBE
、PINGREQ
等)灵活调整。