2.1 MQTT control packet structure
MQTT work protocol defined by a series of exchange of control packets MQTT. This section describes the format of these packets.
MQTT up control packet consists of three parts, the following sequence is always composed, as shown in Figure 2.1 - MQTT control package structure .
FIG. 2.1 - MQTT control packet structure
Fixed header, is present in all control packets MQTT |
Variable head, present in some of the control packets MQTT |
Payload, the control data present in certain packet MQTT |
2.2 Fixed title
MQTT Each packet contains a fixed control head. FIG 2.2- fixed header format described fixed header format.
Figure 2.2 - Fixed Header Format
Place |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Byte 1 |
MQTT control packet types |
MQTT specific to each type of the control packet flag |
||||||
Byte 2 ... |
The remaining length |
2.2.1 MQTT control packet types
Location: byte 1, bits 7-4.
Represents a 4-bit unsigned value, values are listed in Table 2.1 - control packet types .
Table 2.1 - control packet type
name |
value |
Flow direction |
description |
|
Reserved | 0 |
Prohibited |
reserved |
|
CONNECT |
1 |
Client-server |
Client requests the server to connect to |
|
CONNACK |
2 |
Server to the client |
Connection confirmation |
|
PUBLISH |
3 |
Client-server or Server to the client |
make an announcement |
|
PUBACK |
4 |
Client-server or Server to the client |
Published confirmation |
|
PUBREC |
Fives |
Client-server or Server to the client |
You receive a publication (guaranteed delivery Part 1) |
|
PUBREL |
6 |
Client-server or Server to the client |
Were released (guaranteed delivery Part 2) |
|
PUBCOMP |
7 |
Client-server or Server to the client |
Release complete (guaranteed delivery Part 3) |
|
SUBSCRIBE | 8 |
Client-server |
Client subscription request |
|
SUBACK |
9 |
Server to the client |
Subscription Confirmation |
|
UNSUBSCRIBE | 10 |
Client-server |
Unsubscribe request |
|
UNSUBACK |
11 |
Server to the client |
Unsubscribe confirmation |
|
PINGREQ |
12 |
Client-server |
PING requests |
|
PINGRESP |
13 |
Server to the client |
PING response |
|
DISCONNECT |
14 |
Client-server |
The client tells the server to disconnect and elegant |
|
Reserved | 15 |
Prohibited |
reserved |
|
2.2.2 Flags Flag
固定报头中字节1的其余位[3-0]包含特定于每个MQTT控制包类型的标志,如下面的表2.2-标志位所列。如果标志位在表2.2中标记为“保留” - 标志位,则保留供将来使用,并且必须设置为该表 [MQTT-2.2.2-1]中列出的值。如果收到无效标志,接收方必须关闭网络连接[MQTT-2.2.2-2] 。有关处理错误的详细信息,请参见第4.8 节
控制包 |
固定标头标志 |
第3位 |
第2位 |
第1位 |
位0 |
CONNECT |
保留的 |
0 |
0 |
0 |
0 |
CONNACK |
保留的 |
0 |
0 |
0 |
0 |
PUBLISH |
用于MQTT 3.1.1 |
DUP 1 |
QoS 2 |
QoS 2 |
保留3 |
PUBACK |
保留的 |
0 |
0 |
0 |
0 |
PUBREC |
保留的 |
0 |
0 |
0 |
0 |
PUBREL |
保留的 |
0 |
0 |
1 |
0 |
PUBCOMP |
保留的 |
0 |
0 |
0 |
0 |
SUBSCRIBE | 保留的 |
0 |
0 |
1 |
0 |
SUBACK |
保留的 |
0 |
0 |
0 |
0 |
UNSUBSCRIBE | 保留的 |
0 |
0 |
1 |
0 |
UNSUBACK |
保留的 |
0 |
0 |
0 |
0 |
PINGREQ |
保留的 |
0 |
0 |
0 |
0 |
PINGRESP |
保留的 |
0 |
0 |
0 |
0 |
DISCONNECT | 保留的 |
0 |
0 |
0 |
0 |
DUP 1 =重复发送发布控制包
QoS 2 =发布服务质量
RETAIN 3 = 发布保留标志
有关PUBLISH控制包中DUP,QoS和RETAIN标志的说明,请参见第3.3.1节。
2.2.3 Remaining Length 剩余长度
位置:从字节2开始。
剩余长度是当前数据包中剩余的字节数,包括变量头和有效负载中的数据。剩余长度不包括用于编码剩余长度的字节。
剩余长度使用可变长度编码方案进行编码,该方案使用单个字节用于最多127的值。较大的值按如下方式处理。每个字节的最低有效7位对数据进行编码,最高有效位用于指示表示中有后续字节。因此,每个字节编码128个值和“连续位”。“剩余长度”字段中的最大字节数为四。
非规范性评论
例如,64位十进制编码为单字节,十进制值64,十六进制0x40。数字321十进制(= 65 + 2 * 128)被编码为两个字节,最不重要的是第一个。第一个字节是65 + 128 = 193.注意,最高位设置为至少指示一个后续字节。第二个字节是2。
非规范性评论
这允许应用程序发送大小高达268,435,455(256 MB)的控制数据包。这个数字在线上的表示是:0xFF,0xFF,0xFF,0x7F。
表2.4显示了由增加的字节数表示的剩余长度值。
数字 |
从 |
至 |
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 283
encodedByte = X MOD 128 284
X = X DIV 128 285
// if there are more data to encode, set the top bit of this byte 286
if ( X > 0 ) 287
encodedByte = encodedByte OR 128 288
endif 289
'output' encodedByte 290
while ( X > 0 )
其中MOD是模运算符(C中的%),DIV 是整数除法(/在C中),OR是按位或(|在C中)。
非规范性评论
解码剩余长度字段的算法如下:
multiplier = 1 299
value = 0 300
do 301
encodedByte = 'next byte from stream' 302
value += (encodedByte AND 127) * multiplier 303
multiplier *= 128 304
if (multiplier > 128*128*128) 305
throw Error(Malformed Remaining Length) 306
while ((encodedByte AND 128) != 0)
其中AND是按位和运算符(& in C)。
当此算法终止时,value包含Remaining Length值。
2.3 Variable header 变量头
某些类型的MQTT控制数据包包含可变标头组件。它位于固定标头和有效负载之间。变量头的内容根据数据包类型而有所不同。变量头的包标识符字段在几种包类型中是通用的。
2.3.1包标识符
位 |
7 |
6 |
五 |
4 |
3 |
2 |
1 |
0 |
字节1 |
包标识符MSB |
|||||||
字节2 |
包标识符LSB |
许多控制分组类型的可变报头组件包括2字节分组标识符字段。这些控制数据包是PUBLISH(其中QoS> 0),PUBACK,PUBREC,PUBREL,PUBCOMP,SUBSCRIBE,SUBACK,UNSUBSCRIBE,UNSUBACK。
SUBSCRIBE,UNSUBSCRIBE和PUBLISH(在QoS> 0的情况下)控制数据包必须包含非零的16位数据包标识符 [MQTT-2.3.1-1]。每次客户端发送这些类型之一的新数据包时,它必须为其分配当前未使用的数据包标识符 [MQTT-2.3.1-2]。如果客户端重新发送特定的控制数据包,那么它必须在后续重新发送该数据包时使用相同的数据包标识符。客户端处理完相应的确认数据包后,数据包标识符可以重用。在QoS 1 PUBLISH的情况下,这是相应的PUBACK; 在QoS 2的情况下,它是PUBCOMP。对于SUBSCRIBE或UNSUBSCRIBE,它是相应的SUBACK或UNSUBACK [MQTT-2.3.1-3]。 当服务器发送QoS> 0 [MQTT-2.3.1-4] 的PUBLISH时,相同的条件适用于服务器。
如果其QoS值设置为0,则PUBLISH数据包 不得包含数据包标识符[MQTT-2.3.1-5]。
PUBACK,PUBREC或PUBREL数据包必须包含与最初发送的PUBLISH数据包相同的数据包标识符 [MQTT-2.3.1-6]。类似地,SUBACK和UNSUBACK必须包含分别在相应的SUBSCRIBE和UNSUBSCRIBE数据包中使用的数据包标识符 [MQTT-2.3.1-7]。
表2.5 - 包含数据包标识符的控制数据包中列出了需要数据包标识符的控制数据包。
控制包 |
数据包标识符字段 |
CONNECT |
没有 |
CONNACK |
没有 |
PUBLISH | 是(如果QoS> 0) |
PUBACK |
是 |
PUBREC |
是 |
PUBREL |
是 |
PUBCOMP |
是 |
SUBSCRIBE | |
SUBACK |
是 |
UNSUBSCRIBE | 是 |
UNSUBACK |
是 |
PINGREQ |
没有 |
PINGRESP |
没有 |
DISCONNECT | 没有 |
客户端和服务器彼此独立地分配数据包标识符。因此,客户端服务器对可以使用相同的数据包标识符参与并发消息交换。
非规范性评论
客户端可以发送带有数据包标识符0x1234的PUBLISH数据包,然后在收到其发送的PUBLISH的PUBACK之前,从其服务器接收带有数据包标识符0x1234的不同PUBLISH。
客户端服务器
PUBLISH Packet Identifier = 0x1234 --- à
ß -发布数据包标识符= 0x1234
PUBACK数据包标识符= 0x1234 --- à
ß-- PUBACK数据包标识符= 0x1234
2.4 Payload 有效载荷
某些MQTT控制数据包包含有效负载作为数据包的最后部分,如第3章所述。在PUBLISH数据包的情况下,这是应用程序消息。表2.6 - 包含有效负载的控制数据包列出了需要有效负载的控制数据包。
控制包 |
有效载荷 |
CONNECT |
需要 |
CONNACK |
没有 |
PUBLISH | 可选的 |
PUBACK |
没有 |
PUBREC |
没有 |
PUBREL |
没有 |
PUBCOMP |
没有 |
SUBSCRIBE | 需要 |
SUBACK |
需要 |
UNSUBSCRIBE | 需要 |
UNSUBACK |
没有 |
PINGREQ |
没有 |
PINGRESP |
没有 |
DISCONNECT | 没有 |
里面可能有些google翻译不准的地方请大家多多指正!