第九章 MQTT报文

系列文章目录

第一章 总体概述
第二章 在实体机上安装ubuntu
第三章 Windows远程连接ubuntu
第四章 使用Docker安装和运行EMQX
第五章 Docker卸载EMQX
第六章 EMQX客户端MQTTX Desktop的安装与使用
第七章 EMQX客户端MQTTX CLI的安装与使用
第八章 Wireshark工具的安装与使用
第九章 MQTT报文



前言

在 MQTT 中,无论是什么类型的控制报文,它们都由固定报头、可变报头和有效载荷三个部分组成。

固定报头固定存在于所有控制报文中而可变报头和有效载荷是否存在以及它们的内容则取决于具体的报文类型。例如用于维持连接的 PINGREQ 报文就只有一个固定报头,用于传递应用消息的 PUBLISH 报文则完整地包含了这三个部分。
在这里插入图片描述


一、固定报头

固定报头由报文类型、标识位和报文剩余长度三个字段组成。
在这里插入图片描述
报文类型 :占4个bit位,是一个无符号的整数

常见的报文类型:https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901022

标识位:占4个bit位,不过到 MQTT 5.0 为止,只有 PUBLISH 报文的这四个比特位被赋予了明确的含义:

1、Bit 3:DUP,表示当前 PUBLISH 报文是否是一个重传的报文。

2、Bit 2,1:QoS,表示当前 PUBLISH 报文使用的服务质量等级。

3、Bit 0:Retain,表示当前 PUBLISH 报文是否是一个保留消息。

其他所有的报文中,这 4 位都仍是保留的。

剩余长度:剩余长度指示了当前控制报文剩余部分的字节数,也就是可变报头和有效载荷这两个部分的长度。MQTT 控制报文的总长度= 固定报头的长度 + 剩余长度。
在这里插入图片描述


二、可变报头

可变报头的内容取决于具体的报文类型。

举例:

1、CONNECT 报文的可变报头按顺序包含了协议名、协议级别、连接标识、Keep Alive 和属性这五个字段

2、PUBLISH 报文的可变报头则按顺序包含了主题名、报文标识符和属性这三个字段。
在这里插入图片描述
属性是 MQTT 5.0 引入的一个概念。属性字段基本上都是可变报头的最后一部分,由属性长度和紧随其后的一组属性组成,这里的属性长度指的是后面所有属性的总长度
在这里插入图片描述
所有的属性都是可选的,因为它们通常都有一个默认值,如果没有任何属性,那么属性长度的值就为0。属性通常都是为了某个专门的用途而设计的,不同的报文所支持的属性都是不一样的,具体的对应情况可以查看官网地址:https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901027


三、有效载荷

有效载荷是用于实现对应报文的核心功能。

举例:

1、在 PUBLISH 报文中,Payload 用于承载具体的应用消息内容,这也是 PUBLISH 报文最核心的功能。

2、在 SUBSCRIBE 报文中,Payload 包含了想要订阅的主题以及对应的订阅选项,这也是 SUBSCRIBE 报文最主要的工作。


总结

以上,就是MQTT协议报文的简单介绍。

MQTT协议中,**报文类型(Packet Type)**通过控制报文的首字节(`Control Packet Type`字段)的高4位标识,低4位为标志位(Flags)。以下是MQTT 3.1.1和5.0协议中定义的**标准报文类型枚举**及其用途: --- ### **1. MQTT 3.1.1 报文类型枚举** | 十进制值 | 二进制(高4位) | 报文名称 | 方向(C→S/S→C/双向) | 用途说明 | |----------|------------------|-------------------|----------------------|--------------------------------------------------------------------------| | 1 | `0001` | CONNECT | C→S | 客户端发起连接请求,包含客户端ID、用户名、密码等。 | | 2 | `0010` | CONNACK | S→C | 服务器响应连接请求,返回成功或错误码(如协议版本不兼容)。 | | 3 | `0011` | PUBLISH | 双向 | 发布消息到主题,QoS级别决定是否需要确认(PUBACK/PUBREC等)。 | | 4 | `0100` | PUBACK | 双向 | QoS1消息的确认响应。 | | 5 | `0101` | PUBREC | 双向 | QoS2消息的第一阶段确认(接收方收到PUBLISH后回复)。 | | 6 | `0110` | PUBREL | 双向 | QoS2消息的第二阶段确认(发送方收到PUBREC后回复)。 | | 7 | `0111` | PUBCOMP | 双向 | QoS2消息的完成确认(接收方收到PUBREL后回复)。 | | 8 | `1000` | SUBSCRIBE | C→S | 客户端订阅一个或多个主题,包含QoS级别。 | | 9 | `1001` | SUBACK | S→C | 服务器响应订阅请求,返回每个主题的授权QoS。 | | 10 | `1010` | UNSUBSCRIBE | C→S | 客户端取消订阅一个或多个主题。 | | 11 | `1011` | UNSUBACK | S→C | 服务器确认取消订阅请求。 | | 12 | `1100` | PINGREQ | C→S | 客户端保活请求,检测连接是否存活。 | | 13 | `1101` | PINGRESP | S→C | 服务器响应保活请求。 | | 14 | `1110` | DISCONNECT | C→S | 客户端主动断开连接。 | --- ### **2. MQTT 5.0 新增报文类型** MQTT 5.0在3.1.1基础上扩展了以下报文(主要用于增强功能如属性、原因码等): | 十进制值 | 二进制(高4位) | 报文名称 | 方向 | 新增特性 | |----------|------------------|-------------------|------|--------------------------------------------------------------------------| | 15 | `1111` | AUTH | 双向 | 用于增强认证(如挑战-响应机制),替代部分CONNECT/CONNACK中的认证逻辑。 | --- ### **3. 报文类型在代码中的定义** #### **(1) 枚举示例(C语言)** ```c typedef enum { MQTT_PKT_CONNECT = 1, MQTT_PKT_CONNACK = 2, MQTT_PKT_PUBLISH = 3, MQTT_PKT_PUBACK = 4, MQTT_PKT_PUBREC = 5, MQTT_PKT_PUBREL = 6, MQTT_PKT_PUBCOMP = 7, MQTT_PKT_SUBSCRIBE = 8, MQTT_PKT_SUBACK = 9, MQTT_PKT_UNSUBSCRIBE = 10, MQTT_PKT_UNSUBACK = 11, MQTT_PKT_PINGREQ = 12, MQTT_PKT_PINGRESP = 13, MQTT_PKT_DISCONNECT = 14, MQTT_PKT_AUTH = 15 // MQTT 5.0 } MQTT_PacketType; ``` #### **(2) 报文解析逻辑** ```c uint8_t MQTT_ParsePacketType(uint8_t *packet) { return (packet[0] >> 4); // 取首字节高4位 } // 示例:判断报文类型 uint8_t pkt_type = MQTT_ParsePacketType(received_data); switch (pkt_type) { case MQTT_PKT_CONNACK: printf("Received CONNACK\n"); break; case MQTT_PKT_PUBLISH: printf("Received PUBLISH\n"); break; // ...其他类型处理 } ``` --- ### **4. 关键注意事项** 1. **方向性**: - 部分报文仅单向使用(如`PINGREQ`仅客户端发送),需在代码中严格校验方向。 2. **MQTT 5.0兼容性**: - 若支持MQTT 5.0,需处理`AUTH`报文和属性字段(如`Reason Code`、`Properties`)。 3. **错误处理**: - 收到未知报文类型(如`0x00`或`0x0F`在MQTT 3.1.1中无效)应断开连接。 4. **QoS影响**: - `PUBLISH`报文的QoS级别决定是否需要`PUBACK`/`PUBREC`等后续交互。 --- ### **5.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值