其他分享
首页 > 其他分享> > 物联网通信之MQTT控制报文Connect连接服务端

物联网通信之MQTT控制报文Connect连接服务端

作者:互联网

前言

上一篇帖子认识了MQTT协议,这篇帖子研究MQTT控制报文的内容。
物联网通信专栏往期回顾:

connect-连接服务端

客户端到服务端的网络连接建立后,客户端发送给服务端的第一个报文必须是connect报文。(因为客户端和服务端必须要建立连接后才能进行通信)。

1、固定报头

connect报文中固定报头中第一个字节中高四位必须是数值1,表示当前报文是connect报文。低四位是保留位reserved为0。(具体原因请看物联网通信之初识MQTT)第二个字节开始表示剩余长度,剩余长度为可变报头加上有效载荷的长度。
在这里插入图片描述

2、可变报头

可变报头依次包含四个字段:协议名、协议级别、连接标志和保持连接。
(1)协议名:如下图,协议名是MQTT,前两个字节前缀表示字符串长度(所有字符串基本都有两个字节前缀表示字符串长度)。—6字节
在这里插入图片描述
(2)协议级别:3.1.1版本的协议级别是4(0x04)。–1字节
在这里插入图片描述
注:客户端和服务端在连接的时候,如果发现不支持的协议级别,服务端会发送一个返回码0x01的connack报文(服务端确认连接报文)响应connect报文,然后断开客户端的连接。
(3)连接标志Connect Flags–1字节
连接标志占用一个字节长度,连接标志字节包含了一些用于指定MQTT连接行为的参数。还指出了有效载荷中是否存在字段。
在这里插入图片描述
注:服务端必须验证CONNECT控制报文的保留标志位(上图中第0位)是否为0,如果不是0就必须断开与客户端的连接。(规定!不是0就代表着)
其中,Clean Session是清理会话,Will Flag是遗嘱标志,Will Qos是遗嘱服务质量等级,Will Retain是遗嘱保留,Password Flag是用户密码标志,User Name Flag是用户名标志。
a.清理会话标志Clean Session
当MQTT客户端接入MQTT服务器时,选择是否继续之前的会话,如果不清理会话,MQTT服务端会在之前交互的基础上,继续交互,如果清理会话,MQTT服务端必须新建一个全新的会话。
此标志位于连接标志字节的第一位。如果清理会话标志被置为0,服务端必须基于当前会话(使用客户端标识符识别判断是哪个客户端)的状态恢复与客户端的通信。如果清理会话标志被置为1,客户端和服务端必须丢弃之前的任何会话并开始一个新的会话。会话仅支持和网络连接同样长的时间,如果网络连接断开,那么这个会话也就结束了。
服务端的状态包括:

b.遗嘱标志 Will Flag
遗嘱消息:当客户端和服务端断开连接时,服务端向客户端发布的消息。
遗嘱消息发布的条件,包括但不限于:

遗嘱标志被置为1,表示如果连接请求被接受了,遗嘱消息必须被存储在服务端并且与这个网络连接关联,之后网络连接关闭时,服务端必须发布这个遗嘱消息,除非服务端收到disconnect报文时删除了这个遗嘱消息。连接标志的Will QoS和Will Retain 字段会被用到,同时有效载荷中必须包含Will Topic和Will Message字段。
注:一旦被发布或者服务端收到了客户端发送的Disconnect报文,遗嘱消息就必须从存储的会话状态中移除。
因为发出disconnect报文属于正常断开连接情况,不满足遗嘱消息发布的条件。
遗嘱标志被置为0,网络连接断开时,不能发送遗嘱消息。连接标志的Will QoS和Will Retain 字段会必须设置为0,并且有效载荷中不能包含Will Topic和Will Message字段。

c.遗嘱QoS Will QoS
连接标志的第三和第四位,用于指定发布遗嘱消息时使用的服务质量等级,如果遗嘱标志被置为0,遗嘱OoS也必须置为0,如果连接标志置为1,遗嘱QoS可以置为0、1、2(0x00,0x01,0x10)。
d.遗嘱保留Will Retain
遗嘱是否保留的标志位,位于连接标志的第五位。
如果遗嘱标志被置为0,遗嘱保留标志也必须置为0.
如果遗嘱标志被置为1

e.密码标志 Password Flag,用户名标志User Name Flag
百度云、阿里云都支持MQTT用户名+密码的方式接入物联网云平台。

(4)保持连接 Keep Alive --2字节
客户端必须在规定时间内,向服务端发送消息保证服务端是存活状态,如果服务端认为客户端不是存活状态,那么服务端会主动断开与客户端之间的连接。
保持连接部分占用两个字节,是以一个以秒为单位的时间间隔,表示一个16位的字,他是指在客户端传输完成一个控制报文的时刻到发送下一个报文的时刻,两者之间允许空闲的最大时间间隔。
在这里插入图片描述
客户端负责保证控制报文的时间间隔不超过保持连接的值,在此期间,如果没有任何其他的控制报文可以发送,客户端必须发送一个PINGREQ报文(心跳请求报文,告知服务端客户端还活着的报文,下面会专门说这个心跳请求报文)。


由此可知, 3.1.1版本协议可变报头字节数=6+1+1+2=10字节

3、有效载荷Payload

可变报头中的标志决定了有效载荷中是否包含这些字段,如果包含的话,必须按这个顺序出现:客户端标识符、遗嘱主题、遗嘱消息、用户名、密码。
a.客户端标识符 client Identifier
客户端使用客户端标识符识别客户端。连接服务端的每个客户端都有一个唯一的客户端标识符(ClientId),客户端和服务端都必须使用ClientId识别两者之间的MQTT会话相关的状态。
客户端标识符必须存在而且必须是connect报文有效载荷的第一个字段。(因为只有在客户端建立连接时判断第一个字段,效率较高)
b.遗嘱主题Will Topic及其他字段
如果遗嘱标志被设置为1,有效载荷的下一个字段就是遗嘱主题,遗嘱主题必须是UTF-8编码字符串。
根据可变报头的连接标志,如果遗嘱消息/用户名/密码标志为1,那么下一个字段就是该字段,其中用户名服务端可以将它用于身份验证和授权。


注:固定报头中第二个字节表示connect报文中剩余长度,计算方法: 剩余长度=可变报头长度(3.1.1版本是10字节)+有效载荷的长度。

逆水行舟不进则退,有问题在下方评论或者私聊我一直在,一起进步!

标签:标志,报文,MQTT,Connect,遗嘱,连接,服务端,客户端
来源: https://blog.csdn.net/JIANGYINGH/article/details/106864282