Introduction
MQTT (Message Queuing Telemetry Transport) is a lightweight messaging protocol widely used in the Internet of Things (IoT), mobile applications, and other fields. It is based on a publish/subscribe model, providing an efficient messaging mechanism. This article will provide a detailed analysis of the fixed header, variable header, and payload in the MQTT protocol, helping readers gain a deeper understanding of how MQTT works.
Fixed Header
Message Type
Located in bits 7-4 of byte 1, this indicates the type of MQTT message, which includes the following types:
Name | Value | Message Flow Direction | Description |
---|---|---|---|
Reserved | 0 | Prohibited | Reserved bit |
CONNECT | 1 | Client to Server | Client requests to connect to the server |
CONNACK | 2 | Server to Client | Connection acknowledgment |
PUBLISH | 3 | Bidirectional | Publish message |
PUBACK | 4 | Bidirectional | Publish acknowledgment |
PUBREC | 5 | Bidirectional | Publish received (ensures part 1 arrives) |
PUBREL | 6 | Bidirectional | Publish release (ensures part 2 arrives) |
PUBCOMP | 7 | Bidirectional | Publish complete (ensures part 3 arrives) |
SUBSCRIBE | 8 | Client to Server | Client requests to subscribe |
SUBACK | 9 | Server to Client | Subscription acknowledgment |
UNSUBSCRIBE | 10 | Client to Server | Request to unsubscribe |
UNSUBACK | 11 | Server to Client | Unsubscription acknowledgment |
PINGREQ | 12 | Client to Server | Heartbeat request |
PINGRESP | 13 | Server to Client | Heartbeat response |
DISCONNECT | 14 | Client to Server | Disconnect |
Reserved | 15 | Prohibited | Reserved bit |
Flags (DUP, QoS Level, RET)
Located in bits 3-0 of byte 1, this indicates the grouping class identifier of the MQTT message. In message types that do not use flags, the flags are treated as reserved bits. If an invalid flag is received, the receiver must close the network connection.
- DUP: Duplicate of the published message
- QoS: Quality of Service for the published message
- RETAIN: Retain flag for the published message
Control Message | Fixed Header Flags | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
---|---|---|---|---|---|
CONNECT | Reserved bit | 0 | 0 | 0 | 0 |
CONNACK | Reserved bit | 0 | 0 | 0 | 0 |
PUBLISH | Used in MQTT 3.1.1 | DUP1 | QoS2 | QoS2 | RETAIN3 |
PUBACK | Reserved bit | 0 | 0 | 0 | 0 |
PUBREC | Reserved bit | 0 | 0 | 0 | 0 |
PUBREL | Reserved bit | 0 | 0 | 1 | 0 |
PUBCOMP | Reserved bit | 0 | 0 | 0 | 0 |
SUBSCRIBE | Reserved bit | 0 | 0 | 1 | 0 |
SUBACK | Reserved bit | 0 | 0 | 0 | 0 |
UNSUBSCRIBE | Reserved bit | 0 | 0 | 1 | 0 |
UNSUBACK | Reserved bit | 0 | 0 | 0 | 0 |
PINGREQ | Reserved bit | 0 | 0 | 0 | 0 |
PINGRESP | Reserved bit | 0 | 0 | 0 | 0 |
DISCONNECT | Reserved bit | 0 | 0 | 0 | 0 |
Remaining Length
Located in bits 3-0 of byte 2, this indicates the current remaining byte count, including the variable header and payload data. The remaining length does not include the bytes used for encoding the remaining length field itself.
Fixed header:
0x10 for Client to Server
Variable Header
Some MQTT messages have a variable header. It is located between the fixed header and the payload. The content of the variable header varies depending on the message type. The variable header’s message identifier field exists in multiple types of messages.
The variable header consists of four parts: protocol name, protocol level, connection flags, and keep-alive. It is essentially 10 bytes.
Taking the CONNECT message as an example:
Protocol Name
Consists of 6 bytes, representing the UTF-8 encoded string of the protocol name MQTT, structured as shown in the following diagram.
Byte 1 and byte 2 indicate the length of the data following the protocol name, which is fixed at 4 bits. Therefore, byte 1 holds 00, and byte 4 holds 04.
Bytes 3-6 are fixed as M Q T T, with each byte representing a character, corresponding to 4D 51 54 54.
Thus, the protocol name in hexadecimal is 00 04 4D 51 54 54.
Protocol Level
Consists of only 1 byte, with the value for the MQTT 3.1.1 protocol level being 4, structured as shown in the following diagram, converted to hexadecimal as 04.
Connection Flags
Also consists of 1 byte, containing parameters that specify MQTT connection behavior and indicate whether fields in the payload exist. The structure is shown in the following diagram, where × indicates that it is not fixed and can be either 0 or 1, but the reserved bit (Reserved) must be 0.
Bits 0 to 7 represent the reserved bit (Reserved), clean session (Clean Session), will flag (Will Flag), will QoS (Will QoS), will retain (Will Retain), password flag (Password Flag), and username flag (User Name Flag). A bit set to 1 indicates presence, while 0 indicates absence.
Careful readers will notice that the will QoS (Will QoS) occupies two bits; this is because the quality of service level has three levels, and we need two bits to express it in binary. If it is 00, then QoS = 0; if it is 01, then QoS = 1; if it is 10, then QoS = 2.
Assuming the connection flags include the username flag (User Name Flag), password flag (Password Flag), and clean session (Clean Session), the binary representation of the connection flags would be 11000010, converted to hexadecimal as C2.
Commonly used 7, 6, 1
Keep Alive
Consists of 2 bytes, representing a time interval in seconds, indicated as a 16-bit number. It specifies the maximum allowed idle time between the moment the client completes sending a control message and the moment it sends the next message.
Assuming the maximum idle time is 100 seconds, the structure is shown in the following diagram, converted to hexadecimal as 00 64.
We have just provided examples of the protocol name, protocol level, connection flags, and keep-alive using the variable header of the CONNECT message, writing them in hexadecimal. We combine these hexadecimal numbers in order, resulting in the variable header of the CONNECT message being: 00 04 4D 51 54 54 04 C2 00 64.
Payload
The payload is the application message. Some MQTT messages have a payload, which contains one or more fields with a length prefix. The flags in the variable header determine whether these fields are included (the requirement for fields to have a length prefix is due to the UTF-8 encoding format, which features a two-byte length as a prefix).
Taking the CONNECT message as an example:Payload = Device ID + Product ID + Token. The Device ID, Product ID, and Token are parameters used for server-client integration in the MQTT protocol, and all are essential.
Are the Device ID and Product ID familiar? They are our “MQTT triplet,” pulling out the parameters we just saved.
- Device ID: DHT11_01
00 08 44 48 54 31 31 5F 30 31
- Product ID: lafJJm0lSy
00 0A 6C 61 66 4A 4A 6D 30 6C 53 79
- Device Key: ajdTSTBScE1iQlhZZ1RWbXRGbXNDazNMbnBJQWFPdEY=
Using the token tool, generate the encrypted key
The introduction of each parameter is shown in the table below:
Name | Type | Parameter Description | Parameter Example |
---|---|---|---|
res | string | Access resource format: products/{product_id}/devices/{device_name} | products/lafJJm0lSy/devices/DHT11_01 |
et | int | Access expiration time, in seconds, unix time. When the et time in an access parameter is less than the current time, the platform will consider the access parameter expired and reject the access. | 2017881776 indicates: Beijing time 2033-12-11 10:42:56 |
key | string | Device key of the MQTT triplet | ajdTSTBScE1iQlhZZ1RWbXRGbXNDazNMbnBJQWFPdEY= |
method | string | Encryption method, supports hmacmd5, hmacsha1, hmacsha256 | md5 (represents using hmacmd5 algorithm) sha1 (represents using hmacsha1 algorithm) sha256 (represents using hmacsha256 algorithm) |
version | string | Parameter group version number, date format, currently only supports “2018-10-31” | 2018-10-31 |
Generated token:
version=2018-10-31&res=products%2FlafJJm0lSy%2Fdevices%2FDHT11_01&et=2017881776&method=sha1&sign=GxPTQJKu9gV44ozeH%2F8sy%2BXWWg0%3D
version=2018-10-31&res=products%2FlafJJm0lSy%2Fdevices%2FDHT11_01&et=2017881776 &method=sha1&sign=GxPTQJKu9gV44ozeH%2F8sy%2BXWWg0%3D
76 657273696F6E 3D 323031382D 31302D 3331267265733D 70726F64756374732532466C 61664A 4A 6D 306C 53792532466465766963657325324644485431315F30312665743D 32303137383831373736266D 6574686F643D 73686131267369676E 3D 47785054514A 4B 7539675634346F7A 65482532463873792532425857576730253344
00 8376657273696F6E 3D 323031382D 31302D 3331267265733D 70726F64756374732532466C 61664A 4A 6D 306C 53792532466465766963657325324644485431315F30312665743D 32303137383831373736266D 6574686F643D 73686131267369676E 3D 47785054514A 4B 7539675634346F7A 65482532463873792532425857576730253344
Payload = Device ID + Product ID + Token
00 08 44 48 54 31 31 5F 30 31 00 0A 6C 61 66 4A 4A 6D 30 6C 53 79 00 83 76 65 72 73 69 6F 6E 3D 32 30 31 38 2D 31 30 2D 333126 7265733D 70726F64756374732532466C 61664A 4A 6D 306C 53792532466465766963657325324644485431315F30312665743D 32303137383831373736266D 6574686F643D 73686131267369676E 3D 47785054514A 4B 7539675634346F7A 65482532463873792532425857576730253344
Final Message
Fixed Header + Variable Header + Payload
10 90 01 **00 04 4D 51 54 54 04 C2 00 64 **00 08 44 48 54 31 31 5F 30 31 00 0A 6C 61 66 4A 4A 6D 30 6C 53 79 00 84 76 65 72 73 69 6F 6E 3D 32 30 31 38 2D 31 30 2D 333126 7265733D 70726F64756374732532466C 61664A 4A 6D 306C 53792532466465766963657325324644485431315F30312665743D 32303137383831373736266D 6574686F643D 73686131267369676E 3D 47785054514A 4B 7539675634346F7A 65482532463873792532425857576730253344
10 A5 0100044D 51545404 C2 0064000844485431315F3031000A 6C 61664A 4A 6D 306C 5379008376657273696F6E 3D 323031382D 31302D 3331267265733D 70726F64756374732532466C 61664A 4A 6D 306C 53792532466465766963657325324644485431315F30312665743D 32303137383831373736266D 6574686F643D 73686131267369676E 3D 47785054514A 4B 7539675634346F7A 65482532463873792532425857576730253344
Conclusion
This article provides a detailed analysis of the fixed header, variable header, and payload of the MQTT protocol, helping readers gain a deeper understanding of how MQTT works. In practical applications, selecting the appropriate message type and parameter configuration based on specific needs can achieve efficient message transmission and communication between IoT devices.