You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动