IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 对MQTT协议以及COAP协议理解剖析并实现(一) -> 正文阅读

[嵌入式]对MQTT协议以及COAP协议理解剖析并实现(一)

MQTT简介:

????????MQTT协议是在1999年,由IBM的Andy Stanford-Clark 和 Arcom 的 Arlen Nipper为了通过卫星网络连接输油管道的项目开发的,为了满足低电量以及低网络带宽的需求,MQTT协议在设计的初期囊括了以下一些特点:

? ? ? ?1、网络开销小,消息头最小只有2字节,这相比HTTP大大降低了网络流量。
??2、是可保持的会话,为实现服务端及时推消息提供了条件。
??3、是异步消息机制,不会阻塞占用资源。
??4、具备异常中断通知机制,可以获得硬件在线信息变化,及时得到掉线消息。
??5、使用发布/订阅消息模式,一对多或多对一的消息传输,实现与应用程序的解耦。
??6、传输可靠性可控,及三种服务质量,分别是至多一次、至少一次、只有一次。指的是发布者发出的信息,代理服务和订阅者是否收到的情况。
??7、客户端程序够轻量,可在很多嵌入式设备中运行。
??8、可满足低带宽、高延迟、不稳定的网络环境,可传输任意类型的数据。

????在MQTT中,无论是服务端还是客户端,他们都可以有三种身份:发布者、代理、订阅者。

? ? ? ? 在MQTT的通信实现方式是:发布/订阅,而发布与订阅又是基于主题。

????????因为在MQTT协议中,端与端之间是不能直接进行收发信息的,必须通过服务端进行管理分配,而这个服务端就相当于一个“代理”的角色。这个代理的角色所起的作用:进行消息的存储与转发。

? ? ? ? 基于MQTT协议发送消息示例:

? ? ? ? ①发布者连接上MQTT代理

? ? ? ? ②订阅者连接上MQTT代理

? ? ? ? ③订阅者A向MQTT代理订阅TopicA

? ? ? ? ④发布者将一则主题为TopicA的消息发扫描后给MQTT代理

? ? ? ? ⑤MQTT代理收到了发布者的消息,并检查到订阅者A需要接收这个消息,然后把该消息转发给订阅者A

? ? ? ? ⑥订阅者A从MQTT代理接收到消息

?注意:在一个端上,他既可以作为发布者,也能作为订阅者,但一个主题只有一个发布者,但这个主题可以同时被多个订阅者进行订阅,一个客户端也可以同时订阅多个主题。

????????

MQTT协议数据包:

? ? ? ? MQTT协议数据包的消息格式:固定头(必须有)+ 可变头(可有可无)+ 消息(可有可无)

结构体解释数据格式
固定报头报文最开始部分,所有报文都必须有类型 + 标志位 + 剩余长度
可变报头固定报文的附加部分,有些报文没有这个部分报文标识符 + 类型配置
消息体(负载)携带的消息内容,有些报文没有这个部分自定义消息

1、固定报头(Fixed header):

Bit76543210
Byte1(第一个字节)MQTT控制报文的类型控制报文的标志位,相当于属性参数
Byte2(第二个字节)剩余长度,当前报文剩余部分的字节数,包括可变报头和消息体

? ? ? ? 1.1、控制报文类型

? ? ? ? ? ? ? ? 固定报文第一字节的高四位(7 -? 4号bit)是代表控制报文的类型,其具体含义如下:

7-4号bit十进制值报文类型报文允许发起的方向报文描述
00000RESERVED禁止保留,不可用
00011CONNET客户端—→服务端客户端请求连接到服务端的代理服务
00102CONNACK客户端←―服务端连接请求的回复确认报文
00113PUBLISH客户端←→服务端发布主题信息
01004PUBACK客户端←→服务端发布确认,当QoS==1时,对PUBLISH的响应确认
01015PUBREC客户端←→服务端发布收到,当QoS==2时,对PUBLISH的响应确认,是QoS==2实现的第一步
01106PUBREL客户端←→服务端发布释放,当QoS==2时,对PUBREC的响应确认,是QoS==2实现的第二步
01117PUBCOMP客户端←→服务端发布完成,当QoS==2时,对PUBREL的响应确认,是QoS==2实现的第三步
10008SUBSCRIBE客户端―→服务端客户端订阅主题,可一次订阅一个或者多个主题(使用通配符)
10019SUBACK客户端←―服务端订阅完成确认,是对SUBSCRIBE的响应确认
101010UNSUBSCRIBE客户端―→服务端取消订阅,客户端发起的取消某个主题的订阅
101111UNSUBACK客户端←―服务端取消订阅确认,是对UNSUBSCRIBE
110012PINGREQ客户端―→服务端心跳,表示这个数据包是为了通知服务端客户端还在正常连接着
110113PINGRESP客户端←―服务端心跳响应,表示服务端已经成功收到了客户端的心跳
111014DISCONNECT客户端―→服务端断开连接,客户端通知服务端,需要断开当前网络连接
111115RESERVER禁止保留,不可用

?????????1.2、标志位

? ? ? ? ? ? ? ? 固定报文第1个字节的低4位(3 - 0号bit)是代表每个MQTT控制报文类型特定的标志,必须与控制报文类型配套对应使用,否则服务端代理服务会拒绝服务或断开连接,其具体含义如下:

报文类型Bit3BIt2BIt1BIt0
CONNECT0000
CONNACK0000
PUBLISH是否为重复发服务质量高位服务质量低位是否保存消息
PUBACK0000
PUBREC0000
PUBREL0010
PUBCOMP0000
SUBSCRIBE0010
SUBACK0000
UNSUBSCRIBE0010
UNSUBACK0000
PINGREQ0000
PINGRESP0000
DISCONNECT0000

? ? ? ?

????????1.3、第一字节各类型报文具体值

? ? ? ? ? ? ? ? 固定报头的报文类型高4位与标志位的低4位结合起来,最终第一个自己的具体值就是其报文类型所代表的的数值,具体值如下:

报文类型报文作用十六进制
CONNECT连接服务端0x10
CONNACK连接成功确认0x20
PUBLISH新发布等级0不保存

0x30

PUBLISH新发布等级0需保存0x31
PUBLISH新发布等级1不保存0x32
PUBLISH新发布等级1需保存0x33
PUBLISH新发布等级2不保存0x34
PUBLISH新发布等级2需保存0x35
PUBLISH重发等级2不保存0x38
PUBLISH重发等级2需保存0x39
PUBACK等级1发布成功

0x40

PUBREC等级2发布收到0x50
PUBREL等级2发布释放0x62
PUBCOMP等级2发布完成0x70
SUBSCRIBE订阅主题0x82
SUBACK订阅完成确认0x90
UNSUBSCRIBE取消订阅0xA2
UNSUBACK取消完成确认0xB0
PINGREQ心跳包0xC0
PINGRESP心跳回复0xD0
DISCONECT断开网络连接0xE0

? ? ? ? 1.4、剩余长度

? ? ? ? ? ? ? ? 剩余长度在MQTT的协议中,是从第二个字节开始,且最多允许占用4个字节。

? ? ? ? ? ? ? ? 剩余长度描述的是本次发送的消息除去了第一个字节以外,其中的(可变头+消息)的所有字节大小。从固定头的第2字节开始是用于表示MQTT数据包剩余长度的字段,最少为一个字节,最大为四个字节。每一个字节的低7位用于表示剩余长度的大小,范围为0~127。最高的1位是标识位,用于说明是否有后续字节

? ? ? ? ? ? ? ? 若标识为0,代表没有后续字节。

? ? ? ? ? ? ? ? 若标识为1,代表后续还有一个字节用于标识包的长度。

????????????????MQTT协议相应字节数对应的最小、最大包长度如下表所示:

? ? ? ? ? ? ? ? 剩余长度的字节数最小包长度:10字节????????????????(0x00)

????????????????剩余长度的字节数最大包长度:268 435 455字节(0xFF,0xFF,0xFF,0x7F)

????????????????MQTT协议中数据包的剩余长度的最大长度为268435455 字节,约 256M。

????????????????注意:上述的剩余长度不包含固定头的大小,是指(可变头+消息)总长度

? ? ? ? ? ? ? ? 关于剩余长度的变化规则示例:

? ? ? ? ? ? ? ? ①若剩余长度为100,那么我们可以使用1个字节表示,那么这个剩余长度二进制为?01100100。

? ? ? ? ? ? ? ? 其中7号位的0表示没有剩余长度字节了,1100100则表示为(十进制)100

? ? ? ? ? ? ? ? ②若剩余长度为15000,那么我们则需要使用2个字节表示,那么这个剩余长度二进制为

01110101 10011000

? ? ? ? ? ? ? ? 计算的根据是:

? ? ? ? ? ? ? ? ? ? ? ? 128 * 117 + 24 = 15000;

? ? ? ? ? ? ? ? ? ? ? ? 其中128来源是因为第二个字节的最大为0111 1111(127),由于进1的关系,每进1位为128,所以第三个字节的数据为128 * 117 = 14976时最逼近15000,剩余的24由第二个字节表示。

? ? ? ? ? ? ? ? ③第三个字节以此类推...

字节数最大十进制/十六进制(高字节在前)最大二进制(高字节在前)
1127(0x7F)01111111
216383(0x7F,0xFF)01111111 11111111
32097151(0x7F,0xFF,0xFF)01111111?11111111 11111111
4268435455(0x7F,0xFF,0xFF,0xFF)01111111 11111111 11111111 11111111

2、可变头(Variable Header)

????????可变报文头主要包含协议名、协议版本、连接标志、心跳间隔时间、连接返回码、主题名等。

3、消息体(Payload)

? ? ? ? PUBLISH的有效负荷为应用消息,而其他控制报文是否需要包含有效负荷如下:

控制报文报文描述有效负荷
CONNECT客户端请求连接到服务端的代理服务需要
CONNACK连接请求的回复确认报文不需要
PUBLISH发布主题信息可选,可以为0
PUBCAK发布确认,当QoS==1时,对PUBLISH的响应确认不需要
PUBREC发布收到,当QoS==2时,对PUBLISH的响应确认,是QoS==2实现的第一步不需要
PUBREL发布释放,当QoS==2时,对PUBREC的响应确认,是QoS==2实现的第二步不需要
PUBCOMP发布完成,当QoS==2时,对PUBREL的响应确认,是QoS==2实现的第三步不需要
SUBSCRIBE客户端订阅主题,可一次订阅一个或者多个主题(使用通配符)需要
SUBACK订阅完成确认,是对SUBSCRIBE的响应确认不需要
UNSUBSCRIBE取消订阅,客户端发起的取消某个主题的订阅需要
UNSUBACK取消订阅确认,是对UNSUBSCRIBE不需要
PINGREQ心跳,表示这个数据包是为了通知服务端客户端还在正常连接着不需要
PINGRESP心跳响应,表示服务端已经成功收到了客户端的心跳不需要
DISCONNECT断开连接,客户端通知服务端,需要断开当前网络连接不需要

如有写得不对的地方,敬请指出!

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-02-03 01:20:18  更:2022-02-03 01:21:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:33:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码