mqtt报文逐条解析

这篇具有很好参考价值的文章主要介绍了mqtt报文逐条解析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、背景说明

本文还是需要参考mqtt的中文协议文档,所有的变种都是基于这个的。

本文有看不懂的地方需要参考一点我之前的文章:

STM32使用esp01s上云,MQTT.fx调试述
阿里云使用记录

相信看完一定对mqtt协议有更深入的了解!

2、mqtt报文解析

之前的文章已经提到过一些mqtt的格式,这里不再赘述,需要的可以直接翻看之前的文章了解查看,目前mqtt总的报文如下:
mqtt报文逐条解析

下面分别说明这些报文:

connect是一号报文,需要第一个发送,包括一些鉴权信息(用户名,密码等),方向是从客户端到服务器,二号报文是服务器回复客户端的,回复客户端连接正确与否,方向是从服务器到客户端。
mqtt报文逐条解析

之后关注一下ping相关的报文,PING报文,是用于保活的,方向从客户端到服务器,定期发送保活,同样服务器也要定期回复客户端,就是PINGRSP报文,这样就能建立一个长期的连接了。最后的一个是断开连接,断开连接由客户端发起,服务器无需回应报文。
mqtt报文逐条解析
下面关注一下订阅相关的报文,分为订阅和取消订阅,订阅和取消订阅都是由客户端发起的,同时服务器需要有相对应的回应。
mqtt报文逐条解析
下面是正式的数据通信部分的报文了,数据通信这里就是发布消息的报文,这个过程是双向的,两边都可以实现这个报文,可以看下面的箭头描述,同时需要注意目前绝大多是的mqtt服务器都不支持质量等级为QoS2的通信,所以就都不用关下面的几种消息发布了。
mqtt报文逐条解析
以上就是所有关于mqtt的报文的拆分和解析了,下面来具体看这些报文是如何实现的。

3、剩余长度计算

基本上每种报文都需要可变长度,所以每次发消息就都需要计算可变长度(12,13,14号报文没有可变报头和负载,可变长度直接就是00,如下图所示)。
mqtt报文逐条解析
剩余长度的的计算值可以表示为可变报头+负载,最少占用一个字节,最多占用4个字节,这个在前面的文章里面也提到过了,这里在说一点细节相关的东西吧:
mqtt报文逐条解析
看上面的规则,这里比如剩余长度是32,那就是:0x20
mqtt报文逐条解析
下面假如一个长度超过127就是200吧,需要第二个字节来帮忙表示,那就是200-128=72,这里是0x48,
mqtt报文逐条解析
但是还需要表示进位,就是第一个位来表示进位,那就是:0xc8
mqtt报文逐条解析
所以这个里面最终的计算结果为:0xc8 0x01

下面再来看一个更大的数字,就以20000为例子来查看一下吧,两个字节最大表示16383,所以需要三个字节才能表示的清楚这个数字:20000 - 156*128=32所以最下面的一个是32,32再用进位来表示一下:0xA0
mqtt报文逐条解析
之后就是156了,很明显,156也需要进位,那就是156-128=28,进位表示为:0x9c
mqtt报文逐条解析
所以这样最终的结果就是 0xa0 0x9c 0x01,相信通过这个例子能更加看清这个剩余长度的计算方法了。

4、构建connect报文

需要注意就是:在一个网络连接上,客户端只能发送一次 CONNECT 报文。服务端必须将客户端发送的第二个 CONNECT报文当作协议违规处理并断开客户端的连接,所以这一次的连接建立还是很重要的。

首先是固定报头:0x10(直接一眼看出来就是),下面是剩余长度,剩余长度是要等于可变报头的长度加上有效载荷才行,所以这里暂时不知道剩余长度,等确定了内容就知道了。
mqtt报文逐条解析
这里connect报文的可变报头总共是10个字节,分别为:协议名(Protocol Name),协议级别(Protocol
Level),连接标志(Connect Flags)和保持连接(Keep Alive)。

协议名如下所示,直接一眼看出:00 04 4D 51 54 54
mqtt报文逐条解析
mqtt报文逐条解析
下面是协议级别:04
mqtt报文逐条解析
连接标识,这里除了用户名和密码(可以以游客的身份登陆),其他的都可以不要,最后加上一个清理会话,最终的结果就是C2
mqtt报文逐条解析

保持连接:这里是心跳保活的时间,这里选一个100秒吧,就是64
mqtt报文逐条解析
这样就确定了可变报头的内容:00 04 4D 51 54 54 04 C2 00 64,一个是个字节的长度。

之后是有效载荷的部分了,有效载荷,这里根据平台有不同的选择,这里用的阿里云的平台,相关说明如下所示,注意看这个路径位置:
mqtt报文逐条解析
这里我们最终拼接的内容如下所示:
mqtt报文逐条解析
当然也可以偷懒,直接去官方产品页面查看,这里我的mqtt连接参数如下所示,这里的连接参数为mqtt的连接参数
mqtt报文逐条解析
复制下来如下所示:
mqtt报文逐条解析
但是发现好像连接端不是需要这个部分的内容,根据官方文档资料,说明的connect的参数应该是这样的:
mqtt报文逐条解析

这个内容可以在MQTT的连接参数中查看到数据,最终形成的连接内容应该是如下所示:

gukv3BQLi1G.camera1|securemode=2,signmethod=hmacsha256,timestamp=1663601981496|
camera1&gukv3BQLi1G
2b4af23ae4840f34aad897e743b776d847e2aa6d966bef19e08ea2e2e2b74384

这里也是根据官方协议来看的,官方协议在CONNECT的报文的可变内容中描述如下:
mqtt报文逐条解析

同时也对每个部分的内容做了要求,简单来说就是长度加上内容
mqtt报文逐条解析

下面来具体的对上述部分进行封装

首先是mqttClientId,转成16进制再发送:00 4f(长度79)
mqtt报文逐条解析
之后是:mqttUsername,转成16进制再发送:00 13(长度19)
mqtt报文逐条解析
最后是:mqttPassword,转成16进制再发送:00 40(长度64)
mqtt报文逐条解析
所以最后的内容断数据为:(每条的长度+每条的内容)

00 4F 67 75 6B 76 33 42 51 4C 69 31 47 2E 63 61 6D 65 72 61 31 7C 73 65 63 75 72 65 6D 6F 64 65 3D 32 2C 73 69 67 6E 6D 65 74 68 6F 64 3D 68 6D 61 63 73 68 61 32 35 36 2C 74 69 6D 65 73 74 61 6D 70 3D 31 36 36 33 36 30 31 39 38 31 34 39 36 7C

00 13 63 61 6D 65 72 61 31 26 67 75 6B 76 33 42 51 4C 69 31 47

00 40 32 62 34 61 66 32 33 61 65 34 38 34 30 66 33 34 61 61 64 38 39 37 65 37 34 33 62 37 37 36 64 38 34 37 65 32 61 61 36 64 39 36 36 62 65 66 31 39 65 30 38 65 61 32 65 32 65 32 62 37 34 33 38 34

总的可变长度就是10+79+19+64+6=178,表示为 0xB2 0x01
mqtt报文逐条解析

因此最终发送的内容为:

10 B2 01 00 04 4D 51 54 54 04 C2 00 64 00 4F 67 75 6B 76 33 42 51 4C 69 31 47 2E 63 61 6D 65 72 61 31 7C 73 65 63 75 72 65 6D 6F 64 65 3D 32 2C 73 69 67 6E 6D 65 74 68 6F 64 3D 68 6D 61 63 73 68 61 32 35 36 2C 74 69 6D 65 73 74 61 6D 70 3D 31 36 36 33 36 30 31 39 38 31 34 39 36 7C 00 13 63 61 6D 65 72 61 31 26 67 75 6B 76 33 42 51 4C 69 31 47 00 40 32 62 34 61 66 32 33 61 65 34 38 34 30 66 33 34 61 61 64 38 39 37 65 37 34 33 62 37 37 36 64 38 34 37 65 32 61 61 36 64 39 36 36 62 65 66 31 39 65 30 38 65 61 32 65 32 65 32 62 37 34 33 38 34

数据发送如下所示:
mqtt报文逐条解析
可以看到返回的消息如下所示:
mqtt报文逐条解析

5、CONNACK报文示例

可以看到上面发送完(这里一定是建立在发送了正确的CONNECK报文的基础上)CONNECK报文之后,服务器返回了 20 02 00 00的四个数据,下面来查看下这四个数据表示的含义:
mqtt报文逐条解析

首先是CONNACK报文的连接确认:20 02(这是固定报头)
mqtt报文逐条解析
可变报头的描述如下所示,可以看到第一个字节也是00
mqtt报文逐条解析
第二个是连接返回码,关于连接返回码的表示如下所示:
mqtt报文逐条解析
从上表中可以看出,连接返回码为00 正是表示服务器接受连接的意思,所以这个就很正常了,表示连接正确建立。

同时去阿里云的物联网平台也可以看到设备连接上了:
mqtt报文逐条解析

6、心跳PING报文

这里就一个报头,直接从表中读数据就行,应该就是C0 00
mqtt报文逐条解析
发送可以看到数据的返回:
mqtt报文逐条解析
同时刚才的过程也可以用wireshark工具来抓包看看是什么数据:
mqtt报文逐条解析
上面的地方设置规则为mqtt即可,相关的报文详解如下所示:
mqtt报文逐条解析

7、心跳回应PINGRESP报文

服务端发送 PINGRESP 报文响应客户端的 PINGREQ 报文。 表示服务端还活着,相关描述如下所示:(这个也是只有固定报头一项参数可以用
mqtt报文逐条解析
根据上面图表的描述,可以知道,服务器正确返回的参数应该是:D0 00
mqtt报文逐条解析

8、断开连接DISCONNECT报文

DISCONNECT 报文是客户端发给服务端的最后一个控制报文。表示客户端正常断开连接。下面是相关的描述参数,这个同样是只有一项参数固定报头。
mqtt报文逐条解析
根据上面图表的描述,可以知道,服务器正确返回的参数应该是:E0 00
mqtt报文逐条解析
发送完成之后就可以看到服务器主动断开了连接,说明这个报文还是很有用的!

9、订阅请求SUBSCRIBE

查文档可以看到固定报头是 82 xx(剩余长度暂不清楚)
mqtt报文逐条解析
下面是可变报头,这里的可变报头是指报文标识符的部分:
mqtt报文逐条解析
上面是00 10为报文标识符等于10的可变报头,那我们可以自己选的,就是说这个标识符只是用来区别不同报文的,那这里选一个 00 01

这里我们去阿里云找一个主题来订阅下看看

mqtt报文逐条解析
替换设备名称后结果如下所示:

/sys/gukv3BQLi1G/camera1/thing/service/property/set
转成16进制 下面长度是53个字节

2F 73 79 73 2F 67 75 6B 76 33 42 51 4C 69 31 47 2F 63 61 6D 65 72 61 31 2F 74 68 69 6E 67 2F 73 65 72 76 69 63 65 2F 70 72 6F 70 65 72 74 79 2F 73 65 74 

所以根据这个长度拼接一下:

00 33 2F 73 79 73 2F 67 75 6B 76 33 42 51 4C 69 31 47 2F 63 61 6D 65 72 61 31 2F 74 68 69 6E 67 2F 73 65 72 76 69 63 65 2F 70 72 6F 70 65 72 74 79 2F 73 65 74

但是这还不够,订阅还需要一个质量等级,但是这个质量等级这里不需要算到长度里面
mqtt报文逐条解析
阿里云这里默认都是0,所以直接用0就行了:
mqtt报文逐条解析
这样的话现在的内容就是这样了:

00 33 2F 73 79 73 2F 67 75 6B 76 33 42 51 4C 69 31 47 2F 63 61 6D 65 72 61 31 2F 74 68 69 6E 67 2F 73 65 72 76 69 63 65 2F 70 72 6F 70 65 72 74 79 2F 73 65 74 00

再次对总长度进行拼接(之前不清楚的剩余长度现在就可以计算出来了):

82 38
00 01
00 33 2F 73 79 73 2F 67 75 6B 76 33 42 51 4C 69 31 47 2F 63 61 6D 65 72 61 31 2F 74 68 69 6E 67 2F 73 65 72 76 69 63 65 2F 70 72 6F 70 65 72 74 79 2F 73 65 74 00

最上面一行是报文标识符和剩余长度,第二行是报文标识符,第三行是订阅的主题长度和主题

发送,可以看到阿里云回复如下所示:
mqtt报文逐条解析
同时可以在阿里云的后台看到消息如下所示:
mqtt报文逐条解析

10、订阅请求确认SUBACK

上面已经成功订阅了主题,并收到了服务器的消息回复,这里我们直接分析一下服务器回复的消息就行了:

回复了 90 03 00 01 01

查文档可以知道 90 03为固定报头还有剩余长度
mqtt报文逐条解析
00 01位可变报头,这里也可以直接认为是报文标识符,我们之前设置的是 00 01,那他回复的就是 00 01
mqtt报文逐条解析
最后一个01 是最大支持的服务质量等级 01表示最大为服务等级1
mqtt报文逐条解析

11、取消订阅UNSUBSCRIBE

查文档可以看到取消订阅的报头为:A2 XX(剩余长度暂不清楚)
mqtt报文逐条解析
之后就是标识符还有有效载荷的部分了,类似这种取消的都比较简单,这里标识符我们换一个 00 02(上面用过00 01了)
mqtt报文逐条解析
另外需要注意取消订阅不需要服务质量等级,剩下的直接抄:(上面订阅了什么这里就取消什么,因此内容字段直接抄
mqtt报文逐条解析
下面来发送进行一下测试:
mqtt报文逐条解析

阿里云后台的信息如下所示:
mqtt报文逐条解析
上述说明成功实现了订阅和取消订阅

12、取消订阅确认UNSUBACK

上面我们已经拿到了取消订阅的返回,其实就是UNSUBACK的报文信息,下面来详细分析一下这个部分的报文:
B0 02 00 02

其实还是看文档,因为这个服务器一定是按照文档来写的:
mqtt报文逐条解析
从图中可以知道 B0 02是固定报头和剩余长度,00 02是我们刚才取消订阅的报文标识符
mqtt报文逐条解析
OK,解析完成!

13、发布消息PUBLISH(服务质量等级为0)

这里还是先看一下头:
mqtt报文逐条解析
这里其他部分都不要,服务质量等级选0,因此就是 30 xx(剩余长度不清楚),下面可变报头的部分,可以看到,这里可变报头是需要包含主题的
mqtt报文逐条解析
这里我们用一个属性上报来做实验:
mqtt报文逐条解析
因此就是:(前面是长度,后面是topic)

00 32 2F 73 79 73 2F 67 75 6B 76 33 42 51 4C 69 31 47 2F 63 61 6D 65 72 61 31 2F 74 68 69 6E 67 2F 65 76 65 6E 74 2F 70 72 6F 70 65 72 74 79 2F 70 6F 73 74 

下面是报文标识符,这里因为我们用Qos = 0,所以就没有报文标识符
mqtt报文逐条解析
下面是发送内容:(内容本来是可以随便发的,但是阿里云有要求,不能随便发)

这里我们要用之前的物模型:(这里我用的我之前测试的一个物模型吧)
mqtt报文逐条解析
在阿里云平台导出物模型就是这样的:
mqtt报文逐条解析
这里我们要设置他的属性就需要:(这里内容为什么是这个可以看我之前的文章,其实就是用set属性发一下一个参数看他发送的是什么就可以反推内容了

{"method":"thing.service.property.set","id":"1993907181","params":{"test111":0},"version":"1.0.0"} 

因此我们来构造一下我们的报文:(发布的内容如下,下面我转成了16进制的内容
mqtt报文逐条解析
内容:

发布消息:
/sys/gukv3BQLi1G/camera1/thing/event/property/post 50
{"method":"thing.service.property.set","id":"1993907181","params":{"test111":0},"version":"1.0.0"} 98
30 96 01
00 32 2F 73 79 73 2F 67 75 6B 76 33 42 51 4C 69 31 47 2F 63 61 6D 65 72 61 31 2F 74 68 69 6E 67 2F 65 76 65 6E 74 2F 70 72 6F 70 65 72 74 79 2F 70 6F 73 74 
7B 22 6D 65 74 68 6F 64 22 3A 22 74 68 69 6E 67 2E 73 65 72 76 69 63 65 2E 70 72 6F 70 65 72 74 79 2E 73 65 74 22 2C 22 69 64 22 3A 22 31 39 39 33 39 30 37 31 38 31 22 2C 22 70 61 72 61 6D 73 22 3A 7B 22 74 65 73 74 31 31 31 22 3A 30 7D 2C 22 76 65 72 73 69 6F 6E 22 3A 22 31 2E 30 2E 30 22 7D 

下面用我们在之前构建好的客户端给他发送出去,然后看一下回来接收的内容:
mqtt报文逐条解析
这里为了证实我们成功发布了消息,可以在阿里云的日志这里看到我们发布的消息:
mqtt报文逐条解析
同时在物模型这里可以看到我们的物模型发生了变化:
mqtt报文逐条解析

14、发布确认PUBACK

这里因为我们上面采用的是QoS0级别的消息发送,所以应该是没有内容回复的,因为这个级别不需要知道另一方有没有收到消息,如果不是QoS0级别的才要看有没有确认:

同样的也可以看到这个的发布确认发布头如下所示:为 40 02
mqtt报文逐条解析
那他就是固定长度为为40 然后长度为02,然后02是报文标识符:(报文标识符自然要和订阅的报文是相关的!
mqtt报文逐条解析
这里没有有效载荷。

15、其他报文

其他报文都是和Qos2等级相关的,因此这里就不讨论了!
mqtt报文逐条解析

16、本地测试方法

本地可以自己搭建服务器进行测试,这里我推荐mosquitto,也有人推荐使用emqx,但是我觉得使用emqx有点蛮烦,如果是做开发可能更方便一点吧,这里直接介绍使用mosquitto的方案吧!

下载链接如下所示:

https://mosquitto.org/download/

mqtt报文逐条解析
可以根据需求下载,这里我用的是win版本的,比较方便,下面是一些建议设置:
mqtt报文逐条解析
之后设置我们服务器的启动为手动:
mqtt报文逐条解析
mqtt报文逐条解析
之后找到下载安装的路径,点击启动即可
mqtt报文逐条解析
之后就会出现这样一个黑框,不要关闭它,我们的服务器就一直都在:
mqtt报文逐条解析
新建一个其他的窗口来订阅和发布主题:
mqtt报文逐条解析

常见的命令如下:

运行服务器:

mosquitto -v

订阅主题:

mosquitto_sub  -v -t mytopic

发布主题:

mosquitto_pub  -t mytopic -m "xxxxxxxx"

当然他的功能远不止这么点,这些只是示例。文章来源地址https://www.toymoban.com/news/detail-406414.html

到了这里,关于mqtt报文逐条解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 本文将从云原生的概念、背景知识、Kubernetes架构及核心组件、应用场景、案例研究等方面深入剖析云原生课程的相关知识点

    作者:禅与计算机程序设计艺术 2020年,技术快速发展,云计算火爆。云原生领域也随之蓬勃发展。云原生已经成为大势所趋,大量企业都在逐渐转型云原生应用架构。国内外云服务厂商也纷纷推出基于Kubernetes的服务平台,而Kubernetes又是云原生开源技术体系的一部分。为了帮

    2024年02月07日
    浏览(64)
  • MQTT 客户端 MQTT.fx 使用说明

    官网:https://softblade.de/en/download-2/ 说明:最后的免费版本是 MQTT.fx 1.7.1,官网已经没有免费的版本 下载 MQTT.fx 1.7.1 https://nowjava.com/download/44364 【需关注其公众号才能下载】 一路 Next 即可 安装好后,直接启动MQTT.fx 点击第 1 步中界面设置按键(齿轮图标)打开新窗口创建一个

    2024年02月03日
    浏览(42)
  • RabbitMQ MQTT集群方案官方说明

    RabbitMQ MQTT 官方网说明 官方地址: https://www.rabbitmq.com/mqtt.html 从3.8开始,该MQTT插件要求存在一定数量的群集节点。这意味着三分之二,五分之三,依此类推。 该插件也可以在单个节点上使用,但不支持两个节点的集群。 如果大多数群集节点都关闭,则其余群集节点将无法接受

    2024年02月09日
    浏览(39)
  • 视频安防监控EasyCVR平台海康大华设备国标GB28181告警布防的报文说明

    TSINGSEE青犀视频监控综合管理平台EasyCVR基于云边端协同,可支持海量视频的轻量化接入与汇聚管理。平台既具备传统安防视频监控的能力,比如:视频监控直播、云端录像、云存储、录像检索与回看、告警上报、平台级联、云台控制、语音对讲等,也能接入AI智能分析的能力

    2024年02月14日
    浏览(46)
  • 第六章、用户体验五要素之框架层解析(本文作用是通俗讲解,让你更容易理解)

            结构层定义产品运行形式,框架层则用于确定用什么样的功能或者形式来实现。在框架层,功能型和信息型产品都需要信息设计,不同的是功能型还需要界面设计,而信息型产品则是导航设计。         1、界面设计:如果涉及提供给用户做某些事的能力,那就是界

    2024年02月09日
    浏览(41)
  • ModbusTCP协议报文解析

    交互(通信)标识 :2个字节 为此次通信事务处理标识符,一般每次通信之后将被要求加1以区别不同的通信数据报文。 协议标识 :2个字节 表示该条指令遵循ModbusTCP协议,一般都为00 00 报文长度 :2个字节 表示后面数据的长度,有几个字节,高字节在前 (前六位Modbus/TCP协议

    2024年02月02日
    浏览(34)
  • TCP之报文格式解析

    TCP网络协议是较常用的,也基本上都会接触,那么来简单了解下它吧。TCP 是一种面向连接的、可靠的传输协议,它能够将数据分成一些小块,并通过 Internet 进行传输。在 TCP 中,数据被分割成一些称为 TCP 报文段(TCP segment)的小块,每个 TCP 报文段携带了一部分数据,以及一

    2024年02月03日
    浏览(53)
  • ModbusRTU串口读写报文解析

    Modbus是一种通信协议,ModubsRTU是它的一种传输模式,通过这个协议能实现串口数据通讯。可以用C#控件读写串口,也可以直接使用开源的串口助手。 为了简化问题,本文只解析报文的格式,且只讨论 异常状态 、 读多个保持寄存器 与 写多个保持寄存器 。 报文分为上行报文和

    2024年02月05日
    浏览(31)
  • CAN报文解析

    CAN报文是指发送单元向接受单元传送数据的帧。我们通常所说的CAN报文是指在CAN线(内部CAN、整车CAN、充电CAN)上利用ECU和CAN卡接收到的十六进制报文。 对于单个Byte,CAN总线在进行数据传输时,首先传输一个字节的高位(MSB),最后传输该字节的低位(LSB)。 一般情况下,

    2023年04月08日
    浏览(32)
  • 在线解析二进制报文

    智能设备应用越来越普遍,深入到生活的各个方面,从智慧农业到智能制造,从水利灌溉到电力传输,从工业生产到智能家居。智能设备应用在各个领域,设备之间都是通过数据交换来达到信息共享和互相操作,交换的数据都遵守某个协议标准,在测试时,调试时和排查问题

    2024年02月06日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包