前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MQTT Packet详解【01】:CONNECT & CONNACK

MQTT Packet详解【01】:CONNECT & CONNACK

作者头像
Hello工控
发布于 2025-05-08 08:31:04
发布于 2025-05-08 08:31:04
19500
代码可运行
举报
文章被收录于专栏:Hello工控Hello工控
运行总次数:0
代码可运行

在上期中,我们介绍了 MQTT 包由固定头、可变头和负载三部分组成,以及 MQTT 包中的一些常见概念,如可变字节整数和属性。

MQTT Control Packets(MQTT控制包)了解吗?

现在,我们将根据实际用途进一步介绍每种包的组成。首先,我们将重点介绍用于建立 MQTT 连接的包。

如果我们要使用 MQTT 进行通信,第一步必须是建立 MQTT 连接。建立 MQTT 连接需要使用两个控制包,即 CONNECT 包和 CONNACK 包。CONNECT 包是客户端在建立网络连接后发送给服务器的第一个控制包,用于发起连接请求。服务器会返回一个 CONNACK 包来告知客户端连接结果。

Sample样例

我们使用 MQTTX客户端与公共 MQTT 服务器建立连接。

在上图这个连接中,我们将协议版本设置为 MQTT 5.0,Clean Start 设置为 1,会话过期间隔设置为 300 秒,心跳间隔设置为 60,用户名和密码分别设置为 admin 和 public。当然也可以用 MQTTX CLI 命令行工具与公共 MQTT 服务器建立连接。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mqttx conn --hostname broker.emqx.io--mqtt-version5 \
--session-expiry-interval300--keepalive60--username admin --password public

以下是由 MQTTX CLI 发送的 CONNECT 数据包,使用 Wireshark 捕获。

但这是一串十六进制字节,除非将其转换为以下格式才容易理解:

例如上述Variable Header里面的Protocol Name:00 04 4d 51 54 54

具体的协议编码及数据格式可以参考MQTT官方的资料:

https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901004

同样,我们还捕获了公共 MQTT 服务器返回的 CONNACK 包:

解析了这个数据包字符串后,我们可以看到,CONNACK 数据包的 Reason Code 为 0,这意味着连接成功。随后的多个属性提供了一组服务器支持的功能列表,例如支持的最大数据包大小、是否支持保留消息等:

上述示例有助于大家更好地理解 MQTT 包的结构。在实际应用中,您可以直接在 Wireshark 中查看包详情。Wireshark 对 MQTT 提供了很好的支持,它会直接列出每个字段的值,无需我们自行分析。

当然,Wireshark 确实为我们列出了每个字段的值。通过接下来对 CONNECT 和 CONNACK 包的结构介绍,结合 Wireshark 的包捕获结果,你将迅速掌握这两种包:

关于Wireshark的官方免费下载地址:

https://www.wireshark.org/#downloadLink

CONNECT Packet Structure

CONNECT包结构

Fixed Header固定头

在 CONNECT 报文的固定头部中,位于第一个字节高位的包类型字段必须是 1(0b0001),而第一个字节的低位必须全部为 0。

因此,CONNECT 报文的第一个字节的值必须是 0x10 。我们可以使用这一点来确定一个报文是否是 CONNECT 报文。

Variable Header 变量头

CONNECT 包的可变头部按顺序包含以下字段:

  • Protocol Name协议名称: 这是一个 UTF-8 编码的字符串,用于指示协议名称。在 MQTT 中,UTF-8 编码字符串的前两个字节用于表示后续实际字符数据的长度。在 MQTT 3.1.1 和 MQTT 5.0 中,协议名称固定为 MQTT ,因此相应的完整内容在十六进制字节中为 00 04 4d 51 54 54 ,其中 4d 51 54 54 是字符串 MQTT 的 ASCII 值。最早的 MQTT 3.1 中的协议名称为 MQIsdp ,因此对应于 00 06 4d 51 49 73 64 70
  • Protocol Version协议版本: 这是一个无符号整数,用于表示协议版本。目前只有三种可能的值,3 表示 MQTT 3.1,4 表示 MQTT 3.1.1,5 表示 MQTT 5.0。
  • Connect Flags连接标志:连接标志只有 1 个字节长,但包含用于表示连接行为或指示 Payload 中是否存在某些字段的多个标志。
  • User Name Flag用户名标志: 用于指示 Payload 是否包含用户名。
  • Password Flag密码标志:用于指示 Payload 是否包含密码。
  • Will Retain遗留消息: 用于指示遗留消息是否为遗留消息。
  • Will QoS遗留消息 QoS: 用于指示遗留消息的 QoS。
  • Will Flag遗留消息标志: 用于指示 Payload 是否包含遗留消息的相关字段。
  • Clean Start清洁会话:用于指示当前连接是新会话还是现有会话的延续,这决定了服务器是直接创建新会话还是尝试重用现有会话。
  • Reserved保留:这是一个保留位,其值必须为 0。
  • Keep Alive保持活动:这是一个双字节长度无符号整数,用于指示客户端发送的两个相邻控制包之间的最大时间间隔。
  • Properties属性:以下表格列出了 CONNECT 包的所有可用属性:

Payload 载荷

在 CONNECT 包的 Payload 中,除了 Client ID 之外,其他所有字段都是可选的。它们的存在取决于可变头中的 Connect Flags 对应标志的值。然而,如果这些字段存在,它们必须按照 Client ID、Last Will Properties、Last Will Topic、Last Will Payload、User Name 和 Password 的顺序出现。

图片
图片

CONNACK Packet Structure CONNACK 数据包结构

Fixed Header固定头

第一个固定头字节的高 4 位的值为 2(0b0010),表示这是一个 CONNACK 包。

Variable Header 变量头

CONNACK 包的可变头部按顺序包含以下字段:

  • Connect Acknowledge Flags连接确认标志:连接确认标志。
    • Reserved保留(位 7-1):保留位,必须设置为 0。
    • Session Present (Bit 0):用于指示服务器是否使用现有的会话来与客户端通信只只有当客户端在 CONNECT 连接中将 Clean Start 设置为 0 时,
    • Session Present 才可以为 1。
  • Reason Code结果代码:于表示连接的结果。以下是在 CONNACK 包中的一些常见 Reason Code,如需完整列表,请参阅MQTT 5.0 Reason Code快快速参考指南或者后期推文。
  • 属性:以下表格列出了 CONNACK 包的所有可用属性。

Payload 载荷 CONNACK 包没有负载。

结论

CONNECT 是客户端在网络连接与服务器建立之后发送的第一个 MQTT 包。CONNACK,作为 CONNECT 的响应包,通过原因码表示连接结果。

客户端和服务器需要使用 CONNECT 和 CONNACK 报文来完成必要的信息交换,例如协议版本、Client ID、客户端使用的用户名和密码、服务器支持的最大报文大小和 QoS,以及是否存在相应的会话。

以上是对 MQTT CONNECT 和 CONNACK 包的介绍。在后续的文章中,我们将继续研究像 PUBLISH 和 DISCONNECT 这样的包的结构和组成。

参考链接:

  1. https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901004
  2. https://www.emqx.com/en/blog/mqtt-5-0-control-packets-01-connect-connack
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-05-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Hello工控 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Sample样例
  • CONNECT Packet Structure
    • Variable Header 变量头
    • Payload 载荷
  • CONNACK Packet Structure CONNACK 数据包结构
    • Payload 载荷 CONNACK 包没有负载。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档