网络开发必懂:MQTT协议与TCP/IP模型对比全解析
MQTT 协议
1.MQTT 协议介绍
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议)是一种轻量级的发布/订阅模式的消息协议,设计用于低带宽、高延迟或不稳定的网络环境中(MQ 代表 Message Queue(消息队列),来源于 IBM 的 MQSeries 消息队列产品线,尽管 MQTT 名字中包含 “MQ”,但实际上它并不需要实现队列功能)。不同于 TCP 或 UDP 协议采用传统的客户端 - 服务器架构,客户端能够和服务器进行通信,它基于发布/订阅模型,发布者 publisher 发送消息到中间件 broker ,中间件 broker 根据订阅者的订阅信息,将消息转发给相应的订阅者 subscribers。这种协议特别适合物联网(IoT)应用,因为它能够有效地减少网络流量和通信开销。

MQTT 适用于在不同设备之间或设备与云端之间传输数据,MQTT 采用了发布-订阅的消息传递模式,客户端通过订阅特定的主题(Topic)来接收感兴趣的消息,也可以向特定主题发布消息,MQTT Broker 是整个系统的核心,负责接收来自客户端的消息,并根据主题将消息路由到相应的订阅者,从而实现一对多或多对多通信
在 1999 年,Andy Stanford-Clark 和 Arlen Nipper 面临一个挑战:他们需要为一个通过卫星连接的石油管道监控系统设计一个高效的通讯协议。这个系统需要在极端的环境条件下工作,这些条件包括:
- 带宽受限:卫星通信带宽通常非常有限,而且成本高昂
- 电池消耗:设备通常使用电池供电,因此降低能耗非常重要
- 网络不可靠:卫星连接可能会遭遇高延迟和不稳定性的问题

Andy Stanford-Clark 本人照片
为了应对这些挑战,MQTT 协议的设计目标包括:
- 易于实现:设计一个简单的协议,使其能够在资源有限的设备上实现,减少开发和部署的复杂度。
- 减少数据传输成本:通过最小化消息头部的开销和简化通信流程,降低带宽使用和数据传输的成本
- 服务质量管理:提供不同级别的消息服务质量,以满足不同应用对可靠性和效率的需求。这使得 MQTT 可以在不同的网络条件下保持消息传递的可靠性
- 连续的会话控制:允许客户端保持持久的会话,即使在连接中断的情况下,也能继续接收未收到的消息
- 数据格式的灵活性:不强求数据的具体类型或格式,允许用户根据需要灵活地传输各种类型的数据
MQTT 协议的设计成功应对了这些挑战,使其成为了物联网(IoT)和远程监控应用中的重要协议。它能够在带宽有限、网络不稳定的环境中高效地传输数据,特别适合于嵌入式设备和远程传感器的应用。2013 年,IBM 向 OASIS 提交了 MQTT 3.1 版本的规范,以推动其成为开放标准。随后,MQTT 逐渐成为物联网领域的标准协议之一。MQTT 协议的核心原则是:精简设计,采用发布/订阅模式,注重低带宽、高延迟网络环境下的传输效率和可靠性,支持灵活的主题创建与服务质量管理,适用于计算能力有限的设备。
MQTT 协议的主要特点包括:
-
发布-订阅模式: MQTT 采用发布-订阅的通信模式,发布者将消息发布到主题(topic)上,订阅者订阅感兴趣的主题,从而接收相关的消息,MQTT 协议需要一个 Broker 作为中间件来管理消息的发布和订阅,确保消息能够可靠地分发给订阅者
- 这种模式解耦了发送方和接收方,提高了系统的灵活性和可扩展性:
- 发送方和接收方实现了空间解耦:发布者并不知道有哪些订阅者,也不需要知道。同样,订阅者也不知道有哪些发布者,只需要订阅感兴趣的主题
- 发送方和接收方实现了时间解耦:在发布-订阅模式中,发布者和订阅者不需要同时在线。发布者可以在订阅者未启动时就发布消息,消息会被 Broker 缓存起来,直到订阅者上线后再进行推送。同样,订阅者也可以在发布者下线的情况下进行订阅,并在发布者上线后立即收到消息。
- 同时发布者和订阅者可以异步地发送和接收消息,不需要等待对方响应,从而实现了异步通信
- 这种模式解耦了发送方和接收方,提高了系统的灵活性和可扩展性:
-
三层质量服务(QoS): MQTT 提供三种不同的消息传递质量服务级别

QoS 0、QoS 1 与 QoS 2 的消息传递机制对比
- QoS 0 (最多一次): 消息可能会丢失,但传输开销最小,适用于对数据丢失不敏感的应用场景,例如环境传感器数据采集,丢失一次记录不影响整体效果或普通 APP 的推送通知,如果智能设备在消息推送时未联网,则不会收到推送
- QoS 1 (至少一次): 消息会被传递至少一次,但可能会重复,适用于需要保证消息到达的应用场景,但消息重复不会产生严重后果
- QoS 2 (只有一次): 消息会被精确地传递一次,适用于对消息传递要求非常严格的场景,不能有丢失或重复的消息,例如计费系统、即时通讯类 APP 的推送,需要确保消息准确无误地传递
通过使用 QoS(服务质量)级别,MQTT 可以控制消息的传输优先级和冗余度,从而节省带宽 - 轻量级和高效: MQTT 协议头部较小,仅包含必要的信息,减少了通信开销。同时它支持二进制编码,进一步提高了传输效率,这些特点使其非常适合于受限设备和低带宽网络环境
- 连接保活和遗愿消息: MQTT 客户端可以配置保活时间(Keepalive),定期向服务器发送连接保活消息,以确保连接的存活,同时,客户端还可以设置遗愿消息,当客户端意外断开连接时,服务器会发布这个消息,通知其他订阅者
- 基于主题的寻址: MQTT 使用基于层次结构的主题(topic)来标识消息,订阅者可以订阅通配符主题来接收多个相关的消息,这种主题订阅方式提供了灵活的消息路由和过滤机制
- 安全机制:MQTT 支持 SSL/TLS 加密来保护消息传输的安全性,并且有专门的认证机制,如用户名/密码或 OAuth
- 基于 TCP/IP:MQTT 工作在 TCP/IP 协议栈之上,确保可靠的数据传输,另有基于 UDP 的 MQTT-SN 版本
2.MQTT 报文结构
MQTT 基本数据单元为报文(Messsage),报文格式由固定报头(Fixed Header)、可变报头(Variable Header)和消息体(Payload)组成:
+----------+-------------------+-------------------+
| Fixed | Variable Header | Payload |
| Header | | |
+----------+-------------------+-------------------+
MQTT 报文格式如下:
- 固定头(Fixed Header):
- 包类型(Packet Type):标识 MQTT 消息的类型,如连接请求(CONNECT)、发布消息(PUBLISH)、订阅消息(SUBSCRIBE)等
- 保留位(Reserved Bit):未来扩展使用
- 包质量标志(QoS Level):指定消息的传输质量级别,取值范围为 0(最高质量)、1(至少一次传输保证)或 2(仅一次传输)
- 重复检测位(Duplication Flag):指示此消息是否为重复消息
- 保持活动(Keep Alive):指示客户端应多久发送一次保持活动消息,以维持连接
- 可变头(Variable Header):
- 协议名称(Protocol Name):始终为"MQTT"
- 协议级别(Protocol Level):表示客户端和服务器支持的 MQTT 版本
- 连接标识(Connection ID):唯一标识客户端连接的 ID
- 用户名(Username):可选字段,用于身份验证
- 密码(Password):可选字段,用于身份验证
- 心跳(Heartbeat):可选字段,用于检测连接是否活跃
- 消息体(Payload):消息体包含实际要传输的数据,其长度取决于消息类型和 QoS 级别
- 对于 PUBLISH 消息,消息体包含主题(Topic)和消息内容(Message Content)
- 对于 SUBSCRIBE 消息,消息体包含订阅的主题列表(Topic List)
MQTT 报文格式的设计旨在确保消息的紧凑性和最小化传输开销,这对于资源受限的设备尤其重要。
以下是常见的 MQTT 报文格式:
- CONNECT 报文:用于客户端请求连接到服务器

- CONNACK 报文:用于确认连接请求

- PUBLISH 报文:用于发布消息

- PUBACK 报文:用于确认已收到 PUBLISH 报文

- SUBSCRIBE 报文:用于订阅主题

- SUBACK 报文:用于确认 SUBSCRIBE 报文

- DISCONNECT 报文:用于断开连接

3.MQTT 协议工作流程
MQTT 协议工作流程包括以下四个步骤:

MQTT 协议工作流程示意图:由于所有的消息传递都通过中介进行,客户端(发布者和订阅者)只需知道中介的地址,而无需知道其他客户端的网络地址。中介负责将消息路由到相应的订阅者,确保消息传递的透明性;这种方式使得系统的扩展更加灵活和简便:发布者和订阅者之间的耦合度低,使得系统能够更加灵活地适应变化,例如添加新订阅者或发布者,不会对现有的系统造成影响
需要重新作图 + 补充中文
- 客户端连接到 MQTT 服务器:客户端通过 TCP/IP 协议与 MQTT 服务器建立连接
- 客户端连接到 MQTT 代理(Broker)服务器,在连接过程中,需要向服务器提供客户端标识(ClientId),以及用户名和密码等信息
- 客户端发送 CONNECT 报文,代理返回 CONNACK 报文确认连接
- 如果连接成功,客户端与服务器将建立会话(Session),并开始进行数据传输
- 订阅主题:在建立连接后,客户端可以订阅感兴趣的主题,以便接收发布到这些主题上的消息
- 客户端发送 SUBSCRIBE 报文订阅一个或多个主题,报文中需要指定要订阅的主题和 QoS 等级
- 服务器返回 SUBACK 报文确认订阅,表示主题订阅成功或失败
- 发布消息:在建立连接后,客户端可以向指定的主题发布消息
- 客户端发送 PUBLISH 报文将消息发布到指定主题,报文中需要指定要发布的主题和消息内容
- 服务器将返回 PUBACK 报文,表示消息发布成功或失败
- 断开连接:客户端可以主动断开与 MQTT 服务器的连接
- 客户端发送 DISCONNECT 报文断开连接
- 服务器将返回 DISCONNECT 报文,表示连接断开成功
其中发布和订阅的步骤不只能设置一次,可以设置多次。
可以看到,MQTT 协议中通信角色如下:
- 服务器/Broker:
- 负责管理和转发消息
- 维护客户端的连接状态
- 接收发布者发布的消息并将其分发到订阅了相关主题的订阅者
- 客户端/Client:客户端既可以发布也可以订阅,这里按照通信的数据方向分为以下两种
- 订阅者(Subscriber):通常需要与中介保持持续的连接。这是因为订阅者希望持续接收它感兴趣的主题的消息,如果中介断开连接,订阅者可能会错过发布到其订阅主题的消息。
- 连接到中介,订阅自己感兴趣的主题
- 只在主题有新消息时才接收消息
- 可以订阅多个主题,且对不同主题的消息进行处理
- 发布者(Publisher):通常在需要发布消息时才建立连接。一旦消息发布完成,发布者可以断开连接。这样做可以节省资源,特别是在发布频率不高的场景中;如果发布者需要频繁发布消息,它可能会选择保持连接状态,以避免每次发布时都需要重新连接中介。
- 连接到中介,发布消息到特定的主题
- 不需要保持长期连接,只在需要发布消息时建立连接
- 多个发布者可以发布到相同的主题
- 订阅者(Subscriber):通常需要与中介保持持续的连接。这是因为订阅者希望持续接收它感兴趣的主题的消息,如果中介断开连接,订阅者可能会错过发布到其订阅主题的消息。
4.MQTT 心跳机制
MQTT 心跳机制是通过定期发送 PINGREQ 报文来维持客户端与服务器之间的连接。服务器在收到 PINGREQ 报文后,会立即响应一个 PINGRESP 报文。这个过程确保了客户端与服务器之间的连接是活跃的,并防止连接因闲置时间过长而被断开。
在 MQTT 中,心跳机制是由 keepalive 参数控制的。这个参数表示客户端和服务器之间的最大允许空闲时间(单位:秒)。如果在 keepalive 时间内客户端没有发送任何消息,客户端会自动发送一个 PINGREQ 报文。如果服务器在一段时间内没有收到客户端的消息(包括 PINGREQ 报文),它可能会断开连接。
5.MQTT 版本
MQTT 协议已经经历了几个版本的演进。以下是主要版本的简要介绍:

MQTT 协议版本演进史:从 3.1 到 5.0 的技术发展历程
- MQTT 3.1 (2010):由 IBM 公司发布,这是第一个公开的 MQTT 版本,设计目标是支持低带宽、高延迟、不可靠网络环境下的设备通信。引入了基本的服务质量(QoS)级别,主题发布和订阅机制,以及连接保持(Keep Alive)机制。
- MQTT 3.1.1 (2014):由 OASIS(Organization for the Advancement of Structured Information Standards)发布,作为 MQTT 协议的标准。在 MQTT 3.1 的基础上进行了一些改进和修正,包括对协议的一些详细要求进行了明确。改进了连接、消息格式和错误处理等方面。
- MQTT 5.0 (2019):由 OASIS 发布,引入了许多新功能和改进,包括增强的错误报告、消息属性、用户属性、请求/响应模式、主题别名等。支持更复杂的消息传递模式和扩展了 QoS(服务质量)管理功能。

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议)是一种轻量级的发布/订阅模式的消息协议,设计用于低带宽、高延迟或不稳定的网络环境中(MQ 代表 Message Queue(消息队列),来源于 IBM 的 MQSeries 消息队列产品线,**尽管 MQTT 名字中包含 “MQ”,但实际上它并不需要实现队列功能**)。不同于 TCP 或 UDP 协议采用传统的客户端 - 服务器架构,客户端能够和服务器进行通信,它基于发布/订阅模型,发布者 publisher 发送消息到中间件 broker ,中间件 broker 根据订阅者的订阅信息,将消息转发给相应的订阅者 subscribers。这种协议特别适合物联网(IoT)应用,因为它能够有效地减少网络流量和通信开销。
浙公网安备 33010602011771号