ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2020-06-21 21:39:47  阅读:577  来源: 互联网

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

  • 会话是否存在,即使会话状态的其他部分都是空。
  • 客户端的订阅信息。
  • 已经发送给客户端,但是还没有完成确认的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字节)+有效载荷的长度。

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

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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有