博客
关于我
MQTT 控制报文 - CONNECT连接服务器报文,CONNACK,DISCONNECT - 第3章
阅读量:352 次
发布时间:2019-03-04

本文共 4774 字,大约阅读时间需要 15 分钟。

 

目录


3.1 CONNECT - 连接服务器

  • 客户端到服务端的TCP/UDP网络连接建立后,客户端发送给服务端的第一条报文必须是 CONNECT 报文
  • 在一个网络连接上,客户端只能发送一次 CONNECT 报文
  • 服务端必须将客户端发送的第二个 CONNECT 报文当作协议违规。

 

CONNECT报文 - 帧格式:

 

CONNECT报文 的帧格式
  功能 字节空间
固定报头 MQTT报文类型+保留位 1 Byte
剩余长度 1 ~ 4 Byte
可变报头 协议名 6 Byte
协议级别 1 Byte
连接标志 1 Byte
保持连接时间 2 Byte
有效载荷 ... ... ... ...

 

 

3.1.1 CONNECT 固定报头

 

CONNECT 固定报头 的数据格式
Byte - Bit 7 6 5 4 3 2 1 0
Byte 1 MQTT 报文的类型(1 - CONNECT) Reserved 保留位
1,0x1 - CONNECT 0x0
Byte 2~5 剩余长度
  • CONNECT 的第1个字节为 0x10,剩余长度字段需要根据可变报头和有效载荷的长度来确定。
  • 剩余长度字段的计算过程见 2.2.3。

 

 

3.1.2 CONNECT 可变报头

CONNECT的可变报头包含四个字段:

  • 协议名(Protocol Name)
  • 协议级别(Protocol Level)
  • 连接标志(Connect Flags)
  • 保持连接时间(Keep Alive)

 

CONNECT 可变报头 的数据格式
byte 1 ~ 6 协议名
byte 7 协议级别
byte 8 连接标志
byte 9 ~ 10 连接保持时间

 

 

3.1.2.1 协议名

可变报头中,协议名字段的6个字节是固定的:

 

CONNECT 固定报头 - 协议名 的数据格式
  功能 说明
byte 1 协议名长度 长度 MSB 0x00
byte 2 长度 LSB 0x04
byte 3 协议名 ' M ' 0x4D
byte 4 ' Q ' 0x51
byte 5 ' T ' 0x54
byte 6 ' T ' 0x54

 

 

3.1.2.2 协议级别

 

CONNECT 固定报头 - 协议级别 的数据格式
byte 7 0x04(MQTT3.1.1)

客户端用8位的无符号值表示协议的修订版本。对于3.1.1版MQTT协议,协议级别字段的值是4(0x04)。如果发现不支持的协议级别,服务端必须给发送一个返回码为0x01(不支持的协议级别)的CONNACK报文响应CONNECT报文,然后断开客户端的连接。

 

 

3.1.2.3 连接标志

连接标志字节包含一些用于指定MQTT连接行为的参数。它还指出有效载荷中的字段是否存在。

 

CONNECT 固定报头 - 连接标志位 的数据格式
  Bit 7 Bit 6 Bit 5 Bit 4 Bit3 Bit 2 Bit 1 Bit 0
byte 8 User Name Flag Password Flag Will Retain Will Qos Will Flag Clean Session Reserved
用户名标志位 密码标志位 遗嘱保留 遗嘱 Qos 遗嘱标志 清理会话 -

 

Bit 1:清理会话标志位。这个标志位用于控制会话状态的生存时间。如果清理会话(CleanSession)标志被设置为0,服务端必须基于当前会话(使用客户端标识符识别)的状态恢复与客户端的通信;如果清理会话(CleanSession)标志被设置为1,客户端和服务端必须丢弃之前的任何会话并开始一个新的会话。会话仅持续和网络连接同样长的时间。与这个会话关联的状态数据不能被任何之后的会话重用。

Bit 2:遗嘱标志位。遗嘱标志(Will Flag)被设置为1,表示如果连接请求被接受了,遗嘱(Will Message)消息必须被存储在服务端并且与这个网络连接关联。之后网络连接关闭时,服务端必须发布这个遗嘱消息,除非服务端收到DISCONNECT报文时删除了这个遗嘱消息。如果遗嘱标志被设置为1,连接标志中的Will QoS和Will Retain字段会被服务端用到,同时有效载荷中必须包含Will Topic和Will Message字段。

Bit 3~4:遗嘱 Qos。这两位用于指定发布遗嘱消息时使用的服务质量等级。如果遗嘱标志被设置为0,遗嘱QoS也必须设置为0(0x00)。如果遗嘱标志被设置为1,遗嘱QoS的值可以等于0(0x00),1(0x01),2(0x02)。它的值不能等于3。

Bit 5:遗嘱保留标志位。如果遗嘱消息被发布时需要保留,需要指定这一位的值。如果遗嘱标志被设置为0,遗嘱保留(Will Retain)标志也必须设置为0。如果遗嘱标志被设置为1:

  • 如果遗嘱保留被设置为0,服务端必须将遗嘱消息当作非保留消息发布。
  • 如果遗嘱保留被设置为1,服务端必须将遗嘱消息当作保留消息发布。

Bit 6:密码标志位。如果密码(Password)标志被设置为0,有效载荷中不能包含密码字段。如果密码(Password)标志被设置为1,有效载荷中必须包含密码字段。如果用户名标志被设置为0,密码标志也必须设置为0。

Bit 7:用户名标志位。如果用户名(User Name)标志被设置为0,有效载荷中不能包含用户名字段。如果用户名(User Name)标志被设置为1,有效载荷中必须包含用户名字段。

连接标志位最常见的组合是:1100 0010,即为 0xC2

 

 

3.1.2.4 保持连接时间

 

CONNECT 固定报头 - 保持连接时间 的数据格式
  Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
byte 9 保持连接 Keep Alive MSB
byte 10 保持连接 Keep Alive LSB

 

 

保持连接(Keep Alive)是一个以秒为单位的时间长度,表示为一个16位的字,它是指在客户端传输完成一个控制报文的时刻到发送下一个报文的时刻,两者之间允许空闲的最大时间间隔。客户端负责保证控制报文发送的时间间隔不超过保持连接的值。如果没有任何其它的控制报文可以发送,客户端必须发送一个PINGREQ报文。

不管保持连接的值是多少,客户端任何时候都可以发送PINGREQ报文,并且使用PINGRESP报文判断网络和服务端的活动状态。

如果保持连接的值非零,并且服务端在一点五倍的保持连接时间内没有收到客户端的控制报文,它必须断开客户端的网络连接,认为网络连接已断开。

客户端发送了PINGREQ报文之后,如果在合理的时间内仍没有收到PINGRESP报文,它应该关闭到服务端的网络连接。

保持连接的实际值是由应用指定的,一般是几分钟。允许的最大值是18小时12分15秒

 

 

3.1.3 有效载荷

CONNECT报文的有效载荷(payload)包含一个或多个以长度为前缀的字段,可变报头中的标志决定是否包含这些字段。如果包含的话,必须按这个顺序出现:客户端标识符,遗嘱主题,遗嘱消息,用户名,密码。

 

 

 

 

 

 

3.2 CONNACK - 连接响应

服务端发送CONNACK报文响应从客户端收到的CONNECT报文。服务端发送给客户端的第一个报文必须是CONNACK。

如果客户端在合理的时间内没有收到服务端的CONNACK报文,客户端应该关闭网络连接。

 

CONNACK报文 - 帧格式
    功能
byte 1 固定报头 MQTT报文类型+保留位
byte 2 剩余长度
byte 3 可变报头 连接确认标志
byte 4 连接返回码

 

CONNACK 没有 有效载荷 字段

 

 

3.2.1 固定报头

 

CONNACK 固定报头 的数据格式
  Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
byte 1 MQTT报文类型(2 - CONNACK) Reserved 保留位
2,0x2 - CONNACK 0 0 0 0
byte 2 剩余长度值
0x02

 

剩余长度值,表示可变报头的长度。对于CONNACK报文这个值为2

 

 

3.2.2 可变报头

 

CONNACK 可变报头 的数据格式
  Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
byte 3 Reserved 保留位 当前会话标志位 SP
0 0 0 0 0 0 0 X
byte 4 连接返回码
               

 

当前会话标志位 SP(Session Present):如果服务端收到清理会话(CleanSession)标志为1的连接,除了将CONNACK报文中的返回码设置为0之外,还必须将CONNACK报文中的当前会话设置(Session Present)标志为0。

如果服务端收到一个CleanSession为0的连接,当前会话标志的值取决于服务端是否已经保存了ClientId对应客户端的会话状态。如果服务端已经保存了会话状态,它必须将CONNACK报文中的当前会话标志设置为1。如果服务端没有已保存的会话状态,它必须将CONNACK报文中的当前会话设置为0。还需要将CONNACK报文中的返回码设置为0。

如果服务端发送了一个包含非零返回码的CONNACK报文,它必须将当前会话标志设置为0。

 

连接返回码:如果服务端收到一个合法的CONNECT报文,但出于某些原因无法处理它,服务端应该尝试发送一个包含非零返回码的CONNACK报文。

如果服务端发送了一个包含非零返回码的CONNACK报文,那么它必须关闭网络连接

 

CONNACK 可变报头 - 连接返回码 的值
返回码响应 描述
0 0x00连接已接受 连接已被服务端接受
1 0x01连接已拒绝,不支持的协议版本 服务端不支持客户端请求的MQTT协议级别
2 0x02连接已拒绝,不合格的客户端标识符 客户端标识符是正确的UTF-8编码,但服务端不允许使用
3 0x03连接已拒绝,服务端不可用 网络连接已建立,但MQTT服务不可用
4 0x04连接已拒绝,无效的用户名或密码 用户名或密码的数据格式无效
5 0x05连接已拒绝,未授权 客户端未被授权连接到此服务器
6 ~ 255   Reserved 保留

 

如果认为上表中的所有连接返回码都不太合适,那么服务端必须关闭网络连接,不需要发送CONNACK报文

CONNACK 没有 有效载荷 字段

 

 

 

 

 

 

3.3 DISCONNECT - 断开连接

DISCONNECT报文是客户端发给服务端的最后一个控制报文。表示客户端正常断开连接。

 

 

3.3.1 固定报头

 

DISCONNECT 固定报头 的数据格式
  Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
byte 1 MQTT报文类型(14 - DISCONNECT) Reserved 保留位
14,0xE - DISCONNECT 0 0 0 0
byte 2 剩余长度
0x00

 

CONNACK 没有 可变报头 字段

CONNACK 没有 有效载荷 字段

客户端发送DISCONNECT报文之后,必须关闭网络连接,并且不能通过这个网络连接再发送任何控制报文

服务端在收到DISCONNECT报文时,必须丢弃任何与当前连接关联的未发布的遗嘱消息,并且关闭网络连接(如果客户端 还没关闭连接的话)

 

实际案例、相关链接

MQTT 协议详解:

MQTT 报文帧格式详解:

使用MQTT.fx,MQTT接入阿里云物联网平台:

使用电脑网络调试助手,MQTT接入阿里云物联网平台:

 

转载地址:http://oiqe.baihongyu.com/

你可能感兴趣的文章
mysql 死锁(先delete 后insert)日志分析
查看>>
MySQL 死锁了,怎么办?
查看>>
MySQL 深度分页性能急剧下降,该如何优化?
查看>>
MySQL 深度分页性能急剧下降,该如何优化?
查看>>
MySQL 添加列,修改列,删除列
查看>>
mysql 添加索引
查看>>
MySQL 添加索引,删除索引及其用法
查看>>
mysql 状态检查,备份,修复
查看>>
MySQL 用 limit 为什么会影响性能?
查看>>
MySQL 用 limit 为什么会影响性能?有什么优化方案?
查看>>
MySQL 用户权限管理:授权、撤销、密码更新和用户删除(图文解析)
查看>>
mysql 用户管理和权限设置
查看>>
MySQL 的 varchar 水真的太深了!
查看>>
mysql 的GROUP_CONCAT函数的使用(group_by 如何显示分组之前的数据)
查看>>
MySQL 的instr函数
查看>>
MySQL 的mysql_secure_installation安全脚本执行过程介绍
查看>>
MySQL 的Rename Table语句
查看>>
MySQL 的全局锁、表锁和行锁
查看>>
mysql 的存储引擎介绍
查看>>
MySQL 的存储引擎有哪些?为什么常用InnoDB?
查看>>