本篇文章目前只是讲解了conncet报文,但是我感觉你如果搜索到了本文章,那么你一定是对MQTT协议有一定了解的,我相信你可以举一反三,得出其他报文的具体解析格式,有时间的话我后续也会补上其他常用的报文解析。
1.CONNECT – 连接服务端
报文格式:
1.固定报头
0x10+剩余长度(10+有效载荷长度–依据剩余长度格式编写)
剩余长度格式:
2.可变报头
CONNECT 报文的可变报头按下列次序包含四个字段:协议名(Protocol Name) , 协议级别(ProtocolLevel) ,连接标志(Connect Flags)和保持连接(Keep Alive)。
协议名
协议名字结构:
协议长度(2字节)+名字
协议名是表示协议名 MQTT 的 UTF-8 编码的字符串。 MQTT 规范的后续版本不会改变这个字符串的偏移和长度。
协议级别
客户端用 8 位的无符号值表示协议的修订版本。对于 3.1.1 版协议,协议级别字段的值是 4(0x04)。 如果发现不支持的协议级别, 服务端必须给发送一个返回码为 0x01(不支持的协议级别) 的 CONNACK 报文响应CONNECT 报文, 然后断开客户端的连接
连接标志
连接标志字节包含一些用于指定 MQTT 连接行为的参数。 它还指出有效载荷中的字段是否存在。
清理会话
位置: 连接标志字节的第 1 位
这个二进制位指定了会话状态的处理方式。客户端和服务端可以保存会话状态,以支持跨网络连接的可靠消息传输。 这个标志位用于控制会话状态的生存时间。
遗嘱标志
位置: 连接标志的第 2 位。
遗嘱标志(Will Flag) 被设置为 1,表示如果连接请求被接受了, 遗嘱(Will Message) 消息必须被存储在服务端并且与这个网络连接关联。之后网络连接关闭时,服务端必须发布这个遗嘱消息, 除非服务端收到DISCONNECT 报文时删除了这个遗嘱消息
遗嘱 QoS
位置: 连接标志的第 4 和第 3 位。
这两位用于指定发布遗嘱消息时使用的服务质量等级。
如果遗嘱标志被设置为 0, 遗嘱 QoS 也必须设置为 0(0x00) 。
如果遗嘱标志被设置为 1, 遗嘱 QoS 的值可以等于 0(0x00), 1(0x01), 2(0x02)。 它的值不能等于 3
遗嘱保留
位置: 连接标志的第 5位。
用户名标志
位置: 连接标志的第 7 位。
如果用户名(User Name) 标志被设置为 0, 有效载荷中不能包含用户名字段
如果用户名(User Name) 标志被设置为 1, 有效载荷中必须包含用户名字段
密码标志
位置: 连接标志的第 6 位。
如果密码(Password) 标志被设置为 0, 有效载荷中不能包含密码字段 。
如果密码(Password) 标志被设置为 1, 有效载荷中必须包含密码字段。
如果用户名标志被设置为 0, 密码标志也必须设置为 0 。
保持连接
两次发送数据的最大时间间隔(最好不要大于90S)
可变报头格式:
协议名字 + 协议级别+ 连接标志+ 保持连接
0x00+0x04+"MQTT" 0x04 0xc2 0x00+0x46
3.有效载荷
CONNECT 报文的有效载荷(payload) 包含一个或多个以长度为前缀的字段(宽度2字节),可变报头中的标志决定是否包含这些字段。 如果包含的话, 必须按这个顺序出现:客户端标识符, 遗嘱主题, 遗嘱消息, 用户名, 密码
我们未使用遗嘱部分内容:
客户端标识符+遗嘱主题+遗嘱消息+ 用户名+密码
数据格式,每一部分都加了两个字节的长度标志
简化为:
客户端标识符+ 用户名+密码
以上三部分内容,参考你自己的阿里云连接MQTT信息:
#define MQTT_CLIENTID "a1GG15yJIQi.dht11_dev|securemode=2,signmethod=hmacsha256,timestamp=1704436488044|"
#define MQTT_USARNAME "dht11_dev&a1GG15yJIQi"
#define MQTT_PASSWD "f4cae0bb67b8228c6b7e2d3d5cfd928c7e66cbea3366ec8d3d03766af10452d4"