mqtt通讯协议

    科技2025-07-18  11

    MQTT

    最近进入一家物联网公司,物联网是基于MQTT协议进行通讯的,利用国庆假期时间学习了一下,做了个笔记。

    文章目录

    MQTT简介特点MQTT是那一层的协议原理MQTT协议实现方式网络传输与应用消息MQTT客户端MQTT服务器MQTT协议中的订阅、主题、会话MQTT协议中的方法 MQTT消息格式固定头可变头负载 MQTT和TCP的区别

    简介

    MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅模式的轻量级通讯协议,构建于TCP/IP协议上,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。

    MQTT是一个基于客户端-服务端的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的。适用范围非常广泛:机器与机器(M2M)通信和物联网(IOT)。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jimbxJkk-1602128712012)(C:\Users\23990\AppData\Roaming\Typora\typora-user-images\1601990026352.png)]

    特点

    采用发布/订阅的消息模式,可以提供一对多的消息发布,解除应用程序耦合。轻量级,网络开销小对负载内容会有屏蔽的消息传输有三种消息发布质量(QoS) qos = 0:“至多一次”,这一级别会发生消息丢失或重复,消息发布依赖于TCP/IP 网络qos = 1:“至少一次”,确保消息到达,但消息重复可能会发生qos = 2:“只有一次”,确保消息到达一次 通知机制,异常中断时会通知双方

    MQTT是那一层的协议

    TCP/IP参考模型可分为四层:应用层、传输层、网络层、链路层。TCP和UDP位于传输层,应用层常见的协议有HTTP、FTP、SSH等。MQTT协议运行与TCP之上,属于应用层协议。

    原理

    MQTT协议实现方式

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r0GmLwec-1602128712015)(C:\Users\23990\AppData\Roaming\Typora\typora-user-images\1601995055877.png)]

    MQTT协议有三种身份:发布者、代理、订阅者,发布者和订阅者为客户端,代理为服务器,同时消息的发布者也可以是订阅者(为了节约内存和流量发布者和订阅者一般都会定义在一起)。

    MQTT传输的消息分为:主题(Topic)和负载(payload)两部分:

    Topic:可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题的消息内容(payload)payload:可以理解为消息的内容,是指订阅者具体要使用的内容。

    网络传输与应用消息

    MQTT会构建底层网络传输:他讲简历客户端到服务器的链接,提佛那个两者之间的一个有序的、无损的、基于字节流的双向传输。

    当应用数据用过MQTT网络发送时,MQTT会把与之相关的服务质量(QoS)和主题名(Topic)相关联。

    MQTT客户端

    一个使用MQTT协议的应用程序或者设备,它总是建立到服务器的网络连接。客户端可以:

    发布其他客户端可能会订阅的信息; //发布消息订阅其他客户端发布的消息; //订阅消息退订或删除应用程序的消息; //退订消息断开与服务器连接 //断开,连接服务器

    MQTT服务器

    MQTT服务器已成为**“消息代理 ”(Broker)**,可以是一个应用程序或一台设备。他是位于消息发布者和订阅者之间,可以:

    接收来自客户的网络连接; //接收客户端连接接收客户发布的应用消息; //接收客户端发布的消息处理来自客户端的订阅和退订请求; //处理消息的订阅及退订向订阅的客户转发应用程序消息。 //推送消息

    MQTT协议中的订阅、主题、会话

    订阅(Subscription)

    订阅包含主题筛选器(Topic Filter)和最大服务质量(QoS)。订阅会与一个会话(Session)关联。一个会话可以包含多个订阅。每一个会话中的每个订阅都有一个不同的主题筛选器。

    会话(Session)

    每个客户端与服务器建立连接后就是一个会话,客户端和服务器之间有状态交互。会话存在于一个网络之间,也可能在客户端和服务器之间跨越多个连续的网络连接。

    主题名(Topic Name)

    连接到一个应用程序消息的标签,该标签与服务器的订阅相匹配。服务器会将消息发送给订阅所匹配标签的每个客户端。

    主题筛选器(Topic Filter)

    一个对主题名通配符筛选器,在订阅表达式中使用,表示订阅锁匹配到的多个主题。

    负载(Payload)

    消息订阅者锁具体接收的内容。

    MQTT协议中的方法

    MQTT协议中定义了一些方法(也被称为动作),来于表示对确定资源所进行操作。这个资源可以代表预先存在的数据或动态生成数据,这取决于服务器的实现。通常来说,资源指服务器上的文件或输出。主要方法有:

    (1)Connect。等待与服务器建立连接。

    (2)Disconnect。等待MQTT客户端完成所做的工作,并与服务器断开TCP/IP会话。

    (3)Subscribe。等待完成订阅。

    (4)UnSubscribe。等待服务器取消客户端的一个或多个topics订阅。

    (5)Publish。MQTT客户端发送消息请求,发送完成后返回应用程序线程。

    MQTT消息格式

    每条MQTT命令消息的消息头都包含一个固定的报头,有些消息会携带一个可变报文头和一个负载。

    固定报文头 | 可变报文头 | 负载

    固定头(Fixed header):存在于所有的MQTT数据包中,表示数据包类型及数据包的分组类标识。

    可变头(Variable header):存在于部分MQTT数据包中,数据包类型决定了可变头是否存在及其具体内容。

    负载(Payload):存在于部分MQTT数据包中,表示客户端收到的具体内容。

    固定头

    MQTT固定头存在于所有MQTT数据包中:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9AMrHIff-1602128712016)(C:\Users\23990\AppData\Roaming\Typora\typora-user-images\1601996621578.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-es4I8uLX-1602128712019)(C:\Users\23990\AppData\Roaming\Typora\typora-user-images\1601997024636.png)]

    MQTT数据包类型(MessageType)0和15保留,共4个字节

    位置:Byte 1中 bits 7-4

    相于一个4位的无符号值,类型、取值及描述如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xAiMi2SU-1602128712020)(C:\Users\23990\AppData\Roaming\Typora\typora-user-images\1601996715898.png)]

    标识位

    位置:Byte 1中bits 3-0。

    在不使用标识位的消息类型中,标识位被作为保留位。如果收到无效的标志时,接收端必须关闭网络连接:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gbug69sP-1602128712021)(C:\Users\23990\AppData\Roaming\Typora\typora-user-images\1601996923297.png)]

    (1)DUP:发布消息的副本。用来在保证消息的可靠传输,如果设置为1,则在下面的变长中增加MessageId,并且需要回复确认,以保证消息传输完成,但不能用于检测消息重复发送。

    (2)QoS:发布消息的服务质量,即:保证消息传递的次数

    ​ Ø00:最多一次,即:<=1

    ​ Ø01:至少一次,即:>=1

    ​ Ø10:一次,即:=1

    ​ Ø11:预留

    (3)RETAIN: 发布保留标识,表示服务器要保留这次推送的信息,如果有新的订阅者出现,就把这消息推送给它,如果设有那么推送至当前订阅者后释放。

    剩余长度(Remaining Length)

    地址:Byte 2

    固定头的第二字节用来保存边长头部和消息体的总大小的,但不是直接保存的。这一字节是可以扩展,其保存机制,前7位用于保存长度,后一部用做标识。当最后一位为1时,表示长度不足,需要使用二个字节继续保存。

    举例:

    即如果计算出后面的大小为0<length<=127的,正常保存

    如果是127<length<16383的,则需要二个字节保存了,将第一个字节的最大的一位置1,表示未完。然后第二个字节继续存。

    拿130来说,第一个字节存10000011,第二个字节存000000001,也就是0x83,0x01,把两个字节连起来看,第二个字节权重从2的8次开始。

    可变头

    MQTT数据包中包含一个可变头,它位于固定头和负载之间。可变头的内容因数据包类型二不同,较常见的应用是作为包的标识:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-86FpRes4-1602128712022)(C:\Users\23990\AppData\Roaming\Typora\typora-user-images\1601997789106.png)]

    很多类型数据包中都包括一个2字节的数据包标识字段,这些类型的包有:PUBLISH (QoS > 0)、PUBACK、PUBREC、PUBREL、PUBCOMP、SUBSCRIBE、SUBACK、UNSUBSCRIBE、UNSUBACK。

    1、首先最上面的8个字节是Protocol Name(编码名),UTF编码的字符“MQIsdp”,头两个是编码名提长为6。

    这里多说一些,接下去的协议多采用这种方式组合,即头两个字节表示下一部分的长,然后后面跟上内容。这里头两个字节长为6,下面跟6个字符“MQIsdp”。

    2、Protocol Version,协议版本号,v3 也是固定的。

    3、Connect Flag,连接标识,有点像固定头部的。8位分别代表不同的标志。第1个字节保留。

    Clean Session,Will flag,Will Qos, Will Retain都是相对于CONNECT消息来说的。

    **Clean Session:**0表示如果订阅的客户机断线了,那么要保存其要推送的消息,如果其重新连接时,则将这些消息推送。

    ​ 1表示消除,表示客户机是第一次连接,消息所以以前的连接信息。

    Will Flag,表示如果客户机在不是在发送DISCONNECT消息中断,比如IO错误等,将些置为1,要求重传。并且下且的WillQos和WillRetain也要设置,消息体中的Topic和MessageID也要设置,就是表示发生了错误,要重传。

    Will Qos,在CONNECT非正常情况下设置,一般如果标识了WillFlag,那么这个位置也要标识。

    Will RETAIN:同样在CONNECT中,如果标识了WillFlag,那么些位也一定要标识

    usename flag和passwordflag,用来标识是否在消息体中传递用户和密码,只有标识了,消息体中的用户名和密码才用效,只标记密码而不标记用户名是不合法的。

    4、Keep Alive,表示响应时间,如果这个时间内,连接或发送操作未完成,则断开tcp连接,表示离线。

    5、Connect Return Code即通常于CONNACK消息中,表示返回的连接情况,我可以通过此检验连接情况。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d2HeALdv-1602128712023)(C:\Users\23990\AppData\Roaming\Typora\typora-user-images\1601997990746.png)]

    **6、Topic Name,**订阅消息标识,MQTT是基于订阅/发布的消息,那么这个就是消息订阅的标识,像新闻客户端里的订阅不同的栏目一样。用于区别消息的推送类别。

    主要用于PUBLISH和SUBSCRIBE中。最大可支持32767个字符,即4个字节。

    消息体(PayLoad)

    只有3种消息有消息体CONNECT,SUBSCRIBE,SUBACK

    CONNECT主要是客户机的ClientID,订阅的Topic和Message以及用户名和密码,其于变长头部中的will是对应的。

    SUBSCRIBE是包含了一系列的要订阅的主题以及QOS。

    SUBACK是用服务器对于SUBSCRIBE所申请的主题及QOS进行确认和回复。

    而PUBLISH是消息体中则保存推送的消息,以二进制形式,当然这里的编辑可自定义。

    7、Message Identifier

    包含于PUBLISH, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK.

    负载

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MaWRFVVc-1602128712025)(C:\Users\23990\AppData\Roaming\Typora\typora-user-images\1601998064647.png)]

    Payload直译为负荷,可能让人摸不着头脑,实际上可以理解为消息主体(body)。

    Payload消息体位MQTT数据包的第三部分,包含CONNECT、SUBSCRIBE、SUBACK、UNSUBSCRIBE四种类型的消息:

    (1)CONNECT,消息体内容主要是:客户端的ClientID、订阅的Topic、Message以及用户名和密码。

    (2)SUBSCRIBE,消息体内容是一系列的要订阅的主题以及QoS。

    (3)SUBACK,消息体内容是服务器对于SUBSCRIBE所申请的主题及QoS进行确认和回复。

    (4)UNSUBSCRIBE,消息体内容是要订阅的主题。

    MQTT和TCP的区别

    协议位置

    TCP是OSI第四层的传输层协议

    MQTT是基于TCP的七层应用层协议

    协议定位

    TCP设计考虑的是面向连接的、可靠的、基于字节流的传输层通讯协议。

    MQTT则是在低带宽高延迟不可靠的网络下进行数据相对可靠传输的应用层协议。

    设计思想

    TCP的核心思想是分组交换。

    MQTT的核心思想是简单并适应物联网环境。

    传输单位

    TCP的传输单位是packet,当应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,TCP则把数据分割成适当长度的报文段,最大传输段大小(MSS)通常受该计算机连接的网络的数据链路层的最大传送单元(MTU)限制。

    MQTT的传输单位是消息,每条消息字节上限在MQTT Broker代理服务器上进行设置,可以设置操作1M大小的消息上限。

    技术挑战

    TCP需要解决的问题是在IP包传输过程中,处理异构网络环境下的网络堵塞、丢包、乱序、重复包等多种问题。

    MQTT解决的问题是,在低带宽高延迟不可靠的网络下和资源有限的硬件环境内,进行相对可靠的数据传输。

    服务质量

    TCP是一个可靠的流传输服务,通过ACK确认和重传机制,能够保证发送的所有字节在接收时是完全一样的,并且字节顺序也是正确的。

    MQTT提供三种可选的消息发布的QoS服务等级。MQTT客户端和MQTT代理服务器通过session机制保证消息的传输可靠性。

    应用案例

    TCP用户互联网应用程序,如www,email,FTP,SSH,P2P,流媒体

    MQTT用于物联网数据传输,IM聊天软件等。

    Processed: 0.010, SQL: 8