1 概述

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级"通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。MQTT最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。

MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。

注:由于业务用上了MQTT作为设备通讯协议内容,此篇文章为总结几篇mqtt报文解析的好文再加上mqtt官方文档出的,故此为整理备忘文。

2 控制报文格式

MQTT控制报文由三部分组成:固定头(Fixed header)+可变头(Variable header)+有效载荷(Payload)

Fixed header 固定头部,MQTT协议分很多种类型,如连接,发布,订阅,心跳等。其中固定头是必须的,所有类型的MQTT协议中,都必须包含固定头
Variable header 可变头部,可变头部不是可选的意思,而是指这部分在有些协议类型中存在,在有些协议中不存在
Payload 消息载体,就是消息内容。与可变头一样,在有些协议类型中有消息内容,有些协议类型中没有消息内容

2.2 固定报头(Fixed header)

Bit

7

6

5

4

3

2

1

0

byte 1

MQTT Control Packet type

MQTT控制报文类型

Flags specific to each MQTT Control Packet type

用于指定的控制报文类型标志位

byte 2…

Remaining Length 剩余长度

2.2.1 MQTT控制报文类型(MQTT Control Packet type)

第一个字节的7-4位,一共4位,可表示16个数字,除0 禁止使用以外,剩余15个数字各表示一个控制报文类型,如图所示:

Name

名称

Value

Direction of flow

报文流动方向        

Description

描述

Reserved

0

禁止

Reserved (预留)

CONNECT

1

客户端到服务器

Client request to connect to Server

客户端连接到服务器

CONNACK

2

Server to Client

Connect acknowledgment

连接确认

PUBLISH

3

Client to Server

or

Server to Client

Publish message

发布消息

PUBACK

4

Client to Server

or

Server to Client

Publish acknowledgment

发布确认(QoS 1)

PUBREC

5

Client to Server

or

Server to Client

Publish received (assured delivery part 1)

发布收到(QoS 2保证交付第一步)

PUBREL

6

Client to Server

or

Server to Client

Publish release (assured delivery part 2)

发布释放(QoS 2保证交付第二步)

PUBCOMP

7

Client to Server

or

Server to Client

Publish complete (assured delivery part 3)

发布完成(QoS 2保证交付第二步)

SUBSCRIBE

8

Client to Server

Client subscribe request

客户端订阅请求

SUBACK

9

Server to Client

Subscribe acknowledgment

订阅请求确认

UNSUBSCRIBE

10

Client to Server

Unsubscribe request

取消订阅请求

UNSUBACK

11

Server to Client

Unsubscribe acknowledgment

取消订阅请求确认

PINGREQ

12

Client to Server

PING request

心跳请求

PINGRESP

13

Server to Client

PING response

心跳响应

DISCONNECT

14

Client to Server

Client is disconnecting

客户端断开连接

AUTH

15

Client to Server or Server to Client

Authentication exchange

身份验证交换

2.2.2 标志位(Flags)

固定报头中字节1的剩余位[3-0]包含特定于每个MQTT控制数据包类型的标志,如下所示。当标志位标记为“保留”时,它将保留供将来使用,并且必须设置为所列值[MQTT-2.1.3-1]。如果接收到无效标志,则为格式错误的数据包。

MQTT Control Packet

Fixed Header flags

Bit 3

Bit 2

Bit 1

Bit 0

CONNECT

Reserved

0

0

0

0

CONNACK

Reserved

0

0

0

0

PUBLISH

Used in MQTT v5.0

DUP

QoS

RETAIN

PUBACK

Reserved

0

0

0

0

PUBREC

Reserved

0

0

0

0

PUBREL

Reserved

0

0

1

0

PUBCOMP

Reserved

0

0

0

0

SUBSCRIBE

Reserved

0

0

1

0

SUBACK

Reserved

0

0

0

0

UNSUBSCRIBE

Reserved

0

0

1

0

UNSUBACK

Reserved

0

0

0

0

PINGREQ

Reserved

0

0

0

0

PINGRESP

Reserved

0

0

0

0

DISCONNECT

Reserved

0

0

0

0

AUTH

Reserved

0

0

0

0

DUP = Duplicate delivery of a PUBLISH packet(控制报文的重复分发标志)

QoS = PUBLISH Quality of Service( PUBLISH报文的服务质量等级)

RETAIN = PUBLISH retained message flag(PUBLISH报文的保留标志)

2.2.3 剩余长度(Remaining Length)

Remaining Length意思是剩余长度,即Variable Header + Payload的长度。剩余长度从Byte 2开始,最长可达4字节。所以剩余长度范围是Byte[2-5]。那么怎样确定其长度到底是1还是4呢,这取决于字节的最高位Bit 7(默认都是高字节在前),如果这个值是1,那么就继续计算字节长度,如果是0,那么就不再计算字节长度。

消息长度可以简单理解为128进制的数据,4位长度最大可以表示128*128*128*128Byte=256MB。但是这个长度的计算有些特别,就是低位在前,高位在后(因为正常的表示方法是高位在前,低位在后),字节最高位Bit7用于标记是否需要继续计算消息长度。以下是消息长度的长度范围:

字节 最小值 最大值
1 0(0x00) 127(0x7F)
2 128 (0x80, 0x01) 16 383 (0xFF, 0x7F)
3 16 384 (0x80, 0x80, 0x01) 2 097 151 (0xFF, 0xFF, 0x7F)
4 2 097 152 (0x80, 0x80, 0x80, 0x01) 268 435 455 (0xFF, 0xFF, 0xFF, 0x7F)

稍微注意一下,0x80=1000 0000,不是 1000。刚开始以为是1000,所以就没明白。

举个例子。

消息假设长度是[0X60],其二进制是01100000,字节最高位Bit7(从左边起第0位)是0,所以不需要继续往后计算。那么消息长度就是0X60,十进制数是96。

如果消息长度是[0XC1, 0XC2, 0X33],那么他们的二进制分别如下,

0xC1=1100 0001

0xC2=1100 0010

0x33=0011 0011,

第一字节最高位是1,那么需要继续向后计算,去掉标记位(0xC1%128),得到100 0001=41

第二字节最高位是1,那么需要继续向后计算,去掉标记位(0xC2%128),得到100 0010=42

第三字节最高位是0,不需要向后计算,其结果就是0x33=51

因为低位在前,高位在后,那么长度计算为Length=41 + 42*128 + 51*128*128=841001 B = 821KB

需要注意的是,消息长度=可变头部长度+消息内容长度。不包括首字节和消息长度本身,如果消息长度为5,那么说明这条消息后边还有5字节,整条消息长度为7(首字节+1位长度字节+5)。

另外如果消息长度为4字节,最后一位不能超过0X7F=127,因为如果超出这个值,其最高位Bit7是1,还需要往后计算,这与消息最大长度为4字节矛盾。所以如果出现[0XFF, 0XFF, 0XFF, 0XFF]这样的消息长度,那么接收方认为这是一条非法的消息。

2.3 可变报头(Variable header)

某些类型的MQTT控制数据包包含可变头组件。它位于固定标头和有效负载之间。可变报头的内容因数据包类型而异。可变报头的数据包标识符字段在几种数据包类型中很常见。

2.3.1 包标识符

许多 MQTT 控制数据包类型的变量头组件包括一个两字节整数数据包标识符字段。这些 MQTT 控制数据包是 PUBLISH(其中 QoS > 0)、PUBACK、PUBREC、PUBREL、PUBCOMP、SUBSCRIBE、SUBACK、UNSUBSCRIBE、UNSUBACK。

需要数据包标识符的 MQTT 控制数据包如下所示:

MQTT Control Packet

Packet Identifier field

CONNECT

NO

CONNACK

NO

PUBLISH

YES (If QoS > 0)

PUBACK

YES

PUBREC

YES

PUBREL

YES

PUBCOMP

YES

SUBSCRIBE

YES

SUBACK

YES

UNSUBSCRIBE

YES

UNSUBACK

YES

PINGREQ

NO

PINGRESP

NO

DISCONNECT

NO

AUTH

NO

如果 PUBLISH 数据包的 QoS 值设置为 0 ,则 PUBLISH 数据包不得包含数据包标识符。
每次客户端发送一个新的 SUBSCRIBE、UNSUBSCRIBE 或 PUBLISH(其中 QoS > 0)MQTT 控制数据包时,它必须为其分配一个当前未使用的非零数据包标识符 。
每次服务器发送一个新的 PUBLISH(QoS > 0)MQTT 控制数据包时,它必须为其分配一个当前未使用的非零数据包标识符 。
在发送方处理了相应的确认数据包后,数据包标识符就可以重新使用,定义如下。在 QoS 1 PUBLISH 的情况下,这是对应的 PUBACK;在 QoS 2 PUBLISH 的情况下,它是 PUBCOMP 或原因代码为 128 或更大的 PUBREC。对于 SUBSCRIBE 或 UNSUBSCRIBE,它是对应的 SUBACK 或 UNSUBACK。
与 PUBLISH、SUBSCRIBE 和 UNSUBSCRIBE 数据包一起使用的数据包标识符为会话中的客户端和服务器单独形成了一组统一的标识符。一个数据包标识符在任何时候都不能被多个命令使用。
PUBACK、PUBREC、PUBREL 或 PUBCOMP 数据包必须包含与最初发送的 PUBLISH 数据包相同的数据包标识符。SUBACK 和 UNSUBACK 必须包含分别在相应的 SUBSCRIBE 和 UNSUBSCRIBE 数据包中使用的数据包标识符。
客户端和服务器相互独立地分配数据包标识符。因此,客户端-服务器对可以使用相同的数据包标识符参与并发消息交换。

2.4 有效载荷(Payload)

一些MQTT控制数据包包含一个有效负载作为数据包的最后一部分。在发布包中,这是应用程序消息。控制类型所需 payload 如下图:

MQTT Control Packet

Payload

CONNECT

Required

CONNACK

None

PUBLISH

Optional

PUBACK

None

PUBREC

None

PUBREL

None

PUBCOMP

None

SUBSCRIBE

Required

SUBACK

Required

UNSUBSCRIBE

Required

UNSUBACK

Required

PINGREQ

None

PINGRESP

None

DISCONNECT

None

AUTH

None

参考文献:

1.MQTT协议 -- 消息报文格式_weixin_34166847的博客-CSDN博客

2.MQTT Version 5.0

3.MQTT协议报文格式解析 - 知乎

3.

MQTT5协议报文格式相关推荐

  1. 【计算机网络】网络层 : BGP 协议 ( BGP 协议简介 | BGP 协议信息交换 | BGP 协议报文格式 | BGP-4 常用报文 | RIP 、OSPF、BGP 协议对比 )

    文章目录 一.路由选择协议分类 二.BGP 协议 简介 三.BGP 协议 信息交换过程 三.BGP 协议 报文格式 四.BGP 协议 特点 五.BGP-4 协议的 四种报文 六.RIP .OSPF.B ...

  2. 三菱MELSEC 1帧协议报文格式。

    关于三菱 MC 1E协议报文说明: 是不是1E协议可以发送:D100 .报文: 01ff0A00 64 00 00 00 20 44   0200 试试,返回报文:810000000000 报文格式: ...

  3. Bacnet协议报文格式详解(一)

    系统实现基于BACnet/IP(又称B/IP)网络进行通讯.BACnet虚拟链路层(BVLL)提供了BACnet网络层和某指定的通讯子系统的接口,本文指定了BACnet虚拟链路控制(BVLC)要求支持 ...

  4. HTTP(超文本传输协议)报文格式

    HTTP请求报文 http请求报文数据分为三部分: 请求行 请求头部 请求数据 http请求报文的格式如下图所示: 下面是Get请求的例子: GET /92316461213.jpg HTTP/1.1 ...

  5. MQTT协议详解及开发教程(四)MQTT协议报文格式

    推荐一款稳定的基于C编写的MQTT Client开源库 cMQTT MQTT协议详解及开发教程(一)MQTT协议概述 MQTT协议详解及开发教程(二)MQTT服务器EMQx搭建 MQTT协议详解及开发 ...

  6. 计算机网络-传输层(UDP协议报文格式,伪首部,UDP校验过程)

    文章目录 1. UDP协议 UDP报文格式 UDP校验过程 1. UDP协议 UDP只在IP数据报服务之上增加了很少功能,即复用分用和差错检测功能. UDP的主要特点: UDP是无连接的,减少开销和发 ...

  7. http协议报文格式原理图

    报文字段含义请参见:http协议报文字段含义

  8. 计算机网络11种协议报文格式

    文章目录 TCP UDP IP IPV6 IPSec 以太网帧结构 802.1Q以太网帧结构 802.11无线链路帧 SSL记录 RTP实时传输协议 OpenFlow流表 参考 TCP 源端口号和目的 ...

  9. 详解 HTTP 协议报文格式 构造 HTTP 请求

    目录 1. HTTP 协议 1.1 HTTP 协议格式 1.2 HTTP 请求 (Request) 1.2.1 认识 URL 1.2.2 关于 URL encode 1.2.3 认识 "方法 ...

  10. ARP/RARP协议报文格式

    图6-1  ARP/RARP报头结构 ARP和RARP使用相同的报头结构,如图6-1所示. 图6-1中的各字段的具体含义如下: 硬件类型:指明发送方想知道的硬件接口类型,以太网的值为1: 协议类型:指 ...

最新文章

  1. UVA 10714 - Ants
  2. phoenix hbase Can't get master address from ZooKeeper; znode data == null
  3. 利用yum升级操作系统版本(目前最新6.6)
  4. 网页中启动QQ的 XX 命令
  5. 关于VS2012连接MySql数据库时无法选择数据源
  6. codeforces G - Almost Increasing Array 动态规划、动态开点线段树
  7. MSP430F5529 DriverLib 库函数学习笔记(十二)I2C实战
  8. struts2 在拦截器进行注入(依据Action是否实现自己定义接口)
  9. 止汗 咒语_咒语机器学习平台上线
  10. Dima and Salad 01背包变形
  11. 移动医疗是什么 移动医疗应用实例
  12. python双人对决小游戏
  13. 新版个人所得税python123_【Python教程】02.基础语法
  14. MySQL查看当前数据库
  15. php四舍六入五成双算法
  16. hammer.js教程2
  17. 什么是RCT实时时钟?(STM32中RTC时钟源)
  18. 什么是内存溢出?在哪些区域会发生内存溢出?
  19. 软铁氧体磁芯的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  20. 刘强东:企业家千万别算小钱 我不研究马云

热门文章

  1. 计算机操作系统|汤小丹|第四版|习题答案(六)
  2. mongoVue 对mongodb的操作
  3. 越狱苹果抹掉数据怎么恢复cydia红字黄字闪退(淘宝30块买的)
  4. 445端口的简单利用
  5. Flex Builder 3.0正式版+破解补丁
  6. 体重增长:目前为止我们所知道的一切器
  7. 设置Windows系统双网卡同时上内外网
  8. Excel技能培训之十五 函数使用rank,Frequency,subtotal超级表,切片器,iferor,常用错误代码
  9. xposed框架_无需Root使用Xposed框架、功能非常强大
  10. ATmega328p EEprom读写