MQTT 3.1.1 通信协议

目录

 

目录

1 MQTT概述

1.1 简介

1.2 协议特点

1.3 数据格式与约定

2 控制报文格式

2.1 控制报文总体结构

2.1 固定报头

2.1.1 控制报文类型

2.1.2 标志位

2.1.3 剩余长度

2.2 可变报头

2.3 有效载荷

3 各种控制报文

3.1 CONNECT 连接报文

3.1.1 固定报头

3.1.2 可变报头

3.1.3 有效载荷

3.1.4 服务器的响应 

3.2 CONNACK 确认连接请求

3.2.1 固定报头

3.2.2 可变报头

3.2.3 有效载荷

3.3 PUBLISH 发布消息控制报文

3.3.1 固定报头


1 MQTT概述

1.1 简介

MQTT(Message Queuing Telemetry Transport)是消息队列遥测传输协议。在五层网络模型中处于应用层,是轻量级基于代理的发布/订阅的消息传输协议。设计特点:简单、轻量、易于实现。 应用场景:特别适合 带宽小、不可靠、硬件资源有限的场景下。可以说是一款物联网通信协议,运行在TCP/IP,或其他有序、可靠、双向连接的网络连接上。

1.2 协议特点

Sender(发送消息者,简称S),Receiver(接收消息者,简称R),Message(消息,简称M),Topic(主题,简称T),Proxy(代理服务器,简称P)。

1. 发布/订阅模式,使得应用之间解耦。首先接收者要去订阅主题,所有的消息都是按照主题来分类的,发送者也需要标识消息的主题。比如,R订阅了主题T,S指明消息M的主题为T并发送到代理服务器P上,P收到消息后,将M按主题T归类,然后将M推送给订阅了此主题T的用户(其中就有R),这样就完成了消息的传输。 为什么说使得应用之间解耦呢 ?试想,发送者和接受者实际上是应用程序,如果没有代理,S和R直接通信,两者程序之间多少都会存在耦合,因为要直接通信对接;如果中间有了代理,那么两者就只是和代理进行通信,之间没有直接有什么对接,所有解除了耦合。

2. 消息传输不需要知道负载内容。 暂时不理解。

3. 提供三种等级的服务质量。“最多一次”:同一个消息,发送者最多发送一次(发送失败或者发送成功),一个消息发送失败后是不会重新发送的,所以此服务等级存在数据丢失问题,可应用于对数据丢失不敏感的场景,比如部分无线传感网络,传感器丢失小部分数据,并不会产生影响。 “至少一次”:同一个消息,发送失败的时候,就会重传,确保该消息达到,所以称为至少一次;但是可能会出现消息重复,为什么可能出现重复消息呢 ?试想,要确保消息到达,那么消息达到后,必定要返回一个信号给发送者,告诉他消息送到了,但是如果由于网络的拥塞等原因,发送者迟迟没有收到返回信号,这个时间超过等待周期,那么发送者就认为消息没有送到,于是重新发送,等发送了之后,返回信号终于到了,但是消息已经被重新发送了,就造成了同一个消息被传输了两次,数据重复了。这个等级应用场景为:对数据的重复不敏感,只要保证每个数据传输成功就行。“只一次”:确保消息到达,且仅到达一次,这个容易理解。应用场景:对数据丢失和数据重复零容忍的场景。(“只一次”等级应该是最好的,直接用它不就行了,为什么还要提供另外两个等级呢?本人认为:提供的服务越完美,那么通信,计算,时间开销越大,服务越不完美,可能通信简单快速,计算简单快速,实时性高,鱼和熊掌不能兼得)。

4. 很小的传输消耗和协议数据交换,最大限度减少网络流量。这是比较明显的一个优势,协议本身简单轻量,所以传输数据量比较小。

5. 异常连接断开发生时,能通知到相关各方。网络连接因为异常而断开时,mqtt协议有机制去通知相关各方。

1.3 数据格式与约定

字节中,第0位到第7位,0位是最低为,7位是最高位。

整数是16位,又分为高8位和低8位,采用大端模式。

文本字符串采用 utf-8 编码格式。每个字符串的前面都有两个字节长度的字段,该字段是指明后面字符串的字节数,因为每个字符串的大小不能超过65535字节。

特别需要注意,字符串是Unicode编码的,U+ 代表是Unicode编码,16进制的。发送者生成的字符串是Unicode编码的,通过MQTT传输之前,要将Unicode编码的字符串转换为 utf-8 编码,传输出去,接收者接收到后,再讲 utf-8 编码格式的字符串转换为 Unicode编码格式。

在MQTT协议中,明确规定哪些Unicode字符码是不能包含的。

[U+D800, U+DFFF] 区间的字符码是无效的,如果接收者接收到了此区间的数据,必须关闭网络连接。

U+0000 空字符,如果接收者接收到了此数据,必须关闭网络连接。

[U+0001, U+001F]    [U+007F, U+009F]  区间的字符码,如果接收者接收到了,可以选择关闭网络连接。

非字符字符码,保留字符 ,如果接收者接收到了,可以选择关闭网络连接。

2 控制报文格式

2.1 控制报文总体结构

固定报头是固定的,每个控制报文都包含。可变报头,部分控制报文包含。 有效载荷,部分控制报文包含。

2.1 固定报头

2.1.1 控制报文类型

2.1.2 标志位

标志位是和控制报文类型关联的,类型是保留的,当然就不需要标志位了。Reserved表示此标志位为保留,以后开发扩展用的,重点就是PUBLISH类型的标志位。

DUP1:控制报文的重复分发标志。

QoS2:控制报文的服务质量等级。

RETAIN3:控制报文的保留标志。

2.1.3 剩余长度

剩余长度是剩下报文的字节数,不包含剩余长度本身。

剩余长度最少一个字节,最多四个字节,根据剩余报文大小决定。剩余长度的每个字节分为两部分:第7位 和 0~6位,第7位(最高位)表示是否后面还有字节。

2.2 可变报头

可变报头在每种类型的控制报文里面的字段和含义是不一样的,此处暂时不作介绍,第3节介绍各种报文的时候

2.3 有效载荷

有效载荷,可以将其理解为报文所带的附件内容,并不是所有的控制报文都需要有效载荷,对于不同类型的控制报文,有效载荷的意义是不一样的。

3 各种控制报文

3.1 CONNECT 连接报文

在客户端和服务器之间,只要网络是可达的,那么要想客户端和服务器建立连接,客户端就要发送第一个报文CONNECT连接报文,而且只能发送一次CONNECT报文,因为如果服务器收到客户端两个CONNECT报文的话,就必须要以异常处理,断开与客户端的连接。

3.1.1 固定报头

3.1.2 可变报头

可变报头包含四个内容,分别是“协议名”、“协议级别”、“连接标志”、“保持连接”。

协议名:协议名就是MQTT,长度为4字节,前两个字节用于存储长度,所以是04,后面4个字节用于存储协议的名字,就是MQTT,每个字母占据一个字节,用 utf-8 编码表示。这块内容基本不会变了,因为MQTT后续版本的协议对此都不会改变。

                如果协议名不是MQTT的话,服务器可以断开与客户端的连接。

协议级别:级别和协议的版本是一一对应的,比如本文讲的协议版本是3.1.1 ,那么级别就是4。作用:当服务器发现已经不支持客户端使用的协议版本了,就会返回返回一个控制报文,告知客户端协议不支持,然后服务器断开连接。

连接标志:就是指明连接的一些参数。服务器必须检验连接标志中的0位(保留位)是否为0,如果不为0,服务器必须断开连接。

第1位(清理会话):是否及时清理会话状态。服务器与客户端之间是存在会话的,这个会话会保存一些信息(关于客户端),clean Session位设置为0,表示不清理会话,即保存会话状态,如果设置为1,表示要清理会话,即每一次传递数据,都是以新的会话来完成。

第2位(遗嘱标志):是否留下遗嘱消息。当客户端与服务器之间连接非正常断开之后,是否要发布一个遗嘱消息。如果Will Flag设置为1,表示要留下遗嘱消息,遗嘱消息是存储在服务器的,当客户端与服务器之间的连接异常断开后,服务器就发布此遗嘱消息;如果设置为9,表示不留下遗嘱消息。

第3、4位(遗嘱服务质量等级):发布遗嘱消息所使用的服务质量等级(0,1,2)。如果Will Flag设置为1,那么此标志才被用到,如果Will Flag设置为0,则此标志Will Qos必须为0。

第5位(遗嘱保留):是否将遗嘱消息当做保留消息发布。如果Will Flag设置为0,则Will Retain 必须设置为0.。如果Will Flag设置为1,Will Retain设置为0,则服务器将遗嘱消息当作非保留消息发布,Will Retain设置为1,则服务器将遗嘱消息当作保留消息发布。

第6位(密码标志):载荷部分是否包含密码字段。如果Password Flag设置为0,则不能包含有密码字段,设置为1,则必须包含密码字段。如果User Name Flag设置为0,那么Password Flag必须设置为0。

第7位(用户名标志):载荷部分是否包含用户名字段。如果User Name Flag设置为0,则不能包含用户名字段,设置为1,则必须包含用户名字段。

保持连接:客户端发送报文的最大间隔时间,必须不断发送,如果没有什么实际报文可发送,那可以发送一个PINGREQ报文,总之空闲时间不能大于保持连接。2个字节,16位,单位为秒。

如果保持连接不为0,那么客户端就要遵守规则,发送报文的间隔时间不能超过保持连接。如果服务器在 1.5*保持连接 的时间内没有接收到客户端的控制报文,那么就可以认为网络连接断开了,必须要断开与客户端的连接。

如果保持连接等于0,就等于没有这个规则了,服务器不需要去关心客户端是否活跃。

 

3.1.3 有效载荷

就是一个或者多个以长度为前缀的字段,包含的内容有哪些呢? 由可变报头中的那些标志位决定。 载荷中的内容是有严格顺序的:客户端标识符,遗嘱主题,遗嘱消息,用户名,密码。

客户端标识符:每个客户端都有能够唯一标识自己的标识符,这样服务器才能识别客户端身份。(必须存在,而且处于有效载荷的第一个字段),而且标识符的长度为1~23个字节,只能由“大写字母”、“小写字母” 和 “数字” 组成。

服务器也允许客户端传一个零字节的标识符,但是如果是这样,那么服务器必须将此看作是特殊情况,给客户端分配一个标识符, 以此假设客户端提了标识符,接着正常处理。

试想,如果客户端的标识符为零字节,服务器给客户端一个临时的标识符,那么就意味着清理会话标志必须设置为1,因为饿标识符是临时的,没法保存会话状态; 如果此时清理会话标志为0的话,服务器必须发送返回码为0x02的CONNACK报文响应客户端,然后关闭连接。

如果客户端标识符什么的,都没有问题,但是服务器就是拒绝了这个客户端,那服务器必须要发送返回码为0x02的CONNACK报文响应客户端,然后关闭连接。

遗嘱主题:如果可变报头中的遗嘱标志被设置为1,那么接下来一个字段就是遗嘱主题了。

遗嘱消息:如果可变报头中的遗嘱表示被设置为1的话,那么接下来的一个字段就是遗嘱消息。

用户名:如果可变报头中的用户名标志被设置为1的话,那么接下来一个字段就是用户名。

密码:如果可变报头中的密码标志被设置为1的话,那么接下来一个字段就是密码。包含两个字节的“长度”,和密码部分。

3.1.4 服务器的响应 

网络基础设施建立好了之后,即客户端可以与服务器网络沟通之后,如果在规定的时间内没有收到CONNECT报文,服务器可以关闭这个连接。

服务器必须按照相应的要求去验证CONNECT报文,如果报文不符合要求,服务器不发送CONNACK报文,直接关闭连接。

服务器可以做数据的业务检查,如果发现CONNECT报文中的内容不满足要求,可以发送一个适当的CONNACK响应,并且必须关闭连接。

 

 

3.2 CONNACK 确认连接请求

CONNACK报文是专门用于响应用户的CONNECT连接请求报文的,这是服务器发送给客户端的第一个报文。如果客户端从发送完CONNECT报文后的一段合理的时间内,没有接收到服务器的CONNACK报文,客户端应该关闭连接。

3.2.1 固定报头

报文的固定报头的格式肯定都是一样的,只是内容不一样,CONNACK报文的固定报头内容如下,报文类型是2,剩余长度固定是2。既然剩余长度为2,那么我们接下来就看看这两个字节到底存的是什么(可变报头的两个字节,没有有效载荷)。

3.2.2 可变报头

可以看出,CONNACK报文的可变报头中的内容就比较少了,没有CONNECT报文那么多,至于两个内容,连接确认标志和连接返回码,每个内容占1个字节。

连接返回码:先说这个返回码,返回码是1个字节,无符号值。规定了一些返回码,每一个返回码都代表一个意义。服务器如果向客户端返回的CONNACK报文中的返回码是非零的,服务器必须关闭与客户端的连接。

如果实际的场景与下表中所有的返回码意义都不符合,服务器必须关闭网络连接,不需要发送CONNACK报文。

返回码响应描述
00x00 表示接受连接服务器已接受客户端的CONNECT请求连接
10x01 表示拒绝连接,不支持协议版本服务器不支持客户端的MQTT协议版本
20x02 表示拒绝连接,不合格的客户端标识符服务器认为客户端标识符不合格
30x03 表示拒绝连接,服务器不可用网络连接已建立,但是MQTT服务不可用,问题出在服务器上
40x04 表示拒绝连接,无效的用户名或者密码用户名或密码的数据格式无效(注意是格式)
50x05 表示拒绝连接,未授权客户端未被授权连接到此服务器
6~255暂时没有使用保留

连接确认标志:1个字节,共8位,1~7位均为0(保留位),0位才是有用的那一位,0位是“当前会话标志”,那这个当前会话标志有什么作用呢?首先理解下面的一段话:

客户端发送CONNECT连接请求报文,如果报文中的清理会话标志为1,那CONNACK报文的返回码要设置为0,当前会话标志要设置为0。 如果CONNECT报文中的清理会话标志为0,此时就取决于服务器是否已经保存了客户端的会话状态,如果没有存储,那服务器必须将CONNACK报文中的当前会话标志设置为0,将返回码设置为0; 如果服务器存储了客户端的会话状态,那必须将CONNACK报文中的当前会话标志设置为1。

通过上面一段的说明,当前会话标志的作用就是要告诉客户端,我服务器是不是已经存储有我们的会话状态。这样的话,如果服务器返回的会话状态标志为1,就说明服务器存有会话状态,客户端也可以存储会话状态呀,此时客户端就可以判断服务器的行为是否合理,如果不合理,就可以断开。(之前总是服务器去各种验证,检查客户端,现在客户端也可以有点验证服务器的地方了)。

注意:如果服务器发送一个非零返回码的CONNACK报文,必须将当前会话标志设置为0。

3.2.3 有效载荷

CONNACK报文没有有效载荷。

3.3 PUBLISH 发布消息控制报文

3.3.1 固定报头

PUBLISH报文的类型是3,DUP是重发标志,Qos是服务质量等级,RETAIN是保留标志(是有用的,不是那种保留在哪将来用,这个标志的名字就是保留标志)。

 

 

 

 

 

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: MQTT(Message Queuing Telemetry Transport)是一种轻量级的消息传递协议,用于不同设备之间的通信。MQTT 3.1.1是MQTT的版本号,是比较常用的版本。 MQTT 3.1.1协议具有以下特点和优势: 1. 轻量级:MQTT采用一种非常轻巧的封装格式,使得它非常适合在网络带宽较低或者资源受限的环境下使用,如物联网设备中。 2. 简单易用:MQTT协议的设计非常简单,只有3个主要角色:发布者(Publisher)、订阅者(Subscriber)和代理服务器(Broker)。这种简单的架构使得开发者可以轻松地实现MQTT通信。 3. 异步通信:MQTT允许发布者和订阅者之间进行异步通信。发布者只需要将消息发布到代理服务器上,订阅者则可以在需要的时候订阅到消息。这种异步通信的特性可以提高通信的效率和可扩展性。 4. 可靠性:MQTT 3.1.1协议提供了多种传输层的质量保证服务,如最多一次、至少一次和只有一次的传输保证。根据应用场景的不同,可以选择适当的服务质量。 5. 安全性:MQTT 3.1.1协议支持SSL/TLS加密和鉴权机制,确保通信的安全性。通过这些安全机制,可以对消息进行加密传输,同时也可以对客户端进行身份验证。 总而言之,MQTT 3.1.1协议是一种适用于物联网设备的轻量级、简单易用、可靠和安全的通信协议。它的设计目标是在网络带宽有限和资源受限的条件下,实现可靠的异步通信。在物联网领域,MQTT 3.1.1广泛应用于各种场景,如传感器数据的采集、智能家居的控制等。 ### 回答2: MQTT 3.1.1协议是一种轻量级的通信协议,主要用于物联网和小型设备之间的通信。 MQTT(Message Queuing Telemetry Transport)是一种基于发布/订阅的模式的消息协议,具有低带宽、低数据包开销和低延迟的特点。它使用TCP/IP协议进行通信,并支持多种可靠性的服务质量等级。 MQTT 3.1.1协议定义了客户端与服务器之间的消息传输格式和规则。客户端可以是任何设备或应用程序,服务器则负责接收、转发和传送消息。 MQTT 3.1.1协议使用发布/订阅模式进行通信。客户端可以发布消息到特定的主题(topic),而其他客户端可以通过订阅相应的主题来接收消息。通过定义主题层次结构,可以实现灵活的消息过滤和分发。 协议中还定义了三个服务质量等级(QoS):0级为“至多一次”,消息会至少传输一次,但可能会重复或丢失;1级为“至少一次”,消息会至少传输一次,但可以重复;2级为“恰好一次”,消息会确保只传输一次。 此外,MQTT 3.1.1协议还支持保留消息和遗嘱消息的功能。保留消息是指发布到特定主题的消息会被保留在服务器上,新的订阅者可以接收到最新的保留消息。而遗嘱消息是当客户端断开连接时,服务器会代替客户端发布一个预先定义的消息,用于通知其他订阅者。 总的来说,MQTT 3.1.1协议提供了一种高效、灵活和可靠的通信机制,特别适用于物联网场景。它的低带宽和低功耗特性使其成为物联网设备之间通信的理想选择。 ### 回答3: MQTT(Message Queuing Telemetry Transport)是一种轻量级发布/订阅协议,用于在物联网设备之间传输消息。MQTT 3.1.1是MQTT协议的一个版本。 MQTT 3.1.1协议增强了先前版本的功能和性能。它主要包含以下几个方面的改进: 1. 会话状态:MQTT 3.1.1引入了会话状态的概念,使得设备可以保存和恢复连接状态。这意味着设备断开连接后,可以通过恢复会话状态来继续传输消息。 2. 心跳机制:MQTT 3.1.1中添加了心跳机制,用于检测设备是否在线。通过在连接期间定期发送心跳包,可以及时检测设备的连接状态。如果设备长时间未发送心跳包,服务器就可以判断设备已经离线,并采取相应的措施。 3. 遗愿消息:MQTT 3.1.1允许设备在断开连接时发送遗愿消息。遗愿消息是设备事先配置好的消息,当设备异常断开连接时,服务器会自动发布这些消息给其他订阅者。 4. 主题过滤器:MQTT 3.1.1支持更灵活的主题过滤器,可以通过通配符匹配多个主题。这使得订阅者可以更方便地订阅特定类型的消息。 5. 安全性:MQTT 3.1.1支持SSL/TLS加密传输,保护消息的安全性。设备和服务器可以使用用户名和密码进行身份验证,确保只有授权的设备才能连接和发布消息。 总的来说,MQTT 3.1.1协议在原有的基础上增加了一些重要的功能和改进,使得物联网设备之间的通信更加可靠和灵活。它被广泛应用于物联网领域,提供了一种高效、轻量级的消息传输解决方案。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值