内容简介:MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(Publish/Subscribe)模式的轻量级通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布,目前最新版本为v3.1.1。MQTT最大的优点在于可以以极少的代码和有限的带宽,为远程设备提供实时可靠的消息服务。做为一种低开销、低带宽占用的即时通讯协议,MQTT在物联网、小型设备、移动应用等方面有广泛的应用。众所周知,TCP/IP参考模型可以分为四层:应用层、传输
1. 概述
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(Publish/Subscribe)模式的轻量级通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布,目前最新版本为v3.1.1。MQTT最大的优点在于可以以极少的代码和有限的带宽,为远程设备提供实时可靠的消息服务。做为一种低开销、低带宽占用的即时通讯协议,MQTT在物联网、小型设备、移动应用等方面有广泛的应用。众所周知,TCP/IP参考模型可以分为四层:应用层、传输层、网络层、链路层。TCP和UDP位于传输层,应用层常见的协议有HTTP、FTP、SSH等。MQTT协议运行于TCP之上,属于应用层协议,因此只要是支持TCP/IP协议栈的地方,都可以使用MQTT。
2. MQTT客户端
一个使用MQTT协议的应用程序或者设备,它总是建立到服务器的网络连接。客户端可以:
(1)发布其他客户端可能会订阅的信息; //发布消息
(2)订阅其它客户端发布的消息; //订阅消息
(3)退订或删除应用程序的消息;//退订消息
(4)断开与服务器连接。//断开,连接服务器
3. MQTT服务器
MQTT服务器以称为“消息代理”(Broker),可以是一个应用程序或一台设备。它是位于消息发布者和订阅者之间,它可以:
(1)接受来自客户的网络连接; //接受客户端连接
(2)接受客户发布的应用信息;//接收客户端发布的消息
(3)处理来自客户端的订阅和退订请求;//处理消息的订阅及退订
(4)向订阅的客户转发应用程序消息。//推送消息
4. MQTT消息格式
每条MQTT命令消息的消息头都包含一个固定的报头,有些消息会携带一个可变报文头和一个负荷。消息格式如下:
固定报文头 | 可变报文头 | 负荷
4.1 固定报文头(Fixed Header)
剩余长度字段单个字节最大值为二进制0b0111 1111,16进制0x7F。也就是说,单个字节可以描述的最大长度是127字节。为什么不是256字节呢?因为MQTT协议规定,单个字节第八位(最高位)若为1,则表示后续还有字节存在,第八位起“延续位”的作用。
例如,数字64,编码为一个字节,十进制表示为64,十六进制表示为0×40。数字321(65+2*128)编码为两个字节,重要性最低的放在前面,第一个字节为65+128=193(0xC1),第二个字节是2(0x02),表示2×128。
4.2 可变报文头(Variable Header)
4.2.1 消息质量(QoS)
MQTT消息质量有三个等级,QoS 0,QoS 1和 QoS 2。
QoS 0:最多分发一次。消息的传递完全依赖底层的TCP/IP网络,协议里没有定义应答和重试,消息要么只会到达服务端一次,要么根本没有到达。
QoS 1:至少分发一次。服务器的消息接收由PUBACK消息进行确认,如果通信链路或发送设备异常,或者指定时间内没有收到确认消息,发送端会重发这条在消息头中设置了DUP位的消息。
QoS 2:只分发一次。这是最高级别的消息传递,消息丢失和重复都是不可接受的,使用这个服务质量等级会有额外的开销。
4.2.2 遗愿标志(Will Flag)
在可变报文头的连接标志位字段(Connect Flags)里有三个Will标志位:Will Flag、Will QoS和Will Retain Flag,这些Will字段用于监控客户端与服务器之间的连接状况。如果设置了Will Flag,就必须设置Will QoS和Will Retain标志位,消息主体中也必须有Will Topic和Will Message字段。
那遗愿消息是怎么回事呢?服务器与客户端通信时,当遇到异常或客户端心跳超时的情况,MQTT服务器会替客户端发布一个Will消息。当然如果服务器收到来自客户端的DISCONNECT消息,则不会触发Will消息的发送。
因此,Will字段可以应用于设备掉线后需要通知用户的场景。
4.2.3 连接保活心跳机制(Keep Alive Timer)
MQTT客户端可以设置一个心跳间隔时间(Keep Alive Timer),表示在每个心跳间隔时间内发送一条消息。如果在这个时间周期内,没有业务数据相关的消息,客户端会发一个PINGREQ消息,相应的,服务器会返回一个PINGRESP消息进行确认。如果服务器在一个半(1.5)心跳间隔时间周期内没有收到来自客户端的消息,就会断开与客户端的连接。心跳间隔时间最大值大约可以设置为18个小时,0值意味着客户端不断开
4.3 有效负荷(Payload)
当MQTT发送的消息类型是CONNECT(连接)、PUBLISH(发布)、SUBSCRIBE(订阅)、SUBACK(订阅确认)、UNSUBSCRIBE(取消订阅)时,则会带有负荷。
(1)CONNECT,消息体内容主要是:客户端的ClientID、订阅的Topic、Message以及用户名和密码。
(2)SUBSCRIBE,消息体内容是一系列的要订阅的主题以及QoS。
(3)SUBACK,消息体内容是服务器对于SUBSCRIBE所申请的主题及QoS进行确认和回复。
(4)UNSUBSCRIBE,消息体内容是要订阅的主题。
(5)PUBLISH,消息体内容是相关主题的数据。
5. MQTT控制报文
介绍MQTT协议的报文组成并通过wireshark抓取报文包分析报文内容
5.1 连接服务端(CONNECT)
Connect报文在MQTT客户端连接服务器时发出,报文由三部分组成,下面将分别介绍
5.1.1 固定报头(fixed header)
5.1.2 可变报头(variable header)
用户名标志(username flag): 若用户名标志被置为1,有效载荷中必须包含用户名字段。
密码标志(password flag): 若密码标志被置为1,有效载荷中必须包含密码字段,当用户标志被置为0时,密码标志必须被置0.。
遗嘱标志(will flag): 若遗嘱标志被置1,遗嘱服务指令(will Qos)与遗嘱保留标志(will retain)会被服务器用到,遗嘱消息中必须包含will topic和will message。
遗嘱服务指令(will Qos): 如果遗嘱标志被设置为0,遗嘱QoS也必须设置为0(0x00),如果遗嘱标志被设置为1,遗嘱QoS的值可以等于0(0x00),1(0x01),2(0x02)。它的值不能等 于3。
遗嘱保留标志(will retain): 若遗嘱保留标志位被置位,服务器将保留遗嘱消息(保留发布),当客户端异常断开连接时将遗嘱发给订阅遗嘱主题的客户。
清除会话标志(clean session): 标志被设置为1,客户端和服务端必须丢弃之前的任何会话并开始一个新的会话(之前的订阅与发布消息被删除),若标志为0,恢复与服务器会话连接,若没有连接 新建一个会话连接(不删除之前与客户端的会话信息并保存断开本次会话之后的Qos1与Qos2消息)。
保留位(reserved): 如果不为0必须断开客 户端连接。
报文最后两字节为发送心跳包的间隔时间,当客户端没有数据发给服务器时,须发送心跳包(pingreq)到服务器,保证连接不断开。
5.1.3 有效载荷(Payload)
5.2连接请求确认(CONNACK)
Connack为服务器确认客户端连上服务给出的回应。
5.2.1 固定报头(fixed header)
5.2.2 可变报头(variable header)
第一字节1~7位保留,第0位是当前会话标志(session present),若清除会话标志被置1,该位为0,若清除会话标志为0且服务器没有与客户端会话保存,该位置0,有保存置1
第二字节保存连接返回码,若连接成功返回0。
5.3发布消息(PUBLISH)
发布消息可由客户端或服务器发出,被消息订阅者接收。
5.3.1 固定报头(fixed header)
固定报头第一字节的低四位分别保存重发标志(DUP),服务质量(Qos),保留标志(RETAIN)。
重发标志(DUP):当该位被置1,表示该条报文为重发报文,客户端或服务端请求重发一个PUBLISH报文时,必须将DUP标志设置为1。对于QoS 0的消息,DUP标志必须设置为0。
服务质量(Qos):表示发送质量,取值有00 01 10。
保留标志(RETAIN):若该位被置1,表示服务器必须保存其应用消息和质量等级,若为0,表示该消息不须保存,如果服务端收到一条保留(RETAIN)标志为1的QoS 0消息,它必须丢弃之前为那个主题保留的任何消息。它应该将这个新的QoS0消息当作那个主题的新保留消息,但是任何时候都可以选择丢弃它,保留标志为1且有效载荷为零字节的PUBLISH报文会被服务端当作正常消息处理,它会被发送给订阅主题匹配的客户端。此外,同一个主题下任何现存的保留消息必须被移除,因此这个主题之后的任何订阅者都不会收到一个保留消息。
5.3.2 可变报头(variable header)
可变报头按顺序包含主题名和报文标识符。
5.3.3 有效载荷(Payload)
5.4发布确认(PUBACK)
由服务器或客户端确认已接收到pub消息
5.4.1 固定报头(fixed header)
5.4.2 可变报头(variable header)
5.5发布收到 PUBREC(QoS 2,第一步)
5.5.1 固定报头(fixed header)
5.5.2 可变报头(variable header)
5.6发布释放 PUBREL(QoS 2,第二步)
5.6.1 固定报头(fixed header)
5.6.2 可变报头(variable header)
5.7发布完成 PUBCOMP(QoS 2,第三步)
5.7.1 固定报头(fixed header)
5.7.2 可变报头(variable header)
5.8订阅主题(SUBSCRIBE)
客户端通过订阅消息的方式来接收服务端下发的消息
5.8.1 固定报头(fixed header)
5.8.2 可变报头(variable header)
只有两字节的报文标识
5.8.3 有效载荷(Payload)
消息载体包含若干主题过滤器和服务质量等级
PUB时指定的qos是服务器肯定按此规则接收,但是最终订阅者不一定。
5.9订阅确认(SUBACK)
SUBACK报文包含一个返回码清单,它们指定了SUBSCRIBE请求的每个订阅被授予的最大QoS等级。
5.9.1 固定报头(fixed header)
5.9.2 可变报头(variable header)
只有两字节的报文标识
5.9.3 有效载荷(Payload)
5.10取消订阅 (UNSUBSCRIBE)
5.10.1 固定报头(fixed header)
5.10.2 可变报头(variable header)
只有两字节的报文标识
5.10.3 有效载荷(Payload)
5.11取消订阅确认 (UNSUBACK)
5.11.1 固定报头(fixed header)
5.11.2 可变报头(variable header)
5.12心跳请求 (PINGREQ)
客户端发送PINGREQ报文给服务端的。用于:
1.在没有任何其它控制报文从客户端发给服务的时,告知服务端客户端还活着。
2.请求服务端发送 响应确认它还活着。
3.使用网络以确认网络连接没有断开
5.12.1 固定报头(fixed header)
5.13心跳响应 (PINGRESP)
5.13.1 固定报头(fixed header)
5.14断开连接 (DISCONNECT)
5.14.1 固定报头(fixed header)
抓包注意:用标准不加密MQTT能抓到便于查看的报文,加密报文解析时不便于理解
创作不易,白嫖不好,各位的支持和认可,就是我创作的最大动力,我们下篇文章见!
清风 | 文 【原创】
如果本篇博客有任何错误,请批评指教,不胜感激 !
以上所述就是小编给大家介绍的《MQTT抓包分析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 使用动态分析技术分析 Java
- 使用动态分析技术分析 Java
- 案例分析:如何进行需求分析?
- 深度分析ConcurrentHashMap原理分析
- 如何分析“数据分析师”的岗位?
- EOS源码分析(3)案例分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。