小程序
传感搜
传感圈

Introduction to MQTT Control Packets

2023-09-14 20:01:43
关注

Illustration: © IoT For All

MQTT control packets are the smallest unit of data transfer in MQTT. MQTT clients and servers exchange control packets for performing their work, such as subscribing to topics and publishing messages.

Currently, MQTT defines 15 types of control packets. If we classify them based on their functionality, we can categorize these packets into three categories: connection, publishing, and subscribing.

EMQ Technologies

Among them, the CONNECT packet is used by the client to initiate a connection to the server, and the CONNACK packet is sent as a response to indicate the result of the connection. If one wants to terminate the communication or encounters an error that requires terminating the connection, the client and server can send a DISCONNECT packet and then close the network connection.

The AUTH packet is a new type of packet introduced in MQTT 5.0, and it is used solely for enhanced authentication, providing more secure authentication for clients and servers.

The PINGREQ and PINGRESP packets are used for connection keep-alive and probing. The client periodically sends a PINGREQ packet to the server to indicate that it is still active, then judges whether the server is active according to whether the PINGRESP packet is returned in time.

The PUBLISH packet is used to publish messages, and the remaining four packets are used to acknowledge QoS 1 and 2 messages.

The SUBSCRIBE packet is used by the client to subscribe to topics, while the UNSUBSCRIBE packet serves the opposite purpose. The SUBACK and UNSUBACK packets are used to return the results of subscription and unsubscription, respectively.

MQTT Packet Format

In MQTT, regardless of the type of control packet, they all consist of three parts: Fixed Header, Variable Header, and Payload.

The Fixed Header always exists in all control packets. The existence and content of the Variable Header and Payload depend on the specific packet type.

For example, the PINGREQ packet used for keeping alive only includes the Fixed Header, while the PUBLISH packet used for transmitting application messages includes all three parts.

EMQ Technologies

Fixed Header

The Fixed Header consists of three fields: MQTT Control Packet Type, Flags, and Remaining Length.

EMQ Technologies

The MQTT Control Packet Type is located in the high 4 bits of the first byte of the Fixed Header. It is an unsigned integer that represents the type of the current packet.

For example, 1 indicates a CONNECT packet, 2 indicates a CONNACK packet, and so on. The detailed mapping can be found in the MQTT 5.0 specification – MQTT Control Packet Types.

In fact, except for the MQTT Control Packet Type and Remaining Length fields, the content of the remaining part of the MQTT packet depends on the specific packet type. So, this field determines how the receiver should parse the following content of the packet.

The remaining low 4 bits in the first byte of the Fixed Header contain flags determined by the control packet type. However, as of MQTT 5.0, only the four bits in the PUBLISH packet have been assigned specific meanings:

  • Bit 3: DUP, indicates whether the current PUBLISH packet is a retransmitted packet.
  • Bit 2,1QoS, indicates the quality-of-service level used by the current PUBLISH packet.
  • Bit 0: Retain, indicates whether the current PUBLISH packet is retained.

In all other packet types, these 4 bits remain reserved, meaning they have a fixed value that cannot be arbitrarily changed.

The final Remaining Length field indicates the number of bytes in the remaining part of the control packet, which includes the Variable Header and the Payload. Therefore, an MQTT control packet’s total length is equal to the Fixed Header’s length plus the Remaining Length.

EMQ Technologies

Variable Byte Integer

However, the length of the Fixed Header is not fixed. In order to minimize the packet size as much as possible, MQTT uses the Remaining Length field as a variable byte integer.

In MQTT, there are many fields of variable length. For example, the Payload part in the PUBLISH packet is used to carry the actual application message, and the length of the application message is not fixed. So, we need an additional field to indicate the length of these variable-length contents so that the receiving end can parse them correctly.

For a 2 MB application message, which is a total of 2,097,152 bytes, we would need a 4-byte integer to indicate its length. However, not all application messages are that large; in many cases, they are only a few KB or even just a few bytes. Using a 4-byte integer to indicate a message length of only 2 bytes would be excessive.

Therefore, MQTT introduces variable byte integers, which utilize the lower 7 bits of each byte to encode data, while the highest bit indicates whether there are more bytes to follow.

This way, when the packet length is less than 128 bytes, the variable byte integer only needs one byte to indicate. The maximum length of a variable byte integer is 4 bytes, allowing it to indicate a length of up to (2^28 – 1) bytes, which is 256 MB of data.

EMQ Technologies

Variable Header

The contents of the Variable Header in MQTT depend on the specific packet type. For example, the Variable Header of the CONNECT packet includes the Protocol Name, Protocol Level, Connect Flags, Keep Alive, and Properties in that order.

The Variable Header of a PUBLISH packet includes the Topic name, Packet Identifier (if QoS is not 0), and Properties in that order.

EMQ Technologies

The fields in the Variable Header must strictly follow the protocol specification because the receiver will only parse them in the specified order. We cannot omit any field unless the protocol explicitly requires or allows it.

For example, in the Variable Header of the CONNECT packet, if the Connect Flags are placed directly after the Protocol Name, it would result in a parsing failure. Similarly, in the Variable Header of the PUBLISH packet, the packet identifier is only present when QoS is not 0.

Properties

Properties are a concept introduced in MQTT 5.0. They are the last part of the Variable Header. The properties consist of the Property Length field followed by a set of properties. The Property Length indicates the total length of all the properties that follow.

EMQ Technologies

All properties are optional, as they usually have a default value. If there is no property, then the value of the Property Length is 0.

Each property consists of an identifier that defines the purpose and data type of the property and a specific value. Different properties may have different data types.

For example, one is a two-byte integer, and another is a UTF-8 encoded string, so we need to parse the properties according to the data type declared by their identifiers.

EMQ Technologies

The order of properties can be arbitrary because we can know which property it is and its length based on the Identifier.

Properties are typically designed for specific purposes. For example, the CONNECT packet has a Session Expiry Interval property to set the session’s expiration time.

However, this property is not needed in a PUBLISH packet. Therefore, MQTT strictly defines the usage scope of properties, and a valid MQTT control packet should not contain properties that do not belong to it.

For a comprehensive list of MQTT properties, including their identifiers, property names, data types, and usage scopes, please refer to MQTT 5.0 Specification – Properties.

Payload

Lastly, we have the Payload. The Variable Header of the packet can be seen as its supplementary information, while the Payload is used to achieve the core purpose of the packet.

For example, in the PUBLISH packet, the Payload is used to carry the actual application message, which is the primary function of the PUBLISH packet. The QoS, Retain, and other fields in the Variable Header of the PUBLISH packet provide additional capabilities related to the application message.

The SUBSCRIBE packet follows a similar pattern. The Payload contains the topics to subscribe to and their corresponding subscription options, which is the primary task of the SUBSCRIBE packet.

Tweet

Share

Share

Email

  • Data Analytics
  • MQTT
  • Network and Protocols

  • Data Analytics
  • MQTT
  • Network and Protocols

参考译文
MQTT 控制报文简介
插图:© IoT For All --> MQTT 控制数据包是 MQTT 中数据传输的最小单位。MQTT 客户端和服务器通过交换控制数据包来执行各种任务,例如订阅主题和发布消息。目前,MQTT 定义了 15 种类型的控制数据包。如果我们根据其功能对它们进行分类,可以将这些数据包分为三类:连接、发布和订阅。EMQ Technologies 其中,CONNECT 数据包用于客户端发起与服务器的连接,CONNACK 数据包作为响应,用于指示连接结果。如果希望终止通信或遇到需要断开连接的错误,客户端和服务器可以发送 DISCONNECT 数据包,然后关闭网络连接。AUTH 数据包是 MQTT 5.0 引入的新类型数据包,专门用于增强认证,为客户端和服务器提供更安全的认证方式。PINGREQ 和 PINGRESP 数据包用于连接保活和探测。客户端定期发送 PINGREQ 数据包到服务器,表示自己仍然活跃,并根据服务器是否及时返回 PINGRESP 数据包判断服务器是否活跃。PUBLISH 数据包用于发布消息,其余四个数据包用于确认 QoS 1 和 QoS 2 消息。SUBSCRIBE 数据包用于客户端订阅主题,UNSUBSCRIBE 数据包则用于取消订阅。SUBACK 和 UNSUBACK 数据包分别用于返回订阅和取消订阅的结果。MQTT 数据包格式 在 MQTT 中,无论控制数据包的类型如何,它们都由三个部分组成:固定头(Fixed Header)、可变头(Variable Header)和负载(Payload)。固定头在所有控制数据包中始终存在。可变头和负载的存在与否及其内容则取决于具体的数据包类型。例如,用于保活的 PINGREQ 数据包仅包含固定头,而用于传输应用消息的 PUBLISH 数据包则包含全部三个部分。EMQ Technologies 固定头 固定头由三个字段组成:MQTT 控制数据包类型、标志(Flags)和剩余长度(Remaining Length)。EMQ Technologies MQTT 控制数据包类型位于固定头第一个字节的高 4 位中。它是一个无符号整数,表示当前数据包的类型。例如,1 表示 CONNECT 数据包,2 表示 CONNACK 数据包,依此类推。详细的映射关系可以参考《MQTT 5.0 规范 – MQTT 控制数据包类型》。实际上,除了 MQTT 控制数据包类型和剩余长度字段外,其余部分的内容取决于具体的包类型。因此,该字段决定了接收方如何解析数据包的后续内容。固定头第一个字节的低 4 位包含由控制数据包类型决定的标志位。然而,截至 MQTT 5.0,只有 PUBLISH 数据包中的这四个位具有特定含义:第 3 位:DUP,表示当前的 PUBLISH 数据包是否为重传数据包。第 2、1 位 QoS,表示当前的 PUBLISH 数据包所使用的服务质量等级。第 0 位:Retain,表示当前的 PUBLISH 数据包是否为保留消息。在所有其他数据包类型中,这 4 位是预留的,意味着它们具有固定值,不能随意更改。最后的剩余长度字段表示控制数据包剩余部分的字节数,其中包括可变头和负载。因此,MQTT 控制数据包的总长度等于固定头的长度加上剩余长度。EMQ Technologies 可变字节整数 然而,固定头的长度并不是固定的。为了尽可能减小数据包的大小,MQTT 使用剩余长度字段作为可变字节整数。在 MQTT 中,有很多字段的长度是可变的。例如,PUBLISH 数据包中的负载部分用于承载实际的应用消息,而应用消息的长度并不固定。因此,我们需要一个额外字段来指示这些可变长度内容的长度,以便接收端能够正确解析它们。对于一个总长度为 2,097,152 字节(即 2MB)的应用消息,我们需要一个 4 字节的整数来指示其长度。然而,并非所有应用消息都如此庞大;在许多情况下,它们仅是几 KB,甚至只有几个字节。用 4 字节的整数来指示一个长度仅为 2 字节的消息显然过于浪费。因此,MQTT 引入了可变字节整数,利用每个字节的低 7 位来编码数据,而最高位则指示是否还有后续字节。这样一来,当数据包长度小于 128 字节时,可变字节整数只需要一个字节即可表示。可变字节整数的最大长度为 4 字节,可以表示最多 (2^28 – 1) 字节,即 256MB 的数据。EMQ Technologies 可变头 MQTT 中的可变头内容取决于具体的包类型。例如,CONNECT 数据包的可变头依次包括协议名称、协议级别、连接标志、保活时间和属性。PUBLISH 数据包的可变头依次包括主题名、包标识符(如果 QoS 不为 0)和属性。EMQ Technologies 可变头中的字段必须严格按照协议规范排列,因为接收方只能按照指定的顺序解析它们。除非协议明确要求或允许,否则不能省略任何字段。例如,在 CONNECT 数据包的可变头中,若连接标志紧跟在协议名称之后,会导致解析失败。同样,在 PUBLISH 数据包的可变头中,只有在 QoS 不为 0 时,包标识符才会出现。属性 属性是 MQTT 5.0 引入的一个概念,是可变头的最后部分。属性由属性长度字段后接一组属性组成。属性长度字段用于指示后续所有属性的总长度。EMQ Technologies 所有属性都是可选的,因为它们通常具有默认值。如果没有属性,则属性长度字段的值为 0。每个属性由一个定义其用途和数据类型的标识符和一个具体值组成。不同的属性可能有不同的数据类型。例如,一个是两字节的整数,另一个是 UTF-8 编码的字符串,因此我们需要根据标识符声明的数据类型来解析属性。EMQ Technologies 属性的顺序可以是任意的,因为我们可以通过标识符知道属性的种类及其长度。属性通常是为了特定用途设计的。例如,CONNECT 数据包有一个 Session Expiry Interval 属性,用于设置会话的过期时间。然而,这个属性在 PUBLISH 数据包中并不需要。因此,MQTT 对属性的使用范围有严格定义,有效的 MQTT 控制数据包不应包含不属于它的属性。关于 MQTT 属性的完整列表,包括其标识符、属性名称、数据类型和使用范围,请参考《MQTT 5.0 规范 – 属性》。负载 最后,我们来看负载部分。数据包的可变头可以看作是其附加信息,而负载则用于实现数据包的核心功能。例如,在 PUBLISH 数据包中,负载用于承载实际的应用消息,这是 PUBLISH 数据包的主要功能。PUBLISH 数据包的可变头中的 QoS、Retain 等字段提供了与应用消息相关的附加功能。SUBSCRIBE 数据包遵循类似的模式。负载部分包含要订阅的主题及其对应的订阅选项,这是 SUBSCRIBE 数据包的主要任务。TweetShareShareEmail 数据分析 MQTT 网络与协议 --> 数据分析 MQTT 网络与协议
您觉得本篇内容如何
评分

相关产品

Tengrui 腾锐视讯 R-NB60-A 数据采集仪

锐TR-NB60-A NB-IoT终端是一种物联网无线数据终端,利用公用NB-IoT网络为用户提供无线长距离数据传输功能。该产品采用高性能的工业级32位通信处理器和工业级NB-IoT模块,以嵌入式实时操作系统为软件支撑平台,提供RS232、RS485、CAN接口,可直接连接串口设备,实现数据透明传输功能;低功耗设计;符合中国移动、联通、电信等蜂窝物联网通用模组技术规范,支持LWM2M、MQTT等主流通信协议,支持固件本地升级和定制远程升级,提供丰富的外部接口和协议栈。产品已广泛应用于物联网产业链中的M2M行业,如无线抄表、智慧城市、智能电网、智慧交通、消防、资产追踪、移动POS终端、物流、工业自动化、数字化医疗、军事、农业、林业、水务、煤矿、石化等数据传输领域。

评论

您需要登录才可以回复|注册

提交评论

广告
提取码
复制提取码
点击跳转至百度网盘