ICode9

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

MQTT协议解析---(转)

2021-08-11 10:03:14  阅读:213  来源: 互联网

标签:报文 代理 --- MQTT 报头 解析 连接 客户端


网上已有相关讲解,对协议分析得很详细,记录学习一下备用,原blog地址见末尾。

MQTT 3

MQTT 3 (当前版本3.1.1)是目前使用的最为广泛的MQTT协议标准。尽管MQTT5标准已经发布,并且带来了一些令人振奋的新特性,但是在整个应用场景上,从后台服务到消息中间件再到客户端SDK等环节上的产品升级并没有都完成,再加上既有部署的维护,业界从版本3到5的过渡可能会持续相当长一段时间,所以,对于刚加入物联网行业的生力军来说,现在来学习MQTT 3依然是一件很有意义的事情。

MQTT协议的工作方式

在一个QMTT协议中有三个角色会参与到整个通信过程,发布者(publisher)、代理(broker)和订阅者(subscriber)。有别于传统的客户端/服务器通讯协议,MQTT协议并不是端到端的,消息传递通过代理,包括会话(session)也不是建立在发布者和订阅者之间,而是建立在端和代理之间。代理解除了发布者和订阅者之间的耦合。

除了发布者和订阅者之间传递普通消息,代理还可以为发布者处理保留消息和遗愿消息,并可以更改服务质量(QoS)等级。

MQTT控制报文

MQTT协议工作在TCP之上,端和代理之间通过交换预先定义的控制报文来完成通信。MQTT报文有3个部分组成,并按下表顺序出现:

固定报头(fixed header)可变报头(variable header)荷载(payload)
所有报文都包含 部分报文包含 部分报文包含

所有的MQTT控制报文都有一个固定报头,期格式如下:



 

协议版本3定义了14种MQTT报文,用于建立/断开连接、发布消息、订阅消息和维护连接。固定报头的第一字节的4-7位的值指定了报文类型,其取值如下表。0和15为系统保留值;0-3位为标志位,依照报文类型有不同的含义,事实上,除了PUBLISH报文以外,其他报文的标志位均为系统保留。如果收到报文的标志位无效,代理应断开连接。

报文类型描述
CONNECT 1 客户端向代理发起连接请求
CONNACK 2 连接确认
PUBLISH 3 发布消息
PUBACK 4 发布确认
PUBREC 5 发布收到(QoS2)
PUBREL 6 发布释放(QoS2)
PUBCOMP 7 发布完成(QoS2)
SUBSCRIBE 8 客户端向代理发起订阅请求
SUBACK 9 订阅确认
UNSUBSCRIBE 10 取消订阅
UNSUBACK 11 取消订阅确认
PINGREQ 12 PING请求
PINGRESP 13 PING响应
DISCONNECT 14 断开连接

固定报头的第二字节起表示报文的剩余长度。最大4个字节,每字节可以编码至127,并含有一位继续位,如继续位非0,则下一字节依然为剩余长度。由此,理论上一个控制报文最长可以到256MB。

一些报文在固定报头和荷载之间可以有一个可变报头。可变报头的内容根据报文类型不同而不同。最常见的可变报头是报文标识符(PacketIdentifier)。

一些报文可以在最后携带一个荷载。不同的报文可以无荷载,可选荷载,或必须带有荷载。

CONNECT报文

CONNECT是客户端连接到代理的第一个报文,如果在连接已经存在,代理收到该报文将会断开现有连接。

CONNECT报文的固定报头

 

CONNECT报文的可变报头

CONNECT报文的可变报头由4部分组成:

  • 协议名。协议名是UTF-8编码的大写的MQTT。
  • 协议级别。MQTT 3.1.1的协议级别为4.
  • 连接标志位。定义连接行为的参数。见下表。
  • Keep Alive。2字节,客户端和代理之间的无活动时间超过该值后,应关闭连接。如果该值置0表示客户端不要求代理启用KEEPALIVE功能。

连接标志位:

76543210
  用户名 密码 保留遗愿 遗愿QoS 遗愿QoS 遗愿 清除会话 保留(0)

清除会话标志位
这个标志位定义了如何处理会话状态。如果设置为0,客户端和代理可以恢复上一次连接时的会话状态,如果上一次连接的会话状态不存在,代理将会为客户端建立一个新的会话。如果该位设置为1,则双方将清除掉上一次连接的会话状态并建立一个新的会话。

遗愿标志位
如果遗愿标志为1,则遗愿消息会被存储在代理上,当连接关闭时,代理将发布这个消息,除非在客户端断开连接时把遗愿消息清除了。

遗愿QoS标志位
指定了遗愿消息的服务质量等级。

保留遗愿消息标志位
指定在发布遗愿消息的时候,是否把该消息作为保留消息存储在代理。

用户名标志位
如果设置为1,则用户名必须出现在荷载中,反之,用户名不允许出现在荷载中。

密码标志位
如果该位为1,则密码必须出现在荷载中;如果该位为0,则密码不允许出现在荷载中。如果用户名标志位为0,则该位必须也为0。

CONNECT报文的荷载

CONNECT报文的荷载由一个或者多个字段组成,这些字段是否出现由可变报头中的标志位决定。字段总是以长度开始。字段出现的顺序必须是:客户端标识符,遗愿主题,遗愿消息,用户名,密码。

CONNECT报文的响应

在代理在为MQTT协议开放的端口上接收到TCP连接请求并建立连接后应该会收到CONNECT报文,如果在一定时间内代理没有收到CONNECT报文,则应该关闭这个TCP连接。
在收到CONNECT报文后,代理应该检查报文格式是否符合协议标准。如果不符合协议标准,代理应关闭连接,且不发送CONNACK报文给客户端。
代理可以检查CONNECT报文的内容并执行响应的认证和鉴权。如果这些检查没有通过,代理应该向客户端发送一个带有非0返回码的CONNACK报文。

CONNACK报文

CONNACK是代理用来响应客户端CONNECT的报文。代理向客户端发送的第一个报文必须是CONNACT。CONNACK有一个固定报头,一个可变报头,但是不带有荷载。

CONNACK的固定报头

CONNACT报文只有固定报头和一个2字节的可变报头,所以它的剩余长度总是2。

CONNACK报文的可变报头

CONNACK报文的可变报头为定长2字节。第一字节的0位表示是否有会话存在。如果代理上已经有请求连接的客户端的会话,且连接请求的清除会话标识为0,则该位为1,否则该位为0。客户端可以根据这一位的值采取响应行为,比如(重新)订阅主题等。

CONNACK报文的可变报头的第二字节为返回码。如果CONNECT请求的格式正确,但是代理依然不能允许客户端连接,则返回码为一个非零值。如果连接成功,则返回0。

返回码的定义:

返回码含义
0 成功,连接请求被接受。
1 拒绝连接,不可接受的协议版本。
2 拒绝连接,不被允许的身份识别符(Client Identifier)。
3 拒绝连接,服务器不可用。
4 拒绝连接,无效的用户名和密码。
5 拒绝连接,客户端无授权。
6-255 系统保留。

客户端接受到代理的CONNACK的返回码为0,则连接建立完成,双方可以开始通信。

清除会话、保留消息和QoS的组合

清除会话、保留消息等概念,在传统的客户端/服务器方式的通信中不一定会出现,这些概念有时候不太容易理解,特别是当他们被组合起来用的时候。

下面的表格汇总了当一个客户端连接上来时,它能收到消息的各种情况。

清除会话位保留位订阅QoS发布QoS可收到的消息
Y N 0 0 N
Y N 0 1 N
Y N 1 0 N
Y N 1 1 N
N N 0 0 N
N N 0 1 N
N N 1 0 N
N N 1 1 Y,会话全部消息
Y Y 0 0 Y,最后一条消息
Y Y 0 1 Y,最后一条消息
Y Y 1 0 Y,最后一条消息
Y Y 1 1 Y,最后一条消息
N Y 0 0 Y,最后一条消息
N Y 0 1 Y,最后一条消息
N Y 1 0 Y,最后一条消息
N Y 1 1 Y,会话全部消息

原blog地址:https://www.cnblogs.com/JuliaLiu/p/11244449.html

标签:报文,代理,---,MQTT,报头,解析,连接,客户端
来源: https://www.cnblogs.com/MyWPF/p/15126924.html

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

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

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

ICode9版权所有