本文将使用 Wireshark 对 MQTT 常用传输过程进行简要抓包分析。
准备的工具
工具名 | 描述 | 下载 |
---|---|---|
Wireshark | 抓包工具 | 自行百度 |
mosquitto-1.6.8-windows | mqtt broker和client | 官网下载 |
cmd | windows控制台 | 系统自带 |
安装mosquitto-1.6.8-windows并将安装路径加入到PC环境变量;
开始抓包
-
打开Wireshark,双击选择捕获loopback适配器;
-
筛选mqtt协议,配置列加入Src Port和Dst Port显示;
启动代理服务器
打开cmd1(管理员模式)启动代理服务器:
1
mosquitto -v
注:此操作会占用前台,Wireshark无信息。
仅客户端1发布消息
打开cmd2发布消息:
1
2
# -q设定服务质量
mosquitto_pub -t test -m hello -q 0
Wireshark抓取的信息如下:
-
Connect Command
方向:由客户端(56703)发给服务器(1883);
Raw:选中的是MQTT协议层数据;
解析:
-
Connect Ack
方向:由服务器(1883)发给客户器(56703);
Raw:选中的是MQTT协议层数据;
解析:
-
Publish Message [test]
方向:由客户端(56703)发给服务器(1883);
Raw:选中的是MQTT协议层数据;
解析:
-
Disconnect Req
方向:由客户端(56703)发给服务器(1883);
Raw:选中的是MQTT协议层数据;
解析:
发布QoS为0:
发布QoS为1:
发布QoS为2:
仅客户端2订阅主题
打开cmd3订阅主题:
1
2
# -q设定服务质量
mosquitto_sub -v -t test -q 0
Wireshark抓取的信息如下:
可以看到订阅主题的客户端会保持和代理服务器的连接,每过60s会主动ping服务器;
而发布消息的客户端发布完成后就会断开和服务器的连接。
-
Subscribe Request (id=1) [test]
方向:由客户端(56813)发给服务器(1883);
Raw:选中的是MQTT协议层数据;
解析:
-
Subscribe Ack (id=1)
方向:由服务器(1883)发给客户端(56813);
Raw:选中的是MQTT协议层数据;
解析:
-
Ping Request
方向:由客户端(56813)发给服务器(1883);
Raw:选中的是MQTT协议层数据;
解析:
-
Ping Response
方向:由服务器(1883)发给客户端(56813);
Raw:选中的是MQTT协议层数据;
解析:
直接杀掉客户端2进程,Wireshark不会有信息变化。在代理服务器(cmd1)上会显示一条Socket error:
订阅指令中QoS分别为0、1、2,但没有收到发布消息的情况下,均只有如下通信:
联合订阅和发布
以下Sqos为订阅的服务质量,Pqos为发布的服务质量。
Sqos和Pqos | 流程 |
---|---|
0,0 | ![]() |
0,1 | ![]() |
0,2 | ![]() |
1,0 | ![]() |
1,1 | ![]() |
1,2 | ![]() |
2,0 | ![]() |
2,1 | ![]() |
2,2 | ![]() |
总结:
- 必有回应(Ack、Req)的信息:连接命令(Connect)、订阅命令(Subscribe)、Ping命令;
- 必无回应的信息:断开命令(Disconnect);
- Pqos为1,Broker收到发布命令(Publish)将回复Ack;(一次来回确认)
- Pqos为2,Broker收到发布命令(Publish)将回复Received,Broker收到发布释放命令(Publish Release)将回复Complete;(两次来回确认)
- Sqos为1,sub收到发布命令(Publish)将回复Ack;(一次来回确认)
- Sqos为2,sub收到发布命令(Publish)将回复Received,sub收到发布释放命令(Publish Release)将回复Complete;(两次来回确认)
多个订阅的验证
验证:发布的消息是在broker上筛选分发的。
-
首先开两个客户端订阅相同主题test
-
接着用另一个客户端发布一条test主题的消息,并查看Wireshark上的信息
可以看到broker对两个客户端都发布了消息。
-
关掉所有客户端。重新开两个客户端分别订阅主题test1、test
-
接着用另一个客户端发布一条test主题的消息,并查看Wireshark上的信息
可以看到broker筛选后仅对一个客户端发布了消息。
Retained的验证
Retained消息是一种保留消息,pub时可选。
1
2
# -r 表示Retained消息
mosquitto_pub -t test -m hello -q 0 -r
-
先pub一个保留消息
-
开两个sub客户端订阅该主题
可以看到新开的订阅该主题的客户端都收到了保留消息,说明这个消息存储在broker上;
-
关闭所有客户端,再次pub同主题的保留消息
-
开两个sub客户端订阅该主题
可以看到同主题的保留消息被替换了成新的;
-
关闭所有客户端,pub不同主题的两个保留消息
-
开两个sub客户端分别订阅这两个主题
总结:每个主题Retain保留消息最多有一个。