首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >MQTT Packet详解【04】:PINGREQ & PINGRESP心跳报文

MQTT Packet详解【04】:PINGREQ & PINGRESP心跳报文

作者头像
Hello工控
发布2025-05-12 12:32:24
发布2025-05-12 12:32:24
6360
举报
文章被收录于专栏:Hello工控Hello工控

现在,我们将介绍用于保持连接的控制报文:PINGREQ 和 PINGRESP

MQTT 5.0 Packet Explained 04: PINGREQ & PINGRESP
MQTT 5.0 Packet Explained 04: PINGREQ & PINGRESP

除了用于连接、发布和订阅的控制报文外,MQTT 还有一种用于模拟客户端和服务器之间的心跳以保持连接的报文类型。它们是 PINGREQ 和 PINGRESP 报文,我们通常称之为心跳报文

客户端会周期性地向服务器发送 PINGREQ 报文,让服务器知道连接是正常的并且客户端仍然处于活动状态。对于每个收到的 PINGREQ 报文,服务器会回复一个 PINGRESP 报文,这样客户端也可以知道连接是正常的并且服务器仍然处于活动状态。

Sample Pacaket样例

我们使用 MQTTX CLI 来建立一个客户端连接到公共 MQTT 服务器。我们没有发布消息或订阅主题,但在 Wireshark 中,我们仍然可以看到客户端和服务器之间定期出现 MQTT 数据包。这些数据包是 PINGREQ 和 PINGRESP。

也可以使用命令将创建一个客户端连接,Keep Alive 为 5 秒,这将使我们能够尽快看到客户端发送 PINGREQ 消息。

我们会发现 PINGREQ 和 PINGRESP 数据包总是只有 2 字节大小,并且它们的内容似乎从不改变:

这两种数据结构报文也特别简单。

PINGREQ & PINGRESP

数据包结构

PINGREQ 和 PINGRESP 包之间的唯一区别在于固定头部中的包类型字段。PINGREQ 的包类型是 12(0x0C),而 PINGRESP 的包类型是 13(0x0D)。

PINGREQ 和 PINGRESP 包之后跟随的保留长度字段的值总是 0,因为 无论 PINGREQ nor PINGRESP 包中都不包含可变头或负载。

这种结构使得 PINGREQ 和 PINGRESP 包的大小最小化,因此发送它们不会占用太多带宽。

图片
图片

常见问题

Q :MQTT Keep Alive 间隔可以多长?

A:keepalive 参数的值是一个表示秒数的整数。例如, keepalive=300 表示客户端应当每 300 秒向 MQTT 代理发送一条消息,例如 PUBLISH。在另外 150 秒后,代理会关闭连接。Keep Alive 间隔的最大值为 65535,即 18 小时 12 分钟 15 秒。

Q : MQTT Keep Alive 间隔是否可以等于零?

A:可以将 MQTT Keep Alive 机制禁用,如果将间隔设为 0: keepalive=0

Q :MQTT Keep Alive 默认周期是什么?

A:默认值因您使用的 MQTT 客户端库而异。例如,Python MQTT 客户端将默认 Keep Alive 间隔设为 60 秒。同样,Eclipse Paho MQTT 浏览器基于的 JavaScript 客户端库也是如此。而 Arduino 的 MQTT PubSubClient keepalive 间隔默认设为 15 秒。

然而,在建立代理和客户端之间的连接时,你可以将任何其他 Keep Alive 间隔设置为 65535 以内。

Q :MQTT Keep Alive 间隔可以不同吗?代理和客户端之间可以不同吗?

A:客户端在建立连接时会在 MQTT 协议中确定 Keep Alive 间隔。

对于 MQTT v.5.0 客户端,还有一种从代理服务器到客户端设置 MQTT Keep Alive 值的反向方式。代理服务器可以告诉客户端它应该使用的 Keep Alive 间隔。 max_keepalive 选项允许客户端使用不大于指定值的 Keep Alive 间隔。但对于 MQTT v.3.1 和 v.3.1.1 客户端,却没有这样的机制来指定使用什么 Keep Alive 间隔。

结论

PINGREQ 和 PINGRESP 是 MQTT 中最简单的包,它们的内容是固定的。我们唯一可以改变的是通过连接时的保持活动选项来影响客户端发送 PINGREQ 包的频率。

下两个图就是使用Wirshark捕获的数据包具体截图:

如果服务器在 1.5 倍的心跳保留时间内没有收到客户端的任何控制包,它将认为客户端是不活跃的或网络异常并断开连接。在本文的包示例中,连接时我们将心跳保留设置为 5 秒,因此服务器的超时时间为 7.5 秒。

对于客户端,如果在发送 PINGREQ 包后的一段时间内没有收到服务器返回的 PINGRESP 包,它应该断开连接。这个时间长度主要取决于客户端对网络延迟的预期以及每个客户端 SDK 的具体实现。

参考链接:

  1. https://cedalo.com/blog/mqtt-keep-alive-explained/
  2. https://www.emqx.com/en/blog/mqtt-5-0-control-packets-04-pingreq-pingresp
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-05-10,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Sample Pacaket样例
  • Q :MQTT Keep Alive 间隔可以多长?
  • Q : MQTT Keep Alive 间隔是否可以等于零?
  • Q :MQTT Keep Alive 默认周期是什么?
  • 然而,在建立代理和客户端之间的连接时,你可以将任何其他 Keep Alive 间隔设置为 65535 以内。
  • Q :MQTT Keep Alive 间隔可以不同吗?代理和客户端之间可以不同吗?
  • 结论
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档