物联网通信之MQTT控制报文Connect连接服务端、Connack确认连接请求

前言

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

一、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,客户端和服务端必须丢弃之前的任何会话并开始一个新的会话。会话仅支持和网络连接同样长的时间,如果网络连接断开,那么这个会话也就结束了。
服务端的状态包括:

  • 会话是否存在,即使会话状态的其他部分都是空。
  • 客户端的订阅信息。
  • 已经发送给客户端,但是还没有完成确认的QoS1和QoS2级别的消息。
  • 即将传输给客户端的QoS1和QoS2级别的消息。
  • 已从客户端接收,但是还没有完成确认的QoS2级别的消息。
  • 可选,准备发送给客户端的QoS0级别的消息。

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

  • 服务端检测到了一个I/O错误错误或者网络故障。
  • 客户端在保持连接的时间内未能通讯。
  • 客户端没有先发送disconnect报文直接关闭了网络连接。
  • 由于协议错误服务端关闭了网络连接。

遗嘱标志被置为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

  • 遗嘱保留标志被置为0,表示服务端必须将遗嘱消息当作非保留消息发布。
  • 遗嘱保留标志被置为1,表示服务端必须将遗嘱消息当作保留消息发布。

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

  • 如果密码标志位被置为0,有效载荷中不能包含密码字段。
  • 如果密码标志位被置为1,有效载荷中必须包含密码字段。
  • 同理,用户名标志位被置为0/1时,有效载荷中不能/能包含用户名字段。
  • 如果用户名标志位被置为0,密码标志也必须被置为0。

(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字节)+有效载荷的长度。

二、CONNACK–确认连接请求

客户端向服务端发送connect报文后,服务端发送connack报文响应从客户端收到的connnect报文,服务端发送给客户端的第一个报文必须是connack报文!

1、固定报头

connack报文的固定报头第一个字节的高四位表示MQTT报文的类型,必须是2,表示此报文是connack确认请求报文,低四位是保留位为0 。第二个字节表示剩余长度,固定长度2。(这里和connect报文不同!)
在这里插入图片描述

2、可变报头

coonnack控制报文的可变报头占用两个字节,第一个字节是连接确认标志位,且第七位到第一位必须设置为0(是保留位),第0位为当前会话的标志位。第二个字节是连接返回码。
在这里插入图片描述
(1)当前会话 Session Present–第0位
如果服务端收到connect报文中清理会话标志为1的连接,那么这个connack报文中当前会话标志位设置为0;
如果服务端收到一个清理会话为0的连接,当前会话的值取决于服务端是否已保存了Client对应客户端的会话状态。

  • 如果服务端已经保存了会话状态,connack报文中当前会话状态应设置为1;
  • 如果服务端没有已保存的会话状态(首次连接),connack报文中当前会话状态也应设置为0;

(2)连接返回码
用来表示客户端向服务端发起的连接,服务端是否接受,如果服务端不接受连接返回不接受的原因是什么。
在这里插入图片描述
举个栗子:
当返回码的值为0x00时,表示连接被服务端接受;当返回码为0x01时,表示服务端不支持客户端请求的MQTT协议级别。

3、有效载荷

connack报文中没有有效载荷!因为这这是确认请求连接报文,不需要携带其他信息。


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

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姜大大的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值