MQTT 系列:一、抓包浅析

Windows 平台下使用 Wireshark 抓包解析

Posted by Jerry Chen on May 18, 2020

本文将使用 Wireshark 对 MQTT 常用传输过程进行简要抓包分析。

准备的工具

工具名 描述 下载
Wireshark 抓包工具 自行百度
mosquitto-1.6.8-windows mqtt broker和client 官网下载
cmd windows控制台 系统自带

安装mosquitto-1.6.8-windows并将安装路径加入到PC环境变量;

开始抓包

  1. 打开Wireshark,双击选择捕获loopback适配器;

  2. 筛选mqtt协议,配置列加入Src Port和Dst Port显示;

启动代理服务器

打开cmd1(管理员模式)启动代理服务器:

1
mosquitto -v

注:此操作会占用前台,Wireshark无信息。

仅客户端1发布消息

打开cmd2发布消息:

1
2
# -q设定服务质量
mosquitto_pub -t test -m hello -q 0

Wireshark抓取的信息如下:

  1. Connect Command

    方向:由客户端(56703)发给服务器(1883);

    Raw:选中的是MQTT协议层数据;

    解析:

  2. Connect Ack

    方向:由服务器(1883)发给客户器(56703);

    Raw:选中的是MQTT协议层数据;

    解析:

  3. Publish Message [test]

    方向:由客户端(56703)发给服务器(1883);

    Raw:选中的是MQTT协议层数据;

    解析:

  4. 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服务器;
而发布消息的客户端发布完成后就会断开和服务器的连接。

  1. Subscribe Request (id=1) [test]

    方向:由客户端(56813)发给服务器(1883);

    Raw:选中的是MQTT协议层数据;

    解析:

  2. Subscribe Ack (id=1)

    方向:由服务器(1883)发给客户端(56813);

    Raw:选中的是MQTT协议层数据;

    解析:

  3. Ping Request

    方向:由客户端(56813)发给服务器(1883);

    Raw:选中的是MQTT协议层数据;

    解析:

  4. 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

总结:

  1. 必有回应(Ack、Req)的信息:连接命令(Connect)、订阅命令(Subscribe)、Ping命令;
  2. 必无回应的信息:断开命令(Disconnect);
  3. Pqos为1,Broker收到发布命令(Publish)将回复Ack;(一次来回确认)
  4. Pqos为2,Broker收到发布命令(Publish)将回复Received,Broker收到发布释放命令(Publish Release)将回复Complete;(两次来回确认)
  5. Sqos为1,sub收到发布命令(Publish)将回复Ack;(一次来回确认)
  6. Sqos为2,sub收到发布命令(Publish)将回复Received,sub收到发布释放命令(Publish Release)将回复Complete;(两次来回确认)

多个订阅的验证

验证:发布的消息是在broker上筛选分发的。

  1. 首先开两个客户端订阅相同主题test

  2. 接着用另一个客户端发布一条test主题的消息,并查看Wireshark上的信息

    可以看到broker对两个客户端都发布了消息。

  3. 关掉所有客户端。重新开两个客户端分别订阅主题test1、test

  4. 接着用另一个客户端发布一条test主题的消息,并查看Wireshark上的信息

    可以看到broker筛选后仅对一个客户端发布了消息。

Retained的验证

Retained消息是一种保留消息,pub时可选。

1
2
# -r 表示Retained消息
mosquitto_pub -t test -m hello -q 0 -r
  1. 先pub一个保留消息

  2. 开两个sub客户端订阅该主题

    可以看到新开的订阅该主题的客户端都收到了保留消息,说明这个消息存储在broker上;

  3. 关闭所有客户端,再次pub同主题的保留消息

  4. 开两个sub客户端订阅该主题

    可以看到同主题的保留消息被替换了成新的;

  5. 关闭所有客户端,pub不同主题的两个保留消息

  6. 开两个sub客户端分别订阅这两个主题

总结:每个主题Retain保留消息最多有一个。