连接服务端

  客户端到服务端的第一个报文必须是CONNECT,且只能发送一次,发送的第二个connect报文当作违规处理并断开连接。

  有效载荷包含一个或者多个编码的字段。包括客户端的唯一标识符,Will主题,Will消息,用户名和密码。

  除了标识外,其他字段都是可选的,基于标志位决定可变报头中是否需要包含这些字段。

固定报头

  报头长度:2 Bytes

  1、报文类型:1  CONNECT

  2、标志位  0 0 0 0:

 

  3、剩余长度

    等于可变报头的长度(10)加上有效载荷的长度。

可变报头

  在固定CONNECT报文可变报头包含四个字段,协议名、协议级别、连接标志、保持连接:

  1、协议名 (Protocol Name)。

  如果协议名不正确,server端可以断开连接。

  2、协议级别(Protocol Level)。

  使用第7个字节:

  

  客户端用8位的无符号值表示协议的版本。对于3.1.1,协议级别值是4(04)。

  如果发现不支持的协议级别,server必须发送一个0x01的ACK报文响应CONNECT报文,然后断开连接。

  3、连接标志(Connect Flags)。

  bit 0  : server必须验证CONNECT的保留标志位(第0位)是否为0,如果不为0必须断开连接。

  bit 1:指定了会话状态的处理方式。用于控制会话状态的生存时间。

    = 0 :server必须基于当前会话的状态恢复与client的通信。如果没有与这个client标识符关联的会话,server必须创建一个新会话。

      在连接断开后,client和server必须保存会话信息。server必须将之后的QoS 1和QoS2级别的消息保存为会话状态的一部分,

      如果这些消息匹配断开连接时client的任何订阅。server也可以保存满足相同条件的QoS 0级别的消息。

    = 1:server和client必须丢弃之前的任何会话,并开始一个新的会话。

      会话仅持续和网络连接同样长的时间。与这个会话关联的状态数据不能被任何之后的会话重用。

      client的会话状态包括:

        • 已经发送给server,但是还没有完成确认的QoS 1 和QoS 2 级别的消息
        • 已从server接收,但是还没有完成确认的QoS 2 级别的消息

      server会话状态包括:

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

  bit 2:遗嘱标志 (Will Flag)

    =1:如果连接请求被接受了,遗嘱消息必须被保存在server端并且与这个网络连接关联。之后网络连接关闭时,server必须发布这个遗嘱消息。

      除非server收到DISCONNECT报文时删除了这个遗嘱消息。

      遗嘱消息发布的条件:

        • server检测到了一个I/O错误或者网络故障
        • client在保持连接的时间内未能通讯
        • client没有先发送DISCONNECT直接关闭了网络连接
        • 由于协议错误server关闭了网络连接

      之后的连接标志Will QoS 和Will Retain字段会被server用到,同是,有效载荷中必须包含Will Topic 和Will Message字段

      一旦被发布或者server收到了client发送的DISCONNECT,遗嘱消息就必须从存储的会话状态中移除。

    =0:之后的连接标志Will QoS 和Will Retain字段必须为0,并且有效载荷中不能包含Will Topic 和Will Message字段。

      网络连接断开时,不能发送遗嘱消息。

      server端应该迅速发布遗嘱消息。在关机或者故障的情况下,server可以推迟遗嘱消息的发布直到之后的重启。

      如果发生了这种情况,在server故障和遗嘱消息被发布之间可能会有一个延迟。

  bit 3-4:遗嘱QoS  Will QoS

    这两位用于指定发布遗嘱消息时使用的服务质量等级。

    值由遗嘱标志位决定:

    Will Flag = 0:它的值必须设置为0。

    Will Flag = 1:它的值可以等于0,1,2。

  bit 5:遗嘱保留 Will Retain

    如果遗嘱消息被发布时需要保留,需要指定这一位的值。

    如果Will Flag = 0:  它的值为 0 ,server必须将遗嘱消息当作非保留信息发布。

    如果 Will Flag = 1: 它的值为 1 ,server必须将遗嘱消息当作保留信息发布。

  bit 6:密码标志  Password Flag 

    =0:有效载荷中不能包含密码字段

    =1:有效载荷中必须包含密码字段

    如果用户名标志为0,它也必须为0

  bit 7:用户名标志 User Name Flag

    =0:有效载荷中不能包含用户名字段

    =1:有效载荷中必须包含用户名字段

  4、保持连接(Keep Alive)。

  使用第9、10字节。

  它是一个以秒为单位的时间间隔,表示为一个16位的字,它是指在client传输完一个控制报文的时刻到发送下一个报文的时刻。

  client负责保证报文发送的时间间隔不超过保持连接的值。如果没有任何其他的报文发送,就必须发送一个PINGREQ报文。

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

  = !0 :如果server在1.5倍的时间内没有收到client的报文,它必须断开连接。

    client在发送了PINGREQ后,如果在合理的时间内没有收到PINGRESP,也应该关闭连接。

  = 0 :表示关闭连接保持的功能。意味着,server不需要因为client不活跃而关闭连接。

    不管保持值为多少,任何时候,只要server认为client是不活跃或无响应的,可以断开client连接。

  可变报头示例:

有效载荷

  CONNECT报文的有效载荷包含一个或多个以长度为前缀的字段,可变报头中的标志决定是否包含这些字段。

  如果包含的话,必须按照这个顺序出现:client标识符,遗嘱主题,遗嘱消息,用户名,密码。

  1、client标识符

  server使用client标识符识别client。

  连接到server的每个client都有唯一的clientID。

  client和server都必须使用clientID识别两者之间的MQTT会话相关的状态。

  clientID必须存在,必须是CONNECT报文有效载荷的第一个字段。

  clientID必须是UTF-8编码字符串。

  server必须允许1到23个字节长的UTF-8编码的clientID,clientID只能包含这些字符:

      “0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ”

  server可以允许编码后超过23个字节的clientID,也可以允许包含不是上面列表字符的clientID。

  如果server拒绝了这个clientID,它必须发送返回码0x02(表示ID不合格)的CONNACK。

  于PUBLISH来说就是消息内容了。

  需要有效载荷的控制报文:CONNECT、SUBSCRIBE、SUBACK、UNSUBSCRIBE。 PUBLISH是可选。

  2、遗嘱主题 

  如果遗嘱标志为1,有效载荷的下一个字段是遗嘱主题,它必须是UTF-8编码字符串。

  3、遗嘱消息

  如果遗嘱标志为1,有效载荷的下一个字段是遗嘱消息。遗嘱消息定义了将被发布到遗嘱主题的应用消息。

  这个字段由一个两字节长度+有效载荷组成。长度给出了跟在后面的数据的字节数,不包含长度字段本身的两个字节。

  遗嘱消息被发布到遗嘱主题时,它的有效载荷只包含这个字段的数据部分,不包含开头的两个长度字节。

  4、用户名

  如果用户名标志为1:有效载荷的下一个字段就是它,server用于身份验证和授权。

  5、密码

  密码字段包含一个两字节的长度字段,长度表示二进制数据的字节数(不包含长度字段本身占用的两个字节),后面跟着0-65535字节的二进制数据。

  密码字节:

响应

  server检查CONNECT报文的内容是不是满足任何进一步的限制,可以执行身份验证和授权检查。     

  如果验证成功,执行下列步骤:

    1. 如果ClientID表明client已经连接到这个server,server必须断开原来的client连接
    2. server按照执行清理会话过程
    3. server发送返回码为0的CONNACK报文作为CONNECT报文的确认响应
    4. 开始消息分发和保持连接状态监视

  允许client在发送CONNECT报文后立即发送其它的控制报文;client不需要等待server的CONNACK报文。

  如果server拒绝了CONNECT,它不能继续处理在CONNECT报文之后发送的任何数据。

-----------------------------------------------------------------------------------------------------------------------

CONNACK-确认连接请求

  server发送给client的第一个报文必须是CONNACK。

  如果client在合理的时间内没有收到CONNACK,client应该关闭连接。(合理的时间取决于应用的类型和通信基础设施)

  固定报头

  报头格式描述如下:

  剩余长度字段表示可变报头的长度。对于CONNACK,这个值是2.

  可变报头

  可变报头描述如下:

  byte 1 :连接确认标志,1-7位是保留,且必须设置为0。第0位是当前会话标志。使server和client在是否有已保存的会话状态上保持一致。

    如果server收到清理会话标志为1的连接,除了将CONNACK报文中的返回码设置为0之外,还必须设置当前会话标志设为0。

    如果server收到清理会话标志为0的连接,它的值取决于server是否保存了clientID对应client的会话状态。如果保存则为1,否则为0。

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

  byte 2 :连接返回码,使用一个字节的无符号值。

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

  连接返回码:

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

  有效载荷

    CONNACK没有载荷

    

MQTT控制---connect的更多相关文章

  1. ESA2GJK1DH1K微信小程序篇: 测试微信小程序APUConfig给WI-Fi模块配网并绑定设备,并通过MQTT控制设备

    前言(源码使用介绍在最后) 一,微信小程序篇小程序下载(该源码为这节测试源代码) 二.有多少人一直在期盼着小程序可以实现SmartConfig或者Airkiss的功能? 来吧!我的这种方式包您满意. ...

  2. MQTT——控制报文格式

    解控制报文格式是学习MQTT中,笔者认为最为重要的一个知识点.MQTT的所有行为都离不开他.控制报文可以分为三个部分组成,分别为:固定报头.可以变报头.有效载荷部分. 注意:上面的说的报文的类型.是指 ...

  3. ESA2GJK1DH1K基础篇: 测试APP扫描Air202上面的二维码绑定通过MQTT控制设备(兼容SIM800)

    前言 此程序兼容SIM800 如果想绑定SIM800,请把其IMEI号,生成二维码,用手机APP扫描. 实现功能概要 APP通过扫描二维码获取GPRS设备的IMEI号,然后设置订阅的主题:device ...

  4. MQTT控制---pingreq

    心跳请求 客户端向服务端发送PINGREQ报文用于: 在没有任何其他控制报文从client发给server时,告诉server,client还活着 请求server发送 响应确认它还活着 使用网络以确 ...

  5. MQTT控制---subscribe

    连接服务端 客户端向服务端发送SUBSCRIBE报文用于创建一个或多个订阅. 固定报头 报头长度:2 Bytes 1.报头控制类型(0x82) 报文SUBSCRIBE控制报固定报头的第3.2.1.0位 ...

  6. ESA2GJK1DH1K微信小程序篇: 测试微信小程序扫描Air202上面的二维码绑定设备,并通过MQTT控制设备

    前言 一,微信小程序篇小程序下载(该功能为小程序篇基础功能源码) 实现功能概要 微信小程序通过扫描GPRS上的二维码,绑定GPRS设备.然后使用小程序通过GPRS远程控制开发板上的继电器, 远程显示单 ...

  7. 转战物联网·基础篇08-例说MQTT协议各控制报文

      前面讨论了MQTT协议的控制报文的格式,下面分别举例探讨各个控制报文的详细内容. 01.CONNECT – 连接服务端   客户端到服务端的网络连接建立后,客户端发送给服务端的第一个报文必须是CO ...

  8. 转战物联网·基础篇07-深入理解MQTT协议之控制报文(数据包)格式

      在MQTT协议中,一个控制报文(数据包)的结构按照前后顺序分如下三部分: 结构名 中文名 解释说明 Fixed header 固定报头 报文的最开始部分,所有报文都包含这个部分 Variable ...

  9. linux下socket connect 阻塞方式 阻塞时间控制

    同事今天问我,如何在linux下的c代码里面控制connect的阻塞时间.应用的背景是:linux下的c程序有两个目标IP需要connect,如果用阻塞方式,当其中一个IP不能连接的情况下,程序将阻塞 ...

随机推荐

  1. Url校验正则

    最近需要对HTTP请求合法性做一些校验,在网上查找了一些关于URL合法性的正则表达式. 在github上的有个关于weburl匹配的gist: https://gist.github.com/dper ...

  2. Spring Boot环境下出现No operations allowed after connection close错误

    一个基于springcloud的微服务项目,详细配置: SpringCloud + SpringMVC+SpringData JPA+ MySql+Postgresql 其中项目配置了多数据源,前期开 ...

  3. git总结二、关于分支上——好好认识下分支是怎么回事

    同样需要先来明确两件事: HEAD指针指向的是当前分支 分支(master, dev)指向的是最新的提交 一开始,git 中只有一个master分支,严格来讲,HEAD不是指向提交而是指向master ...

  4. 缓存,热点key

    热点Key问题的发现与解决 https://help.aliyun.com/document_detail/67252.html 缓存击穿.失效以及热点key问题 https://www.jiansh ...

  5. Android List 排序

    Collections.sort(list, (l1, l2) -> l1.getID().compareTo(l2.getID())); list:泛型集合 l1:比较的前一个泛型 l2:比较 ...

  6. ES6中的Array.from()函数的用法

    ES6为Array增加了from函数用来将其他对象转换成数组. 当然,其他对象也是有要求,也不是所有的,可以将两种对象转换成数组. 1.部署了Iterator(迭代器)接口的对象,比如:Set,Map ...

  7. 【持续跟新】剑指Offer_Java实现

    [第一题 ]二维数组中的查找 package sword_finger_offer; import org.junit.jupiter.api.Test; /** * 剑指offer习题一 二维数组中 ...

  8. Unity 大中华区核心业务

    Unity 大中华区核心业务: UnityTechnologies:引擎技术 UnitySolutions:解决方案 AssetStore:开发插件 UnityGames:发行服务 UnityEduc ...

  9. Mac 下 Eclipse 添加 Dynamic Web Project 并配置 Tomcat

    最近拿到了一个 Dynamic Web Project,我的 Mac 上的 Eclipse 之前没有过这类型的项目,所以导入之后无法正常运行.下面是我记录的如何配置 Eclipse 使之能够运行 Dy ...

  10. Aras简单报表

    1.编辑Report对象类的窗体Report_Tab_Report,将xsl_stylesheet放到窗体上 2.新建报表 3.将编辑好的XSLT复制到xsl_stylesheet中. <xsl ...