MQTT协议图解,一文看懂MQTT协议数据包(真实报文数据解析解释)

这篇具有很好参考价值的文章主要介绍了MQTT协议图解,一文看懂MQTT协议数据包(真实报文数据解析解释)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文主要介绍MQTT协议的结构和具体的2条报文数据解析,帮忙更简单、快速地理解mqtt协议,如果要深入了解实现完整的协议,可以查看文章最后的完整协议文档做更深入的研究。

一、MQTT协议

MQTT协议在lot领域是使用的最广泛的通用协议,在一般企业级物联网产品开发中,通常会考虑的协议基本上就只有2种,一种是私有的自定义协议,另一种就是通用的MQTT协议;在产品品类相对较少或者对系统性能要求极高的情况下,一般会选择自定义的协议,其他大部分情况下,都会选择MQTT协议。

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。

mqtt协议的优点,官方的解释是:用极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务;简单理解就是,实现起来简单,并且在传输上无效的数据也很少,而且能够保证数据传输的可靠性。

二、协议详解

2.1 协议结构

MQTT协议由三部分组成,固定报头,可变报头,有效载荷;固定报头是所有的报文统一的格式,可变抱头则根据固定抱头中的报文类型不同基本不同,每个报文类型基本上都有自己的可变报头格式,这里需要注意,最后有效载荷则部分报文有,部分报文没有,而且报文内容也是根据报文类型的不同而不同;协议总结构如下图所示:
MQTT协议图解,一文看懂MQTT协议数据包(真实报文数据解析解释)

MQTT结构示意图

MQTT协议总体来讲,就是规定了16条报文的具体规范,每一条报文都有自己的用途,自己的规定;一开始接触MQTT协议的时候,因为概念和名字较多可能会有点不容易理解,但是梳理清楚一两条具体报文的含义之后,就能比较清晰的理解这份协议了;把16条报文理解清楚,就能实现完整的MQTT协议。

2.1.1 固定报头

固定报头是MQTT协议开头,2个字节,分为三个部分:标志位、报文类型、剩余长度,下图为固定报头结构示意图
MQTT协议图解,一文看懂MQTT协议数据包(真实报文数据解析解释)
在上面的结构示意图中可以看的比较清晰;第一个字节分为2个部分:标志位和报文类型,一个字节有8位二进制,前面的4位用来做标志位,标志位在每条报文中有不同的作用,具体作用看后面的单条报文数据分析

后4位用来表示表示具体的报文类型,一共有16种,有部分类型是预留未使用的类型,在代码实现时,可以暂时忽略;具体的报文类型如下表所示:
MQTT协议图解,一文看懂MQTT协议数据包(真实报文数据解析解释)

第二个字节是剩余长度,其表示的就是在剩余长度之后的数据长度(还有多少个字节),剩余长度的字节数是不固定的,至少一个字节,最多4个字节,所以固定报头中包含的一个字节就是剩余长度的第一个字节;这里需要说明一下,剩余长度的每一个字节的最高位是一个标志位,用来表示下一个字节是否也属于剩余长度

举例说明:
比如:
0100 0000(最高位为0) 则说明后面的字节数据不属于剩余长度了

1010 0000(第一个字节,最高位为1) 0000 0001(第二个字节,最高位为0) 则说明后面的字节数据属于剩余长度,第2个字节最高位为0,则说明后面没有属于剩余长度的字节了,那么此剩余长度则为这2个字节

因为剩余长度的每个字节的最高位为标志位,所以其真实值并不是这些字节直接合并而成,需要另外进行计算;
举例说明:
如果第一个字节的最高位为0,则说明剩余长度只有一个字节,并且其值就是这个字节的值,如:0100 0000 那么剩余长度的真实值就是:64
如果剩余长度超过一个字节,那么就需要将每个字节的高字节去掉,然后组成一个新的数据,计算其值,下面举例说明:
2个字节长度的剩余长度计算

第一个字节 第二个字节
1010 0000 0000 0001

去掉标志位后,其新值为

第一个字节 第二个字节
010 0000 000 0001

合并时,后面的字节在高位,则合并后值为:1010 0000,则剩余长度的值为十进制的160;

三个字节长度的剩余长度计算

第一个字节 第二个字节 第三个字节
1001 0001 1100 1001 0100 1001

去掉标志位后,其新值为

第一个字节 第二个字节 第三个字节
001 0001 100 1001 100 1001

后面的字节在高位,则合并后值为:100 1001 100 1001 001 0001,则剩余长度的值为十进制的1205393;

四个字节长度的剩余长度计算

第一个字节 第二个字节 第三个字节 第四个个字节
1001 0001 1100 1001 1100 1001 0100 1101

去掉标志位后,其新值为

第一个字节 第二个字节 第三个字节 第四个个字节
001 0001 100 1001 100 1001 100 1101

后面的字节在高位,则合并后值为:100 1101 100 1001 100 1001 001 0001,则剩余长度的值为十进制的162686097;

剩余长度字段的解码算法如下:

multiplier = 1
 value = 0
 do
	 encodedByte = 'next byte from stream'
	 value += (encodedByte AND 127) * multiplier
	 multiplier *= 128
	 if (multiplier > 128*128*128)
	 throw Error(Malformed Remaining Length)
 while ((encodedByte AND 128) != 0)

AND 是位操作与(C 语言中的&)
这个算法终止时,value 包含的就是剩余长度的值

2.1.2 可变报头

可变报头的数据依据固定报头中的报文类型而不同,一般是包含和报文类型相关的数据;例如客户端连接服务器报文,包含了协议名,协议级别(用来表示mqtt的版本信息)、连接标志、保持连接;可变报头内容示意图如下:
MQTT协议图解,一文看懂MQTT协议数据包(真实报文数据解析解释)
发布消息报文可变报头,则内容仅包含了主题名和报文标识符(仅当标志位Qos>0)
MQTT协议图解,一文看懂MQTT协议数据包(真实报文数据解析解释)

2.1.3 有效载荷

有效载荷内容也是根据报文类型的不同而不同,在上述可变报头的2张示意图中也能看出,连接服务器报文的有效载荷则包含了:客户端标识符、遗属主题、遗属消息、用户、密码,而发布消息报文,则仅仅包含了应用消息;不同的有效载荷解析方式有所不同,具体要看每一条报文的规定,详情可以参见最后一个章节提供的Mqtt官方手册。

三、具体协议报文详解

经过上面的学习,对MQTT协议应该有了一个初步的了解,接下来就使用2条具体的协议报文数据,更详细的介绍mqtt协议的具体数据和实现。

3.1 连接服务器报文详解

首先来看看连接服务器报文协议,先贴出具体的一条连接服务器报文协议数据(16进制数,每2个数字表示一个字节)

10ab0100044d51545404c2001400177061686f31363735313537353030373437303030303030000464656d6f00803846334238444532464443384244334437393242453737454143343132303130393731373635453542444436433439394144434545383430434534343142444546313745333036383442443935434137303846353530323232323243433631363144304432334332444643423132463841433939384635394537323133333933

接下来我们一个字节一个字节来解析,还是按照协议结构来分析(每一条报文所包含报文信息,在mqtt协议规范中都会有说明)
MQTT协议图解,一文看懂MQTT协议数据包(真实报文数据解析解释)
先把整体的解析数据罗列出,再进行详细的解析说明:
MQTT协议图解,一文看懂MQTT协议数据包(真实报文数据解析解释)
第1个字节是10,二进制则为:0001 0000(位置从后往前数) ,前4位为0000,则标志位全为0,标志位数据表示的意思需要根据报文类型来确定,详情可以参考文章最后的官方文档;后4位0001,值为1,则表示报文类型为客户端连接服务器(CONNECT)

第2个字节:ab,二进制为:1010 1011,第2个字节为剩余长度的起始字节,其最高位为1,则说明后面一个字节也属于剩余长度,第3个字节:01,二进制为:0000 0001 最高位为0,则剩余长度结束,共包含了2个字节,依据前面剩余长度的算法解释,可得出剩余长度等于171,表示该报文后面还有171个字节。

根据官方文档的解释:连接服务器报文可变报头的起始2个字节为协议名的长度;前面已经解析了3个字节;
则第4个字节至第5个字节则为协议名称的长度:00 04 协议名长度为4,

第6-9个字节为协议名,6-9字节为:4d 51 54 54 ,根据协议规定,协议名为ascii码值,则协议名解析为:MQTT

接下来的字节为协议级别,即第10个字节为协议级别:04 (官方解释:0x04 表示3.1.1版本)

接下来的第11个字节为 连接标志,连接标志位的详细解释如下图所示:
MQTT协议图解,一文看懂MQTT协议数据包(真实报文数据解析解释)
第11个字节:c2 二进制为:1100 0010,那么会话清理(clean session)为1,表示丢弃之前的会话,开始一个新的会话;另外用户名和密码标志位为1,则说明在有效载荷中携带了用户名和密码信息,遗属标志位为0,则有效载荷中就没有遗属主题和遗属消息

第12-13字节:00 14,用来表示保持连接的时间(秒),即为10十进制:20秒

到此处可变报头就解析完了,接下来就是解析有效载荷部分了,连接服务器报文有效载荷格式为前个字节为字段长度,然后接字段值的格式

第14-15字节:00 17,用来表示客户端标识符长度,即为10十进制:23个字节
第16-38字节:7061686f31363735313537353030373437303030303030 ,表示客户端标识符,客服端标识符为ascii码格式,则此处为:paho1675157500747000000
第39-40字节:00 04,用来表示用户长度,即为10十进制:4个字节
第41-44字节:64 65 6d 6f,用来表示用户名,ascii码为(demo)
第45-46字节:00 80 ,用来表示密码长度 ,即为10进制:128
第47-174字节:
3846334238444532464443384244334437393242453737454143343132303130393731373635453542444436433439394144434545383430434534343142444546313745333036383442443935434137303846353530323232323243433631363144304432334332444643423132463841433939384635394537323133333933
即为密码,也是使用ascii码

至此我们已经完整的解析了一条mqtt客户端连接服务器报文

3.2 发布消息报文详解

下面来看发布消息报文,此报文可变报头仅有2个部分,一个是主题名,一个是报文标识符,报文标识符仅当Qos大于0时才有,然后就是有效载荷,有效载荷都是自己定义的内容,收到数据后按自定义规则解析即可;
MQTT协议图解,一文看懂MQTT协议数据包(真实报文数据解析解释)

发布消息报文结构示意图
来看一条具体报文数据(报文都是16进制显示,2个字符表示一个字节)
301200047465737468656c6c6f2c776f726c64

先把整体的解析数据罗列出,再进行详细的解析说明:
MQTT协议图解,一文看懂MQTT协议数据包(真实报文数据解析解释)
第1个字节是30,二进制则为:0011 0000(位置从后往前数) ,前4位为0000,则标志位全为0,标志位数据表示的意思需要根据报文类型来确定,详情可以参考文章最后的官方文档;后4位0011 值为3,则表示报文类型为发布消息(PUBLISH)

第2个字节:11,二进制为:0001 0001,第2个字节为剩余长度的起始字节,其最高位为0,则说明剩余长度就只有这一个字节,10进制值为17,表示该报文后面还有17个字节。

第3个字节开始就是可变报头,发布消息类型的可变抱头,第一个就是主题,格式内容为2个字节的主题名称长度,然后跟上主题名;则第3-4个字节为主题名长度:00 04,表示有4个字节的主题名

第5-8字节为主题名:74657374 ,主题名为asicc码格式,则为:test

因为固定报头中标志位为0,则Qos=0,则没有报文标识符
第9-19字节为有效载荷:68656c6c6f2c776f726c64 (ascii码:hello,world)

再看一条带有Qos=1的发布消息报文数据

3213000474657374000168656c6c6f2c776f726c64

先列出整体的解析数据
MQTT协议图解,一文看懂MQTT协议数据包(真实报文数据解析解释)
这里解释一下什么是 QoS
很多时候,使用 MQTT 协议的设备都运行在网络受限的环境下,而只依靠底层的 TCP 传输协议,并不能完全保证消息的可靠到达。因此,MQTT 提供了 QoS 机制,其核心是设计了多种消息交互机制来提供不同的服务质量,来满足用户在各种场景下对消息可靠性的要求。

MQTT 定义了三个 QoS 等级,分别为:
QoS 0,最多交付一次。
QoS 1,至少交付一次。
QoS 2,只交付一次。
其中,使用 QoS 0 可能丢失消息,使用 QoS 1 可以保证收到消息,但消息可能重复,使用 QoS 2 可以保证消息既不丢失也不重复。QoS 等级从低到高,不仅意味着消息可靠性的提升,也意味着传输复杂程度的提升。在发布者到订阅者的消息投递流程中,QoS 等级是由发布者在 PUBLISH 报文中指定的。

第1个字节是32,二进制则为:0011 0010(位置从后往前数) ,第2-3位表示的是Qos,则Qos=1那么后面的可变报文中,就会添加报文标识符了;后4位0011 值为3,则表示报文类型为发布消息(PUBLISH)

第2个字节:13,二进制为:0001 0011,第2个字节为剩余长度的起始字节,其最高位为0,则说明剩余长度就只有这一个字节,10进制值为19,表示该报文后面还有19个字节。

第3个字节开始就是可变报头,发布消息类型的可变抱头,第一个就是主题,格式内容为2个字节的主题名称长度,然后跟上主题名;则第3-4个字节为主题名长度:00 04,表示有4个字节的主题名

第5-8字节为主题名:74657374 ,主题名为asicc码格式,则为:test

因为标志位中Qos=1,则下面的2个字节表示报文标识符,报文标识符一般都是用来表示消息数,用来区分不同的消息,避免处理重复消息
第9-10字节:00 01,则报文标识符为1

第11-21字节为有效载荷:68656c6c6f2c776f726c64 (ascii码:hello,world)

两条报文对比一下,因为固定报头中的标志位不同,影响了可变报头的内容,多了一个报文标识符;通过这3条报文数据的解析,相信你应该对mqtt协议有了一个比较清晰的认识了,如果想实现完整的协议,则请继续往后看。

四、开源的MQTT实现

了解熟悉mqtt协议后,就可以学着去实现mqtt协议,MQTT协议作为成熟、通用且使用广泛的协议,其实已经有很多的开源代码实现了其协议,学习借鉴这些优秀的开源代码,相信能给你开发出理想的mqtt应用带来非常多的帮助,以下是mqtt官方罗列的一些实现 ,点击这里查看

五、官方文档3.1.1中文翻译下载

想要查看更详细、完整的MQTT协议,可以查看此份官方文档,每一条报文的详细实现都有非常明确的说明
下载MQTT 协议 3.1.1 中文版

有些小伙伴反馈,无法下载文档,如果无法下载,请前往百度网盘下载,百度网盘地址 , 提取码: bvk5

六、官方文档5.0中文翻译下载

百度网盘地址 链接: https://pan.baidu.com/s/1iI75rW5El2BJ3exlkgddng?pwd=jpe1 提取码: jpe1,点击下载文章来源地址https://www.toymoban.com/news/detail-415613.html

到了这里,关于MQTT协议图解,一文看懂MQTT协议数据包(真实报文数据解析解释)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 冒泡排序(超详细图解加代码解析,5分钟看懂)

      目录 1.冒泡排序的定义 2.冒泡排序的原理 3.代码及其解析 4.冒泡排序的改进 5.实现冒泡排序函数 生命中永远会有令人懊恼的事,但我知道,我们是为了不留遗憾活着的,对吗? 1.冒泡排序的定义 冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的

    2024年02月11日
    浏览(47)
  • 【SBUS】一文看懂SBUS协议

    【STM32】STM32单片机总目录 S.BUS是一个串行通信协议,S.BUS是FUTABA提出的舵机控制总线, S.bus使用RS232C串口的硬件协议作为自己的硬件运行基础。 使用TTL电平,即3.3V。 使用负逻辑,即低电平为“1”,高电平为“0”。 波特率:100000(100k),注意:不兼容波特率115200。 硬件取

    2024年02月14日
    浏览(35)
  • HTTP协议 | 一文详解HTTP报文结构

    目录 🌳 HTTP/HTTPS简介 🌳 HTTP工作原理 HTTP三点注意事项 1. HTTP是无连接的 2. HTTP是媒体独立的 3. HTTP是无状态的 HTTPS 作用 🌳 HTTP消息结构 HTTP请求消息 1. 请求行 2. 请求头 3. 空行 4. 请求数据 HTTP请求实例 HTTP请求GET和POST的区别 1. 传输数据的方式不同 2. 传输数据的大小不同 3

    2024年02月03日
    浏览(44)
  • 一文看懂计算机网络五层协议+各层网络协议大全

    目录 一、通用五层协议体系 5. 应用层 4. 运输层 3. 网络层 2. 数据链路层 1. 物理层 二、各层之间的传递过程 三、TCP/IP体系结构 四、网络协议大全(各种属于哪一层) 五、举例:RTSP 应用进程间通信和交互的规则。通过应用进程间的交互来完成因特网络应用,协议有很多,比

    2023年04月08日
    浏览(36)
  • 【阿里云】物联网平台配置ESP8266真实设备AT串口连接,支持MQTT协议通信

    1 阿里云物联网平台 官方文档:https://help.aliyun.com/product/30520.html 官方控制台:https://iot.console.aliyun.com/lk/summary/new 左边有产品和设备, 产品是抽象的品类 ,比如说电灯,空调等等。 设备是品类下具体的物品 ,和实物一一对应的云端信息,比如电灯1,电灯2,电灯-卧室,电灯

    2024年02月01日
    浏览(56)
  • 一文看懂微信小程序新版隐私协议(附带弹窗组件)

    微信小程序近期又迎来了一次改革–9月15日之后如果小程序涉及调用微信的隐私接口获取用户的信息的,需要用户手动同意协议后才可正常调用接口,否则会返回报错信息。 隐私接口目前常用的有:手机号快捷获取、读取照片、获取用户的头像昵称(包括快捷填写能力)等。

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

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

    2024年02月02日
    浏览(34)
  • YOLOv8 深度解析!一文看懂,快速上手实操(附实践代码)

    关注并星标 从此不迷路 计算机视觉研究院 公众号ID |ComputerVisionGzq 学习群 |扫码在主页获取加入方式 开源地址:https://github.com/ultralytics/ultralytics 计算机视觉研究院专栏 作者:Edison_G YOLOv8 是 ultralytics 公司在 2023 年 1月 10 号开源的 YOLOv5 的下一个重大更新版本,目前支持图

    2024年02月09日
    浏览(46)
  • 2.1 - 网络协议 - ARP协议原理,报文解析,抓包实战

    「作者主页」: 士别三日wyx 「作者简介」: CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」: 对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 ARP(Address Resolution Protocol)是 「地址解析协议」 ,可以根据IP地址获取Mac地

    2024年02月07日
    浏览(35)
  • 一文讲透TCP/IP协议 | 图解+秒懂+史上最全

    目录 🙋‍♂️ TCP/IP协议详解 🙋‍♂️ TCP/IP协议的分层模型 OSI模型的七层框架 TCP/IP协议与七层ISO模型的对应关系 (一)TCP/IP协议的应用层 (二)TCP/IP协议的传输层 (三)TCP/IP协议的网络层 (四)TCP/IP协议的链路层 🙋‍♂️ 图解 物理层:使用MAC解决设备的身份证问题

    2024年02月06日
    浏览(54)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包