MQTT 调试工具使用示例
有关 MQTT 的常见问题请参考 MQTT FAQ。
以下通过具体案例说明 ESP-IDF MQTT 报错的排查方法,并展示调试工具如何帮助快速确认问题原因和最终解决方案。
示例:esp-tls: [sock=54] select() timeout
此问题对应的完整 log 往往为:
E (15220) esp-tls: [sock=54] select() timeout
E (15220) transport_base: Failed to open a new connection: 32774
E (15220) mqtt_client: Error transport connect
I (15220) mqtt_example: MQTT_EVENT_ERROR
E (15220) mqtt_example: Last error reported from esp-tls: 0x8006
报错分析:
TLS 错误码 0x8006 对应
ESP_ERR_ESP_TLS_CONNECTION_TIMEOUT,说明 TCP 连接阶段超时,底层 socket 等待服务器响应时未在设定时间内收到数据,导致传输层连接建立失败。
可能的原因:
在 TCP 连接建立阶段,客户端(ESP 设备)与服务器之间通过三次握手(Three-way Handshake)建立可靠的传输连接。具体流程如下:
当出现 TCP 连接超时问题时,可以从以下三个角度出发进行排查:
设备端是否成功发送/接收数据包
服务器是否成功发送/接收数据包
路由器是否成功转发数据包
情况一:Broker 不可用
开启 lwIP 层 TCP Debug Log 查看设备端是否发送 SYN 数据包:
开启 Debug Log 后观察到如下信息,表明在 TCP 连接阶段,设备端已发送 SYN 数据包,但尚未收到服务器响应,说明超时问题可能是由于服务器未返回 SYN + ACK 或设备端未收到 SYN + ACK 导致。
使用 MQTT 测试工具 验证目标 Broker 及网络情况。
使用 MQTTX 进行测试,输入相关参数:
Name:用户自定义
Host:目标 Broker 地址
Port:按实际情况输入端口,明文 MQTT 默认端口为 1883,TLS MQTT 默认端口为 8883,该示例使用明文 MQTT
按实际情况选择是否启用 SSL/TLS
连接至目标 Broker,根据测试工具日志可以发现,测试工具多次尝试重连,依然无法连接,故可以判断,该问题可能由于 Broker 不可用导致服务器未返回 ACK 数据包,或网络不稳定导致路由器未能成功转发数据包。
更换 Broker 后,设备成功建立连接,从而确认问题是 Broker 不可用导致。
备注
若更换 Broker 后仍无法解决问题,可参考情况二进行进一步排查。
情况二:Wi-Fi 未能成功接收并转发数据包
若更换 Broker 后,设备仍然无法连接,需通过 无线抓包 查看设备和服务器之间的通信情况。
设置 过滤器,显示设备和服务器之间的 TCP 数据流,方便观察 TLS 握手是否成功。
对于 TCP 数据包需要结合设备 IP,服务器 IP,以及 TCP 进行过滤。
tcp && ((ip.src == 设备IP && ip.dst == 服务器IP) || (ip.src == 服务器IP && ip.dst == 设备IP))
观察抓包信息发现:
设备端发送了 SYN 包;
服务器返回了 SYN + ACK 包;
设备端 没有 返回 ACK 包。
结合设备端 Debug Log,没有显示接收到服务器发送的 SYN + ACK 包,说明服务器的数据包被路由器成功转发却没有到达设备端,由此判断可能是 Wi-Fi 链路接收(RX)部分的问题。