MQTT-SN协议乱翻之消息格式
前言
紧接着上篇初步介绍,本文为第二篇,主要梳理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相比,多了:
- 持续时长字段(Duration)
- 标识符Flags有所不同,下面表格进行说明
- 网关地址(GwAdd),可变长度,但依赖于底层网络,在ZigBee网络中2个字节长度
- 一个字节网关Id(GwId)
- 协议Id(ProtocolId),一个字节,唯一值 0x01,统一表示协议名称和协议名称
- 广播路径跳数(广播路径深度/广播辐射范围),Radius,一个字节表示,0x00表示广播给当前网络中所有节点
- 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中使用到的标志位:
- Will:若为1,客户端会在稍后请求遗嘱主题和遗嘱消息
- 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转发器适用于客户端无法直接访问网关或当前传感器网络区域中不存在网关时,转发器作用就体现出来了:
- 接收MQTT-SN客户端消息封装后转发给上游网关
- 解封上游网关所发送消息,直接发送给对应客户端
转发器作用于消息的封装转发,解封发送,针对消息不做修改。
转发器对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协议乱翻之消息格式相关推荐
- 网络协议之:WebSocket的消息格式
文章目录 简介 WebSocket的握手流程 webSocket的消息格式 Extensions和Subprotocols 总结 简介 我们知道WebSocket是建立在TCP协议基础上的一种网络协议 ...
- MQTT-SN协议乱翻之实现要点
前言 本篇是MQTT-SN 1.2协议最后一篇翻译了,主要涉及实现要点,很简短. 需要支持QoS 值为 -1 QoS虽默认设置有0,1,2三个值,但还有一种情况其值为-1.来自客户端的PUBLISH消 ...
- 计算机网络学习笔记(28. Email消息格式与POP协议)
1. Email消息格式 2. Email消息格式:多媒体扩展 3. 邮件访问协议 4. POP协议 "下载并删除"模式 i.用户如果换了客户端软件,无法重读该邮件 "下 ...
- dubbo协议报文消息格式
一般协议头关键因素 1,协议用途标志 2,协议id 3,消息长度 4,协议类型(请求/响应) 5,响应状态 dubbo默认采用netty进行网络传输,协议中对字节流的处理在com.alibaba.du ...
- NDEF消息格式(翻译版)
转自百度文库 1 概览 国际标准ISO / IEC 18092 ,近场通信 - 接口和协议( NFCIP -1),定义了一个接口和协议用于工作在13.56MHz的设备间进行近距离.简单的无线互连 ...
- Kafka的消息格式
Commit Log Kafka储存消息的文件被它叫做log,按照Kafka文档的说法是: Each partition is an ordered, immutable sequence of me ...
- CORBA GIOP消息格式学习
想要深入理解ORB的工作过程与原理,学习与了解GIOP消息格式必不可少.我们知道GIOP是独立于具体通信的更高级别的抽象,因此这里针对GIOP在TCP/IP上的实现IIOP协议进行学习与分析(IIOP ...
- MQTT 物联网协议
目录 MQTT 简介 MQTT 协议(上) MQTT 通信基本原理 连接MQTT 服务端 CONNECT 请求报文 CONNACK 回复报文 断开连接 发布消息.订阅主题与取消订阅主题 PUBLISH ...
- 基于MQTT应用层协议的物联网家庭温湿度监测系统
引言 出生于互联网时代的我们,见证了智能手机和个人电脑通过计算机网络互相进行连接,把每个人紧密地连接在一起,形成了一个地球村.而今,我们即将迈入5G时代,在通信技术不断发展的今天,连接到互联网的将不仅 ...
最新文章
- CPU和GPU跑深度学习差别有多大?
- React Native登录注册页面实现空白处收起键盘
- 陈炳藻用计算机研究,计算机闯入“大观园”
- 批量打印html文档,web页面的单页打印以及批量打印实现方法
- c语言xml字符串,C语言的XML解析器
- mac 完全卸载vscode
- 问题 J: Sequence Problem (II) : Array Practice
- mexcuda中矩阵数据的传输
- linux创建云主机内存不足,云主机DC2 Linux系统CPU与内存占用率高导致无法登录
- Python 数据结构与算法——侏儒排序
- bootstrap按钮组(二)
- win7美化_Windows桌面美化记(二)这可能是你看过最详细的美化教程
- 我的TLS1.3之旅
- 6. LaTeX 参考文献的排版与引用
- PUN ☀️九、玩家网络实例化与昵称显示
- 05--SpringBoot之上传文件
- Python批量处理lrmx格式文档内指定内容
- dfs之解救小哈-c语言
- 箭头函数与普通函数,以及使用场景
- 天龙八部与珍珑(文/《北京青年报》记者 郭婷婷)
热门文章
- mysql拒绝访问root用户_设置mysql的root用户允许远程登录
- java 定时器delay_技术贴-java 定时器
- 请求的站点不可用或找不到_公厕再不是“找不到、用不了、坐不下”
- python的threading库_python标准库介绍——31 threading 模块详解
- html5 子标题栏,HTML5 建构主义标题栏页面模板
- 跳转到_301跳转常见问题汇总
- matlab数学实验课件4,数学实验4_数学实验_doc_大学课件预览_高等教育资讯网
- python16进制转2进制流_将十六进制文件转换为二进制文件
- php excel 导入 显示,php Excel 导入
- 发那科pmc编程手册_如何学习FANUC PMC功能指令