ESP32(NodeMCU)连接树莓派Mosquitto MQTT Broker时出现连接中止错误求助
解决ESP32连接树莓派Mosquitto MQTT Broker时的"Software caused connection abort"错误
我看到你用ESP32(NodeMCU)通过EspMQTTClient库连接树莓派上的Mosquitto Broker时遇到了errno:113的连接失败问题,已经排查了端口和Broker运行状态但没解决。结合你的代码和这类问题的常见诱因,我整理了几个针对性的排查和修复方向:
1. 先确认ESP32与树莓派的基础网络连通性
错误113本质是网络层面的连接中断,先排除最基础的网络问题:
- 在ESP32代码里添加Ping树莓派IP的逻辑,验证跨设备通信是否正常:
#include <ESPping.h> // 在setup()的Serial初始化后添加 void setup() { Serial.begin(9600); // 新增Ping测试 if(ping("你的树莓派局域网IP", 3)){ Serial.println("✅ 能正常ping通树莓派"); } else { Serial.println("❌ 无法ping通树莓派,请检查:"); Serial.println(" - ESP32和树莓派是否在同一WiFi网段"); Serial.println(" - 树莓派的WiFi/以太网是否正常联网"); } // 原有的client初始化逻辑... } - 务必确保两者在同一局域网,跨网段场景需要额外配置路由器端口转发,优先先在同网段测试。
2. 检查Mosquitto Broker的绑定配置
默认情况下,部分Mosquitto安装会仅绑定本地回环地址(127.0.0.1),导致外部设备无法连接:
- 编辑树莓派上的Mosquitto配置文件(通常路径为
/etc/mosquitto/mosquitto.conf):- 找到
bind_address字段,如果存在,修改为bind_address 0.0.0.0(允许所有IP访问),或者直接注释掉该行(默认允许所有IP连接)。 - 重启Mosquitto服务生效:
sudo systemctl restart mosquitto
- 找到
- 用命令验证监听状态:
netstat -tulpn | grep 1883,确保输出里有0.0.0.0:1883,而不是只有127.0.0.1:1883。
3. 修正EspMQTTClient的初始化参数
你的代码里初始化EspMQTTClient时,第二、第三个参数是MQTT的用户名和密码占位符,如果你的Mosquitto没有开启认证,这两个参数必须传空字符串,不能留占位符:
// 修正后的初始化代码(无认证场景) EspMQTTClient client( "你的树莓派实际IP", // 替换为真实局域网IP "", // 无用户名则传空字符串 "", // 无密码则传空字符串 "TestClient", // 唯一标识设备的客户端名 1883 // MQTT端口 );
如果你的Broker开启了认证,务必确保用户名、密码完全匹配(注意大小写)。
4. 禁用ESP32的WiFi电源管理(隐性坑)
部分ESP32模块的WiFi休眠机制会导致连接意外中断,在setup()里添加禁用代码:
void setup() { Serial.begin(9600); WiFi.setSleep(false); // 关闭WiFi休眠,避免连接中途断开 // 原有的client初始化逻辑... }
5. 用原生PubSubClient库做对比测试
换用更基础的PubSubClient库测试,排除EspMQTTClient库的潜在问题:
#include <WiFi.h> #include <PubSubClient.h> const char* ssid = "你的WiFi名称"; const char* password = "你的WiFi密码"; const char* mqtt_server = "你的树莓派IP"; WiFiClient espClient; PubSubClient client(espClient); void setup() { Serial.begin(9600); // 连接WiFi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nWiFi connected"); client.setServer(mqtt_server, 1883); } void loop() { if (!client.connected()) { Serial.println("Attempting MQTT connection..."); // 无认证的连接方式 if (client.connect("TestClient")) { Serial.println("✅ MQTT连接成功"); client.publish("refrigerator/temp", "Test Data"); } else { Serial.print("❌ 连接失败,状态码:"); Serial.print(client.state()); Serial.println(" 5秒后重试"); delay(5000); } } client.loop(); }
如果这个代码能正常连接,说明问题出在EspMQTTClient的使用逻辑上,可重点排查原库的回调或初始化细节。
6. 检查树莓派的防火墙规则
即使你确认1883端口开放,树莓派的ufw防火墙可能仍在拦截连接:
- 临时关闭ufw测试:
sudo ufw disable,再尝试ESP32连接。 - 如果关闭后能正常连接,添加允许1883端口的规则:
sudo ufw allow 1883/tcp,再重新开启ufw:sudo ufw enable。
内容的提问来源于stack exchange,提问作者Adarsh SR




