You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32-CAM使用WiFiClientSecure连接Azure服务器失败求助

ESP32-CAM 无法连接 Azure 认知服务 443 端口的排查与解决

核心问题分析

你的代码使用WiFiClientSecure发起TLS连接,但ESP32-CAM默认没有预装Azure认知服务域名对应的根证书,同时TLS连接依赖正确的系统时间,这两个因素是导致连接失败的最常见原因。

具体排查步骤与修复方案

1. 处理TLS证书验证

WiFiClientSecure默认会验证服务器证书,ESP32如果没有对应根证书,会直接拒绝连接。有两种处理方式:

  • 方式一:添加正确的根证书(生产环境推荐)
    访问Azure认知服务域名myproject.cognitiveservices.azure.com,获取其SSL证书链中的根证书(如DigiCert Global Root CA),将证书内容以字符串形式添加到代码中,通过client.setCACert()设置:
    const char* azure_root_ca = R"EOF(
    -----BEGIN CERTIFICATE-----
    // 粘贴实际获取的根证书内容
    -----END CERTIFICATE-----
    )EOF";
    
    void setup() {
      // ... WiFi连接代码 ...
      client.setCACert(azure_root_ca); // 添加证书配置
      Serial.printf("Connecting to %s:%d... ", host, Port);
      if (!client.connect(host, Port)) {
        Serial.println("Failure in connection with the server");
        Serial.print("Error code: ");
        Serial.println(client.lastError()); // 打印错误码辅助排查
      } else {
        Serial.println("Connected successfully!");
      }
    }
    
  • 方式二:临时跳过证书验证(仅测试用)
    如果只是测试连接,可以关闭证书验证,快速确认是否是证书问题:
    void setup() {
      // ... WiFi连接代码 ...
      client.setInsecure(); // 关闭证书验证
      // ... 连接代码 ...
    }
    

2. 同步系统时间

TLS连接需要ESP32有正确的当前时间,否则证书有效期验证会失败。添加NTP时间同步代码:

#include <NTPClient.h>
#include <WiFiUdp.h>

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 8*3600, 60000); // 东八区时间配置

void setup() {
  // ... WiFi连接代码 ...
  timeClient.begin();
  while(!timeClient.update()) {
    timeClient.forceUpdate();
    delay(1000);
    Serial.println("Syncing time...");
  }
  Serial.print("Current time: ");
  Serial.println(timeClient.getFormattedTime());
  // ... 后续连接代码 ...
}

3. 排查网络环境问题

  • 确认ESP32-CAM连接的WiFi与笔记本处于同一网络,且网络没有限制出站443端口的防火墙规则
  • 手动测试ESP32的DNS解析是否正常,添加代码打印解析后的IP:
    IPAddress ip;
    if(WiFi.hostByName(host, ip)){
      Serial.print("Resolved IP: ");
      Serial.println(ip.toString());
    } else {
      Serial.println("DNS resolution failed");
    }
    

4. 打印详细错误信息

在连接失败时,打印WiFiClientSecure的错误码和错误信息,帮助定位具体问题:

if (!client.connect(host, Port)) {
  Serial.println("Failure in connection with the server");
  Serial.print("Error code: ");
  Serial.println(client.lastError());
  Serial.print("Error message: ");
  Serial.println(client.lastErrorMsg());
}

修复后的完整示例代码

#include "esp_camera.h"
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <NTPClient.h>
#include <WiFiUdp.h>

// WiFi credentials
const char* ssid = "mywifiId";
const char* password = "MyPass";

WiFiClientSecure client;
const char* host = "myproject.cognitiveservices.azure.com";
const int Port = 443;

// Azure根证书示例(请替换为实际获取的根证书)
const char* azure_root_ca = R"EOF(
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
)EOF";

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 8*3600, 60000);

void setup() {
  Serial.begin(115200);
  
  // Connect to WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("WiFi connected.");

  // Sync time
  timeClient.begin();
  while(!timeClient.update()) {
    timeClient.forceUpdate();
    delay(1000);
    Serial.println("Syncing time...");
  }
  Serial.print("Current time: ");
  Serial.println(timeClient.getFormattedTime());

  // Set root certificate
  client.setCACert(azure_root_ca);

  // DNS resolution test
  IPAddress ip;
  if(WiFi.hostByName(host, ip)){
    Serial.print("Resolved IP for ");
    Serial.print(host);
    Serial.print(": ");
    Serial.println(ip.toString());
  } else {
    Serial.println("DNS resolution failed for " + String(host));
  }

  // Connect to server
  Serial.printf("Connecting to %s:%d... ", host, Port);
  if (!client.connect(host, Port)) {
    Serial.println("Failure in connection with the server");
    Serial.print("Error code: ");
    Serial.println(client.lastError());
    Serial.print("Error message: ");
    Serial.println(client.lastErrorMsg());
  } else {
    Serial.println("Connected successfully!");
  }
}

void loop() {
}

内容的提问来源于stack exchange,提问作者Hassan Ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 12:05:01