前言

紧接着上篇初步介绍,本文为第二篇,主要梳理MQTT-SN 1.2协议中定义的消息格式。

通用消息格式

消息头 其它可变部分
2/4字节表示 N字节组成

消息头部

长度 消息类型
1或3个字节 1个字节
  • 长度要么是1个字节,要么3个字节表示,并且自身也会包含在其内。一个字节可表示256长度,一般情况下,完全够用了。
  • 只需要判断第一个字节是否为 0x01,若是那么长度为3个字节表示,剩下的两个字节会表示真正的消息长度,最大长度为65535
  • 否则长度就是一个字节表示,256个长度,大部分消息长度都是一个字节,除非特别提醒

备注:

 MQTT-SN不支持消息的分片和重组。底层网络所定义数据包长度若小于MQTT-SN消息的最大长度,自身进行的分片和重组,对MQTT-SN协议本身不受影响。

MQTT-SN消息类型

MQTT-SN定义的消息类型数量众多,超过25个,感觉有些头大。

消息类型值 消息类型名称 说明
0x00 ADVERTISE 广播消息
0x01 SEARCHGW 寻找网关
0x02 GWINFO 网关信息
0x03 reserved 没有使用到
0x04 CONNECT 发起连接
0x05 CONNACK 连接确认
0x06 WILLTOPICREQ 遗嘱主题请求
0x07 WILLTOPIC 遗嘱主题确认
0x08 WILLMSGREQ 遗嘱消息请求
0x09 WILLMSG 遗嘱消息确认
0x0A REGISTER 注册主题
0x0B REGACK 注册确认
0x0C PUBLISH 发布消息
0x0D PUBACK 发布确认
0x0E PUBCOMP 发布环节消息
0x0F PUBREC 发布环节消息
0x10 PUBREL 发布环节消息
0x11 reserved 保留字段
0x12 SUBSCRIBE 订阅主题
0x13 SUBACK 订阅确认
0x14 UNSUBSCRIBE 退订
0x15 UNSUBACK 退订确认
0x16 PINGREQ Ping请求
0x17 PINGRESP Ping响应
0x18 DISCONNECT 断开
0x19 reserved 保留字段
0x1A WILLTOPICUPD 遗嘱主题更新
0x1B WILLTOPICRESP 遗嘱主题更新确认
0x1C WILLMSGUPD 遗嘱消息更新
0x1D WILLMSGRESP 遗嘱消息更新确认
0x1E-0xFD reserved 保留字段
0xFE 转发封装标志 用于转发

消息可变部分

可变字段很多,与MQTT相比,多了:

  1. 持续时长字段(Duration)
  2. 标识符Flags有所不同,下面表格进行说明
  3. 网关地址(GwAdd),可变长度,但依赖于底层网络,在ZigBee网络中2个字节长度
  4. 一个字节网关Id(GwId)
  5. 协议Id(ProtocolId),一个字节,唯一值 0x01,统一表示协议名称和协议名称
  6. 广播路径跳数(广播路径深度/广播辐射范围),Radius,一个字节表示,0x00表示广播给当前网络中所有节点
  7. CONNECT/REGISTER/SUBSCRIBE/PUBLISH等消息对应回执中都会包含返回码Recode Code,见下表格
返回值 返回值含义
0x00 接受请求(Accepted)
0x01 因拥塞拒绝(Rejected: congestion),一般需要接收方等待T_WAIT时间长
0x02 因非法主题标识符拒绝(Rejected: invalid topic ID)
0x03 因不支持拒绝(Rejected: not supported)
0x04 - 0xFF 保留,没有使用到

具体消息格式说明

网关周期性会对当前网络下所有客户端、节点进行广播,用于客户端发现可用网关。

字节索引 表示内容 说明
0 Length 0x05
1 MsgType 0x00
2 GwId 网关需要吧自身标识符包含其中
3-4 Duration 网关的下次广播间隔时长,单位秒

SEARCHGW

字节索引 表示内容 说明
0 Length 0x03
1 MsgType 0x01
2 Radius 广播半径深度,同时也是只是给当前网络传输层

客户端主动寻找网关进行广播的消息,广播路径范围受限于当前网络环境下的客户端部署密度,比如只有1跳广播在非常密集的网络环境下客户端都可以彼此互相访问。

GWINFO

字节索引 表示内容 说明
0 Length 动态确定
1 MsgType 0x02
2 GwId 网关Id
3-n GwAdd* 一个网关地址,仅仅由客户端发出消息时,此字段才存在

GWINFO作为对SEARCHGW消息的响应:

  • 若由网关发出,则无GwAdd字段
  • 若来自于客户端,需要包含网关地址

CONNECT

客户端向网关发出建立连接的消息。

字节索引 表示内容 说明
0 Length 动态计算
1 MsgType 0x04
2 Flags 标志位
3 ProtocolId 0x01,表示协议版本和协议名称
4-5 Duration 存活持续时长
6-n ClientId 客户端标识符,1-23个字节表示的字符串

在CONNECT消息标志位具体表示如下:

DUP QoS Retain Will CleanSession TopicIdType
bit 7 6,5 4 3 2 1,0
X X X 0/1 0/1 X
  • 0/1 表示具体值待定
  • X 表示没有使用到

在Flags中使用到的标志位:

  1. Will:若为1,客户端会在稍后请求遗嘱主题和遗嘱消息
  2. CleanSession:不但表示订阅持久化,同时也被可扩展到遗嘱主题和遗嘱消息中

CONNACK

网关对客户端发出CONNECT消息的响应。

字节索引 表示内容 说明
0 Length 0x03
1 MsgType 0x05
2 ReturnCode 接受值0x00,拒绝为0x01-0x03,具体见上文RecodeCode定义

WILLTOPICREQ

根据客户端CONNECT标志位中WILL字段为true情况下,网关向客户端发出遗嘱主题请求,格式如下:

字节索引 表示内容 说明
0 Length 0x02
1 MsgType 0x06

只有头部部分,很简单。

WILLTOPIC

客户端作为网关WILLTOPICREQ请求响应消息。下面是一个正常版本的WILLTOPIC消息:

字节索引 表示内容 说明
0 Length 动态计算
1 MsgType 0x07
2 Flags 标志位
3-n WillTopic 遗嘱主题

此时的标志位如下

DUP QoS Retain Will CleanSession TopicIdType
bit 7 6,5 4 3 2 1,0
X 0x00-0x02 0/1 X X X

而空的WILLTOPIC也是允许存在的,就两个字节表示,用于客户端请求删除已存在于服务器端的对应遗嘱主题和消息。

字节索引 表示内容 说明
0 Length 0x02
1 MsgType 0x07

WILLMSGREQ

根据客户端CONNECT标志位中WILL字段为真情况下,网关向客户端发出遗嘱消息请求,格式如下:

字节索引 表示内容 说明
0 Length 0x02
1 MsgType 0x08

只有头部部分,没有别的。

WILLMSG

客户端对网关WILLMSGREQ请求的响应,从而把遗嘱消息传递给网关进行保存。

字节索引 表示内容 说明
0 Length 动态计算
1 MsgType 0x09
2-n WillMsg 客户端遗嘱

REGISTER

  • 客户端-->网关,请求主题(topic name)对应的主题标识符(topic id)
  • 网关-->客户端,通知主题(topic name)已经被指派到某个主题标识符(topic id)
字节索引 表示内容 说明
0 Length 动态计算
1 MsgType 0x0A
2-3 TopicId 客户端发出,此值为0x0000;服务器发出,需要包含对应于Topic Name的主题标识符
4-5 MsgId 自然数,用以标识对应的REGACK确认
6-n TopicName 主题名称,不能太长,尽量不要使用通配符

REGACK

客户端或网关针对REGISTER消息的响应。

字节索引 表示内容 说明
0 Length 0x07
1 MsgType 0x0B
2-3 TopicId 对应于Topic Name的主题标识符,被用于PUBLISH消息发布
4-5 MsgId 自然数,用以标识对应的REGISTER消息
6 ReturnCode 0x00被接受,其它值被拒绝

PUBLISH

PUBLISH消息用于客户端或网关发布消息用:

字节索引 表示内容 说明
0 Length 动态计算
1 MsgType 0x0C
2 Flags 标志位
3-4 TopicId 主题标识符
5-6 MsgId QoS 1-2时需要填充自然值;QoS 0时,值为0x0000
7-n Data 用于发布的具体消息内容

标识位具体如下:

DUP QoS Retain Will CleanSession TopicIdType
bit 7 6,5 4 3 2 1,0
0/1 0x00-0x02 0/1 X X 0b00/0b01/0b10

标识位里面各个字段和MQTT协议一致,无须多解释。

PUBACK

客户端/网关仅仅对QoS 1/2的PUBLISH消息做出响应。

字节索引 表示内容 说明
0 Length 0x07
1 MsgType 0x0D
2-3 TopicId 对应PUBLISH消息中TopicId
4-5 MsgId 自然数,用以标识对应的REGISTER消息
6 ReturnCode 0x00被接受,其它值被拒绝,不同值表示不同拒绝理由

处理PUBLISH消息异常?在PUBACK消息中的ReturnCode字段中以相应值体现出来,这就要求接收者处理拒绝理由。

PUBREC, PUBREL, PUBCOMP

只有在PUBLISH消息中QoS 2时,PUBREC, PUBREL, PUBCOMP才会一起登场,否则是没有出场机会的。消息格式嘛,都很统一:

字节索引 表示内容 说明
0 Length 0x04
1 MsgType 0x0F/0x10/0x0E
2-3 MsgId 对应PUBLISH消息中的MsgId

SUBSCRIBE

SUBSCRIBE用于客户端订阅某个主题的消息。

字节索引 表示内容 说明
0 Length 动态计算
1 MsgType 0x12
2 Flags 标志位
3-4 MsgId 用于确定对应的订阅确认SUBACK消息
5-N TopicId/TopicName 具体需要根据Flags标志位中TopicIdType进行填充

标识位具体如下:

DUP QoS Retain Will CleanSession TopicIdType
bit 7 6,5 4 3 2 1,0
0/1 0x00-0x02 X X X 0b00/0b01/0b10

此处,标志位中TopicIdType决定了SUBSCRIBE消息中TopicId/TopicName字段具体填充值:预定义topic id,或短小两个字符表示主题(topic name),或直接填写主题。

SUBACK

网关->客户端,订阅处理情况的确认回执,接受订阅或出于其它原因拒绝之。

字节索引 表示内容 说明
0 Length 0x08
1 MsgType 0x13
2 Flags 标志位
3-4 TopicId 网关接受其注册,此处对应具体指派的TopicId
5-6 MsgId SUBSCRIBE消息中对应MsgId值
7 ReturnCode 0x00被接受,其它值被拒绝

标识位具体如下:

DUP QoS Retain Will CleanSession TopicIdType
bit 7 6,5 4 3 2 1,0
X 0x00-0x02 X X X X

SUBACK消息标志位中QoS为网关根据实际情况授权后的QoS具体值,这也应该是客户端需要知道并处理的。

UNSUBSCRIBE

UNSUBSCRIBE用于客户端取消订阅某个主题的消息。

字节索引 表示内容 说明
0 Length 动态计算
1 MsgType 0x14
2 Flags 标志位
3-4 MsgId 用于确定对应的退订确认UNSUBACK消息
5-N TopicId/TopicName 具体需要根据Flags标志位中TopicIdType进行填充

标识位具体如下:

DUP QoS Retain Will CleanSession TopicIdType
bit 7 6,5 4 3 2 1,0
X X X X X 0b00/0b01/0b10

UNSUBSCRIBE消息标志位中唯一可用属性TopicIdType决定了UNSUBSCRIBE消息中TopicId/TopicName字段具体填充值。

UNSUBACK

网关->客户端,取消订阅处理情况的确认回执,很简单,4个字节表示。

字节索引 表示内容 说明
0 Length 0x04
1 MsgType 0x15
2-3 MsgId UNSUBSCRIBE消息中对应MsgId值

PINGREQ

和MQTT协议中的PINGREQ一致,存活检测。

字节索引 表示内容 说明
0 Length 动态计算
1 MsgType 0x16
2-N ClientId 可选项,表示客户端休眠状态转换为唤醒状态用于检查网关是否为其缓存消息

PINGRESP

接受PINGREQ消息的一方,如网关响应PINGRESP消息表示自己现在运行OK。

另外一个意图,若唤醒状态客户端发送PINGREQ消息之后,直接收到PINGRESP消息,表示网关当前暂时没有为其缓存的消息可供发送。

字节索引 表示内容 说明
0 Length 0x02
1 MsgType 0x17

很简单,两个字节表示足矣。

DISCONNECT

字节索引 表示内容 说明
0 Length 动态计算
1 MsgType 0x18
2-3 Duration 可选项,表示客户端即将进入睡眠状态的持续时间值
  • 客户端->网关,客户端主动关闭当前连接,网关响应确认消息。只有表示自己进入睡眠状态的客户端,才会在DISCONNECT消息中附加Duration持续字段。
  • 网关->客户端,网关由于异常主动通知客户端关闭两者之间连接,客户端接收到DISCONNECT时需要发送CONNECT消息到网关,重试重新建立连接。没有Duration字段填充。

网关接收到要进入休眠状态的客户端发送的包含有Duration字段DISCONNECT消息时,可以直接返回2个字节的(不能包含有Duration字段)DISCONNECT消息以示确认。

WILLTOPICUPD

客户端发送请求网关更新其遗嘱主题。

字节索引 表示内容 说明
0 Length 动态计算
1 MsgType 0x1A
2 Flags 标志位
3-N WillTopic 用于更新的遗嘱主题

标识位具体如下:

DUP QoS Retain Will CleanSession TopicIdType
bit 7 6,5 4 3 2 1,0
X 0x00-0x02 0/1 X X X

协议规定只有两个字节空WILLTOPICUPD也是允许存在的,存在意义用于客户端请求网关删除已保存的遗嘱主题和遗嘱消息等。

字节索引 表示内容 说明
0 Length 0x02
1 MsgType 0x1A

WILLTOPICRESP

WILLTOPICRESP为网关收到WILLTOPICUPD后作出的应答消息。

字节索引 表示内容 说明
0 Length 0x03
1 MsgType 0x1B
2 ReturnCode 0x00被接受,其它值被拒绝

WILLMSGUPD

字节索引 表示内容 说明
0 Length 动态计算
1 MsgType 0x1C
2-N WillMsg 用于更新的遗嘱消息

客户端->网关,确认更新的遗嘱消息。

WILLMSGRESP

WILLMSGRESP为网关收到WILLMSGUPD后作出的应答消息。

字节索引 表示内容 说明
0 Length 0x03
1 MsgType 0x1D
2 ReturnCode 0x00被接受,其它值被拒绝

转发封装

在MQTT-SN架构图中,MQTT-SN Forwarder转发器适用于客户端无法直接访问网关或当前传感器网络区域中不存在网关时,转发器作用就体现出来了:

  1. 接收MQTT-SN客户端消息封装后转发给上游网关
  2. 解封上游网关所发送消息,直接发送给对应客户端

转发器作用于消息的封装转发,解封发送,针对消息不做修改。

转发器对MQTT-SN消息封装格式:

字节索引 表示内容 说明
0 Length 十进制表示长度就是N
1 MsgType 0xFE
2 Ctrl 包含网关和转发器之间的控制交换信息,主要是前两位包含了半径范围
3-N Wireless Node Id 标识所发目的或需要接收封装消息的无线节点
N+1-M MQTT-SN message 一个MQTT-SN消息消息

无线节点Id(Wireless Node Id):

  • 转发器->网关,无线节点Id为转发器所在的无线节点Id,便于告知网关转发器位置
  • 网关->转发器,无线节点Id为网关的无线节点Id

控制交换字段Ctrl,单个字节,位表示含义:

bit 7,2 1,0
X 0x00-0x03

小结

MQTT-SN 1.2规范中所定义消息格式介绍完毕,下一篇将对MQTT-SN主要流程功、能进行阐述。

原文 http://www.blogjava.net/yongboy/archive/2015/01/08/422142.html

MQTT-SN协议乱翻之消息格式的更多相关文章

  1. MQTT-SN协议乱翻之功能描述

    前言 紧接上文,这是第三篇,主要是对MQTT-SN 1.2协议进行总体性功能描述. 嗯,这一部分可以结合着MQTT协议对比着来看. 网关的广播和发现 网关只能在成功连接到MQTT Server之后,才 ...

  2. 详解FIX协议的原理、消息格式及配置开发

    一.定义 FIX协议是由国际FIX协会组织提供的一个开放式协议,目的是推动国际贸易电子化的进程,在各类参与者之间,包括投资经理.经纪人,买方.卖方建立起实时的电子化通讯协议.FIX协议的目标是把各类证 ...

  3. 网络协议之:WebSocket的消息格式

    目录 简介 WebSocket的握手流程 webSocket的消息格式 Extensions和Subprotocols 总结 简介 我们知道WebSocket是建立在TCP协议基础上的一种网络协议,用 ...

  4. MQTT-SN协议乱翻之小结篇

    前言 这里简单做一些小结和对比,针对前面的协议翻译部分,一阶段的学习完结. MQTT-SN VS MQTT MQTT-SN基于MQTT原有语义,但做了很多的调整.比如: 一个CONNECT消息被拆分为 ...

  5. MQTT-SN协议乱翻之简要介绍

    前言 这一段时间在翻看MQTT-SN的协议,对针对不依赖于TCP传输的MQTT协议十分感兴趣,总是再想着这货到底是怎么定义的.一系列文章皆有MQTT-SN 1.2协议所拼装组成,原文档地址: MQTT ...

  6. MQTT-SN协议乱翻之实现要点

    前言 本篇是MQTT-SN 1.2协议最后一篇翻译了,主要涉及实现要点,很简短. 需要支持QoS 值为 -1 QoS虽默认设置有0,1,2三个值,但还有一种情况其值为-1.来自客户端的PUBLISH消 ...

  7. CORBA GIOP消息格式学习

    想要深入理解ORB的工作过程与原理,学习与了解GIOP消息格式必不可少.我们知道GIOP是独立于具体通信的更高级别的抽象,因此这里针对GIOP在TCP/IP上的实现IIOP协议进行学习与分析(IIOP ...

  8. Kafka的消息格式

    Commit Log Kafka储存消息的文件被它叫做log,按照Kafka文档的说法是: Each partition is an ordered, immutable sequence of me ...

  9. 物联网时代-跟着Thingsboard学IOT架构-MQTT设备协议

    Thingsboard的MQTT设备协议 thingsboard官网: https://thingsboard.io/ thingsboard GitHub: https://github.com/t ...

随机推荐

  1. OK335xS 256M 512M nand flash make ubifs hacking

    /********************************************************************************* * OK335xs 256M 51 ...

  2. [Linux应用]Linux应用程序输出数据重定向到文件中

    转自:http://blog.chinaunix.net/uid-20680966-id-4698387.html 目的是要让程序的printf的打印能重定向到某个文本中,ctrl+c强制退出后查看文 ...

  3. Android—— Intent参数this问题

    Android Intent参数this问题 (2013-04-02 11:19:48) 转载▼ 标签: android intent 分类: Android 转自:http://blog.csdn. ...

  4. HDU 5289 Assignment(多校2015 RMQ 单调(双端)队列)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5289 Problem Description Tom owns a company and he is ...

  5. jquery 新建的元素事件绑定问题研究[转]

    原文:http://www.cnblogs.com/linzheng/archive/2010/10/17/1853568.html js的事件监听跟css不一样,css只要设定好了样式,不论是原来就 ...

  6. 【转】MFC WM_CTLCOLOR 消息

    WM_CTLCOLOR消息用来完成对EDIT, STATIC, BUTTON等控件设置背景和字体颜色, 其用法如下: 1.首先在自己需要设置界面的对话框上点击右键-->建立类向导-->加入 ...

  7. C++函数的高级特性

    对比于 C 语言的函数,C++增加了重载(overloaded).内联(inline).const 和 virtual 四种新机制.其中重载和内联机制既可用于全局函数也可用于类的成员函数,const ...

  8. CentOS 7拨号上网(ADSL & PPPoE)

    步骤概述: 1.搜寻PPPoE相关软件,本人使用的是rp-pppoe yum search pppoe 2.使用yum安装rp-pppoe yum install rp-pppoe -y 3.开始配置 ...

  9. 说一下zoom:1的原理,万一被问到呢?

    某一天.前同事低着头从鹅厂面试回来.他说他被一道非经常见的问题难倒了. 对方问他知道zoom:1的作用吗? 前同事:清楚浮动啊,触发haslayout. 再问:那你知道zoom:1的工作原理和来龙去脉 ...

  10. Altera特殊管脚的使用(适用全系列Altera FPGA,MSEL区别除外)-来自altera论坛

    1.I/O, ASDO  在AS 模式下是专用输出脚,在PS 和JTAG 模式下可以当I/O 脚来用.在AS 模式下,这个脚是CII 向串行配置芯片发送控制信号的脚.也是用来从配置芯片中读配置数据的脚 ...