MQTT的协议有必要的话也是可以抓包看一下其交互过程,加深理解其原理
1. 报文
固定报文格式:类型+标志位
Bit | 7 - 4 | 3 - 0 |
byte 1 | MQTT控制报文的类型 | 用于指定控制报文类型的标志位 |
byte 2… | 剩余长度 |
1.1 MQTT控制报文的类型:
报文类型 | 字段值 | 数据方向 | 描述 |
保留 | 0 | 禁用 | 保留 |
CONNECT | 1 | Client —> Server | 客户端连接到服务器 |
CONNACK | 2 | Server —> Client | 连接确认 |
PUBLISH | 3 | Client <–> Server | 发布消息 |
PUBACK | 4 | Client <–> Server | 发布确认 |
PUBREC | 5 | Client <–> Server | 消息已接收(QoS2第一阶段) |
PUBREL | 6 | Client <–> Server | 消息释放(QoS2第二阶段) |
PUBCOMP | 7 | Client <–> Server | 发布结束(QoS2第三阶段) |
SUBSCRIBE | 8 | Client —> Server | 客户端订阅请求 |
SUBACK | 9 | Server —> Client | 服务端订阅确认 |
UNSUBACRIBE | 10 | Client —> Server | 客户端取消订阅 |
UNSUBACK | 11 | Server —> Client | 服务端取消订阅确认 |
PINGREQ | 12 | Client —> Server | 客户端发送心跳 |
PINGRESP | 13 | Server —> Client | 服务端回复心跳 |
DISCONNECT | 14 | Client —> Server | 客户端断开连接请求 |
保留 | 15 | 禁用 | 保留 |
1.2 控制报文类型的标志位:
控制报文 | 固定报头标志 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
CONNECT | Reserved | 0 | 0 | 0 | 0 |
CONNACK | Reserved | 0 | 0 | 0 | 0 |
PUBLISH | Used in MQTT 3.1.1 | DUP | QoS | QoS | RETAIN |
PUBACK | Reserved | 0 | 0 | 0 | 0 |
PUBREC | Reserved | 0 | 0 | 0 | 0 |
PUBREL | Reserved | 0 | 0 | 1 | 0 |
PUBCOMP | Reserved | 0 | 0 | 0 | 0 |
SUBSCRIBE | Reserved | 0 | 0 | 1 | 0 |
SUBACK | Reserved | 0 | 0 | 0 | 0 |
UNSUBSCRIBE | Reserved | 0 | 0 | 1 | 0 |
UNSUBACK | Reserved | 0 | 0 | 0 | 0 |
PINGREQ | Reserved | 0 | 0 | 0 | 0 |
PINGRESP | Reserved | 0 | 0 | 0 | 0 |
DISCONNECT | Reserved | 0 | 0 | 0 | 0 |
- 看上面的消息可以观察到PUB的QOS标志直接位于“控制报文类型的标志位”里面,而CONNECT和SUB的QOS标记却不在头部。
- 抓包可以发现CONNECT和SUB的QOS标记位于后续的数据里面
- PING心跳没有QOS设置
2. 连接
报文类型 | 数据方向 | 描述 |
0x10 | client->broker | MQTT CONNECT |
0x20 | broker->client | MQTT CONNACK |
值 | 返回码响应 | 描述 |
0 | 0x00连接已接受 | 连接已被服务端接受 |
1 | 0x01连接已拒绝,不支持的协议版本 | 服务端不支持客户端请求的MQTT协议级别 |
2 | 0x02连接已拒绝,不合格的客户端标识符 | 客户端标识符是正确的UTF-8编码,但服务端不允许使用 |
3 | 0x03连接已拒绝,服务端不可用 | 网络连接已建立,但MQTT服务不可用 |
4 | 0x04连接已拒绝,无效的用户名或密码 | 用户名或密码的数据格式无效 |
5 | 0x05连接已拒绝,未授权 | 客户端未被授权连接到此服务器 |
6-255 | 保留 | 如果认为上表中的所有连接返回码都不太合适,那么服务端必须 |
3. 心跳
一个心跳有三个包
报文类型 | 数据方向 | 描述 |
0xc0 | client->broker | MQTT PINGREQ |
0xd0 | broker->client | MQTT PINGRESP |
client->broker | TCP ACK |
4. 发布
4.1 QOS=0时
报文类型 | 数据方向 | 描述 |
0x30 | client->broker | MQTT PUBLISH |
broker->client | TCP ACK |
4.2 QOS=1时
报文类型 | 数据方向 | 描述 |
0x32 | client->broker | MQTT PUBLISH |
0x40 | broker->client | MQTT PUBACK |
4.3 QOS=2时
报文类型 | 数据方向 | 描述 |
0x34 | client->broker | MQTT PUBLISH |
0x50 | broker->client | MQTT PUBREC |
0x62 | client->broker | MQTT PUBREL |
0x70 | broker->client | TCP PUBCOMP |
5. 抓包
【MQTT】使用Wireshark分析MQTT协议:
- 更新到最新的版本可以可以直接解析mqtt的报文(必须是1883端口的才可以解析)
- 但是还是没办法解析mqtts的报文,会显示BitTorrent(比特流)
- 可以用端口过滤
(tcp.dstport == 1883) || (tcp.srcport == 1883)
http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html
https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html