MQTT控制报文格式

目录

2.1 MQTT控制报文的结构 Structure of an MQTT Control Packet

MQTT协议通过交换预定义的MQTT的控制报文来通信。本节将介绍这些数据报文的格式。

MQTT控制报文可以最多由三部分组成,它们按照图例2.1-MQTT控制报文的结构所示的顺序排序:

图例2.1-MQTT控制报文的结构

固定报头 Fixed header存在于所有MQTT控制报文中可变报头 Variable header存在于某些MQTT控制报文中有效负载 Variable header存在于某些MQTT控制报文中

2.2 固定报头 Fixed header

每个MQTT控制报文都包含一个固定报头。图例2.2-固定报头的格式说明了固定报头的格式。

图例2.2-固定报头的格式

位 Bit76543210字节1 byte 1MQTT控制数据报文类型每种MQTT控制报文的专属标志字节2 byte 2 ...剩余长度

2.2.1 MQTT控制数据报文的类型 MQTT Control Packet type

位置:第1个字节的7-4位。

表示为4位无符号值,这些值的定义见 表2.1-控制数据报文类型

表2.1-控制数据报文类型

名称

传递方向

描述

保留 Reserved

0

禁止

保留类型

连接 CONNECT

1

客户端→服务端

客户端请求连接到服务端

连接确认 CONNACK

2

客户端←服务端

连接确认

发布 PUBLISH

3

客户端→服务端 或 客户端←服务端

发布消息

发布确认 PUBACK

4

客户端→服务端 或 客户端←服务端

发布确认

发布收到 PUBREC

5

客户端→服务端 或 客户端←服务端

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

发布释放 PUBREL

6

客户端→服务端 或 客户端←服务端

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

发布完成 PUBCOMP

7

客户端→服务端 或 客户端←服务端

发布完成(保证交互第三步)

订阅 SUBSCRIBE

8

客户端→服务端

客户端订阅请求

订阅确认 SUBACK

9

客户端←服务端

订阅确认

退订 UNSUBSCRIBE

10

客户端→服务端

退订请求

退订确认 UNSUBACK

11

客户端←服务端

退订确认

心跳请求 PINGREQ

12

客户端→服务端

心跳PING请求

心跳响应 PINGRESP

13

客户端←服务端

心跳PING响应

断开 DISCONNECT

14

客户端→服务端

客户端断开连接

保留 Reserved

15

禁止

保留类型

2.2.2 标志 Flags

固定报头第1个字节的[3-0]位的剩余位报文含专属于不同MQTT控制报文类型的标志,如下面表格2.2 -标志位所示。==表格2.2中标记为“保留Reserved”的标志位,是为了将来的使用而保留的,同时设置它为表格中列出的值== [MQTT-2.2.2-1]。==如果收到非法的标志位,接收端必须关闭网络连接==。[MQTT-2.2.2-2] 有关错误处理的详细信息请参见第4.8节。

表格2.2-标志位

控制报文类型 Control Packet

固定报头标志 Fixed header flags

位3 Bit 3

位2 Bit 2

位1 Bit 1

位0 Bit 0

连接 CONNECT

Reserved

0

0

0

0

连接确认 CONNACK

Reserved

0

0

0

0

发布 PUBLISH

Used in MQTT 3.1.1

DUP1

QoS2

QoS2

RETAIN3

发布确认 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

退订 UNSUBSCRI

Reserved

0

0

1

0

退订确认 UNSUBAC

Reserved

0

0

0

0

心跳请求 PINGREQ

Reserved

0

0

0

0

心跳响应 PINGRESP

Reserved

0

0

0

0

断开 DISCONNECT

Reserved

0

0

0

0

  • DUP1 =PUBLISH报文的重发标志

  • QoS2 = PUBLISH报文的服务质量等级

  • RETAIN3 = PUBLISH报文的保留标志

  • 有关PUBLISH控制报文中的DUP,QoS和RETAIN标志的说明,请参见第3.3.1节。

2.2.3 剩余长度 Remaining Length

位置:从第2个字节开始。

剩余长度表示当前数据报文剩余部分的字节数,包括可变报头和有效负载中的数据。剩余长度不包括用于编码剩余长度字段本身的字节数。

剩余长度使用可变长度编码方案进行编码,对于小于128位的值它使用单字节编码。更大的值按下面的方式处理。将每个字节的低7位有效位用于编码数据,最高有效位用于表示还有更多的字节。因此每个字节可以编码128个值和一个连续位continuation bit。剩余长度字段最多可以有4个字节。

非规范性注解 例如,将十进制数64编码为一个字节,十进制数值是64,十六进制为0x40。以最低有效位在前的方式,将十进制数字321(= 65 + 2128 )编码为两个字节,第一个字节是65 + 128 = 193。注意,最高位之1表示至少还有一个后续字节。第二个字节是2。 *非规范性注解 这允许应用最大可以发送268,435,455B(256 MB)的控制报文。这个数值在报文中的表示是:0xFF,0xFF,0xFF,0x7F。 表格 2.4剩余长度字段的大小表示,随着字节数增加,剩余长度所能表示的值的范围。

表格2.4剩余长度字段的大小

字节数Digits

最小值From

最大值To

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)

非规范性注解 使用变长编码方案对非负整数(X)编码的算法如下:

//译者注:这是伪代码实现
do
  encodeByte = X MOD 128 //
  X=X DIV 128
  //如果有更多的数据需要编码,就设置此字节的最高位
  if (X>0)
    encodeByte = encodeByte OR 128
  endif
    `output` encodeByte
while(X>0)

MOD是模运算符(相当于C中的%),DIV是整数除法(相当于C中的/),OR是按位或(相当于C中的|) 非规范性注解 剩余长度字段的解码算法如下:

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

AND是按位和运算符(相当于C语言中的&) 这个算法终止时,值value参数中包含的就是剩余长度的值。

2.3 可变报头 Variable header

某些类型MQTT控制报文中会包含一个可变报头部分。它在固定报头和有效负载之间。可变报头的内容根据报文类型的不同而不同。可变报头的报文标识符Packet Identifier字段存在于在多种类型的报文中。

2.3.1 报文标识符 Packet Identifier

图例2.3-报文标识符字节

位 Bit76543210字节 1 byte 1最高有效字节报文标识符 Packet Identifier MSB字节 2 byte 2最低有效字节报文标识符 Packet Identifier MSB

很多控制报文的可变报头部分会包含一个2字节的报文标识符字段。这些报文是PUBLISH(当QoS>0时)、PUBACKPUBRECPUBRELPUBCOMPSUBSCRIBESUBACKUNSUBSCIBEUNSUBACK

SUBSCRIBE、UNSUBSCRIBE、PUBLISH(当QoS>0时)==控制报文必须包含一个非零的16位报文标识符==[MQTT-2.3.1-1]。==客户端每发送一个新的这些类型的报文时,都必须分配一个当前未使用过的的报文标识符==[MQTT-2.3.1-2]。==如果客户端要重发一个指定的控制报文,那么它必须在重发过程中对该报文使用相同的报文标识符。当客户端处理完与之相匹配的确认报文后,这个报文标识符将释放并可重用。与服务质量等级为QoS1PUBLISHl类型的报文对应的报文标识符是PUBACKQoS 2等级对应的的是PUBCOMP。与SUBSCRIBEUNSUBSCRIBE对应的分别是SUBACKUNSUBACK== [MQTT-2.3.1-3]。==当服务端发送Qos>0的PUBLISH类型报文时,也适用于相同情况== [MQTT-2.3.1-4]。

==QoS 0等级的PUBLISH报文不能包含报文标识符== [MQTT-2.3.1-5]。

==PUBACK, PUBREC, PUBREL报文必须包含与最初发送的PUBLISH报文相同的报文标识符== [MQTT-2.3.1-6]。==类似地,SUBACKUNSUBACK报文必须包含对应的SUBSCRIBEUNSUBSCRIBE报文中使用的报文标识符== [MQTT-2.3.1-7]。

需要报文标识符的控制报文在 表格 2.5 -包含报文标识符的控制报文 中列出。

表格2.5-报文含报文标识符的控制报文

控制报文Control Packet

报文标识符字段Packet Identifier field

CONNECT

不需要

CONNACK

不需要

PUBLISH

需要(如果QoS>0)

PUBACK

需要

PUBREC

需要

PUBREL

需要

PUBCOMP

需要

SUBSCRIBE

需要

SUBACK

需要

UNSUBSCRIBE

需要

UNSUBACK

需要

PINGREQ

不需要

PINGRESP

不需要

DISCONNECT

不需要

客户端和服务端彼此独立地分配报文标识符。因此,客户端服务端使用相同的报文标识符可以实现两端并行的消息交换。

非规范注解 客户端发送标识符为0x1234的PUBLISH报文,它有可能会在收到此PUBLISH报文对应的PUBACK报文之前,先收到服务端发送的另一个标识符也为0x1234的PUBLISH报文,尽管它们是不同的。

Client                     Server
PUBLISH Packet Identifier=0x1234---→
←--PUBLISH Packet Identifier=0x1234
PUBACK Packet Identifier=0x1234---→
←--PUBACK Packet Identifier=0x1234

2.4 有效负载 Payload

正如将在第3章所说的,一些MQTT控制报文会用一个有效负载字段来作为数据报文的最后部分。对于PUBLISH报文来说有效负载就是应用消息。表格2.6 –包含有效负载的控制报文中列出了需要有效负载的控制报文。

表格2.6-包含有效负载的控制报文

控制报文Control Packet

有效负载Payload

CONNECT

需要

CONNACK

不需要

PUBLISH

可选

PUBACK

不需要

PUBREC

不需要

PUBREL

不需要

PUBCOMP

不需要

SUBSCRIBE

需要

SUBACK

需要

UNSUBSCRIBE

需要

UNSUBACK

不需要

PINGREQ

不需要

PINGRESP

不需要

DISCONNECT

不需要

Last updated