怎么抓取 MQTT 协议数据包进行调试分析

举报
沈唁 发表于 2021/04/22 15:21:50 2021/04/22
【摘要】 在使用 MQTT 协议开发物联网相关项目或者作为消息队列使用时,可能会遇到一些问题:例如为什么订阅失效了?连接为什么断开了等等在 MQTT5.0 中存在 code 的属性,可以通过 code 来分析错误原因,而在 MQTT3.x 中没有 code 的属性,所以对于分析问题的话,只能借助抓包工具来分析了可以使用tcpdump来进行抓包,命令为:tcpdump -i en0 port 1883 ...

在使用 MQTT 协议开发物联网相关项目或者作为消息队列使用时,可能会遇到一些问题:

例如为什么订阅失效了?连接为什么断开了等等

在 MQTT5.0 中存在 code 的属性,可以通过 code 来分析错误原因,而在 MQTT3.x 中没有 code 的属性,所以对于分析问题的话,只能借助抓包工具来分析了

可以使用tcpdump来进行抓包,命令为:

tcpdump -i en0 port 1883 -w mqtt.pcap

这里需要注意修改网卡和对应的端口号,使用ifconfig查看网卡信息

lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
	options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
	inet 127.0.0.1 netmask 0xff000000
	inet6 ::1 prefixlen 128
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
	nd6 options=201<PERFORMNUD,DAD>

en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	options=400<CHANNEL_IO>
	ether f0:18:98:ae:9e:df
	inet6 fe80::1053:12ff:524e:c2a2%en0 prefixlen 64 secured scopeid 0x6
	inet 192.168.2.139 netmask 0xffffff00 broadcast 192.168.2.255
	nd6 options=201<PERFORMNUD,DAD>
	media: autoselect
	status: active

服务端 Broker 如果使用外网通讯则可以使用en0,而本地内网通讯的话可以使用lo0

端口1883就可以按照实际对应的端口设置,一般默认为1883,建议使用常规的端口:

1883 : MQTT, unencrypted
8883 : MQTT, encrypted
8884 : MQTT, encrypted, client certificate required
8887 : MQTT, encrypted, server certificate deliberately expired
8080 : MQTT over WebSockets, unencrypted
8081 : MQTT over WebSockets, encrypted

在执行tcpdump之后,看到如下输出,就可以发起请求了

$ tcpdump -i en0 port 1883 -w mqtt.pcap
tcpdump: listening on en0, link-type EN10MB (Ethernet), capture size 262144 bytes

出现问题的请求之后,使用CTRL+C结束,看到如下输出:

$ tcpdump -i en0 port 1883 -w mqtt.pcap
tcpdump: listening on en0, link-type EN10MB (Ethernet), capture size 262144 bytes
^C14 packets captured
70 packets received by filter
0 packets dropped by kernel

表示捕获到了 14 个数据包,就可以进行分析,分析可以使用 Wireshark,打开生成的 mqtt.pcap 文件

当然也可以直接使用 Wireshark 进行抓包分析

而 MQTT 5.0 协议中有 code 返回码,可以使用 simps/mqtt 中的 Simps\MQTT\Hex\ReasonCode 转为人类可读的信息,如:

use Simps\MQTT\Client;
use Simps\MQTT\Hex\ReasonCode;
use Simps\MQTT\Protocol\V5;
use Simps\MQTT\Config\ClientConfig;
use function Swoole\Coroutine\run;

run(function () {
    $config = (new ClientConfig())->setClientId(Client::genClientID())
        ->setKeepAlive(10)
        ->setDelay(3000) // 3s
        ->setMaxAttempts(5)
        ->setProtocolLevel(V5::MQTT_PROTOCOL_LEVEL_5_0)
        ->setSwooleConfig([
            'open_mqtt_protocol' => true,
            'package_max_length' => 2 * 1024 * 1024,
            'connect_timeout' => 5.0,
        ]);

    $client = new Client('broker.emqx.io', 1883, $config);
    $res = $client->connect();
    var_dump('Connect: ' . ReasonCode::getReasonPhrase($res['code']));
    $res = $client->publish('simps-mqtt/test', 'hello', 3);
    var_dump($res);
    var_dump('Publish: ' . ReasonCode::getReasonPhrase($res['code']));
});

connect 可以正常成功,返回Success,而 publish 因为发布了错误的 qos 等级3,所以被断开了链接,错误信息为:QoS not supported

具体的上下文还是要用过 Wireshark 来抓包进行分析的

关于 PHPMQTT

  • MQTT 协议解析 & 协程客户端
  • 适用于 PHP 的 MQTT 协议解析和协程客户端
  • 支持 MQTT 协议 3.1、3.1.1 和 5.0 版本,支持 QoS 0、QoS 1、QoS 2
  • 首个支持 MQTT v5.0 协议的 PHP library

文档:https://mqtt.simps.io
GitHub:https://github.com/simps/mqtt
Gitee:https://gitee.com/phpiot/mqtt

支持记得点个 Star~

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。