ESP-IDF环境下Zenoh-Pico无法连接公共服务器问题求助
ESP32-S3 无法连接 Zenoh 公共服务器问题
问题背景
所有CMakeLists.txt配置正常,代码可正常编译,但ESP32-S3始终无法连接Zenoh公共服务器demo.zenoh.io(解析IP:212.71.244.198)。Wi-Fi连接正常且能获取IP,已尝试切换不同移动数据网络,本地测试tcp/212.71.244.198:7447的Pub/Sub功能正常,排除路由器防火墙问题,但仍存在类似防火墙的连接故障。
最小示例代码
#include <stdio.h> #include <string.h> #include "nvs_flash.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "zenoh-pico.h" #include "utils/config.h" #include "utils/secret.h" #include "utils/wifi.h" #define ZENOH_CONNECT_IP "212.71.244.198" void data_handler(z_loaned_sample_t *sample, void *arg) { z_view_string_t keystr; z_keyexpr_as_view_string(z_sample_keyexpr(sample), &keystr); z_owned_string_t value; z_bytes_to_string(z_sample_payload(sample), &value); ESP_LOGI(TAG, "--> [Subscriber] Received ('%.*s': '%.*s')", (int)z_string_len(z_view_string_loan(&keystr)), z_string_data(z_view_string_loan(&keystr)), (int)z_string_len(z_string_loan(&value)), z_string_data(z_string_loan(&value))); z_drop(z_move(value)); } void app_main(void) { configure_system_logging(); ESP_LOGI(TAG, "--- ZENOH - ESP-IDF PUB/SUB ----"); // 初始化NVS Flash esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); ESP_LOGI(TAG, "Wi-Fi init..."); wifi_init_sta(); ESP_LOGI(TAG, "Starting Zenoh app in CLIENT mode..."); z_owned_session_t session; z_owned_config_t config; while(1) { z_config_default(&config); zp_config_insert(z_loan_mut(config), Z_CONFIG_MODE_KEY, "client"); char connect_endpoint[128]; snprintf(connect_endpoint, sizeof(connect_endpoint), "tcp/%s:7447", ZENOH_CONNECT_IP); zp_config_insert(z_loan_mut(config), Z_CONFIG_CONNECT_KEY, connect_endpoint); ESP_LOGI(TAG, "Opening Zenoh session: %s", connect_endpoint); if (z_open(&session, z_move(config), NULL) == Z_OK) { ESP_LOGI(TAG, "Zenoh session opened successfully!"); break; } else { ESP_LOGE(TAG, "Zenoh session failed. Retry in 27 sec..."); vTaskDelay(27000 / portTICK_PERIOD_MS); } } zp_start_read_task(z_loan_mut(session), NULL); zp_start_lease_task(z_loan_mut(session), NULL); // 发布者 const char *pub_key_expr = "demo/esp32/ping"; ESP_LOGI(TAG, "Declare PUBlisher '%s'...", pub_key_expr); z_owned_keyexpr_t pub_key; z_keyexpr_from_str(&pub_key, pub_key_expr); z_owned_publisher_t pub; z_declare_publisher(z_loan(session), &pub, z_loan(pub_key), NULL); z_drop(z_move(pub_key)); // 订阅者 const char *sub_key_expr = "demo/esp32/ping"; ESP_LOGI(TAG, "Declare SUBscriber '%s'...", sub_key_expr); z_owned_keyexpr_t sub_key; z_keyexpr_from_str(&sub_key, sub_key_expr); z_owned_closure_sample_t callback; z_closure(&callback, data_handler, NULL, NULL); z_owned_subscriber_t sub; z_declare_subscriber(z_loan(session), &sub, z_loan(sub_key), z_move(callback), NULL); z_drop(z_move(sub_key)); int count = 0; char payload_buffer[128]; while (1) { snprintf(payload_buffer, sizeof(payload_buffer), "ESP32 Message #%d", count++); ESP_LOGI(TAG, "[Publisher] Sending: '%s'", payload_buffer); z_owned_bytes_t payload; z_bytes_copy_from_str(&payload, payload_buffer); z_publisher_put(z_loan(pub), z_move(payload), NULL); // 等待23秒后发送下一条消息 vTaskDelay(23000 / portTICK_PERIOD_MS); } }
错误日志
I (2569) WIFI: got ip:192.168.1.101 I (2569) WIFI: connected to SSID:XXXXXXXXX I (2569) ZENOH_APP: Starting Zenoh application in CLIENT mode... I (2579) ZENOH_APP: Opening Zenoh session: tcp/212.71.244.198:7447 E (2579) ZENOH_APP: Zenoh session failed. Retry in 27 sec...
详细ESP日志
OK! Opening Zenoh Session...D (4345) lwip: udp_bind(ipaddr = D (4345) lwip: 0.0.0.0 D (4345) lwip: , port = 16452) D (4345) lwip: udp_bind: bound to D (4355) lwip: 0.0.0.0 D (4355) lwip: , port 16452) D (4355) lwip: udp_send D (4355) lwip: udp_send: added header in given pbuf 0x3fcb46ec D (4365) lwip: udp_send: sending datagram of length 39 D (4375) lwip: udp_send: UDP packet length 39 D (4375) lwip: udp_send: UDP checksum 0x6c21 D (4375) lwip: udp_send: ip_output_if (,,,,0x11,) D (4395) wifi:eb is dhcp or dns sport = 16452, dport = 53 D (4435) lwip: udp_input: received datagram of length 55 D (4435) lwip: UDP header: D (4435) lwip: +-------------------------------+ D (4435) lwip: | 53 | 16452 | (src port, dest port) D (4435) lwip: +-------------------------------+ D (4445) lwip: | 55 | 0x5c38 | (len, chksum) D (4455) lwip: +-------------------------------+ D (4455) lwip: udp ( D (4455) lwip: 192.168.1.100 D (4455) lwip: , 16452) <-- ( D (4465) lwip: 192.168.1.1 D (4465) lwip: , 53) D (4465) lwip: pcb ( D (4465) lwip: 0.0.0.0 D (4475) lwip: , 16452) <-- ( D (4475) lwip: 0.0.0.0 D (4475) lwip: , 0) D (4475) lwip: pcb ( D (4475) lwip: 0.0.0.0 D (4485) lwip: , 68) <-- ( D (4485) lwip: 0.0.0.0 D (4485) lwip: , 67) D (4485) lwip: udp_input: calculating checksum D (4495) lwip: tcp_close: closing in D (4495) lwip: State: CLOSED Unable to open session!
排查建议
- 单独测试TCP连接:在代码中添加独立的TCP客户端逻辑,直接连接
212.71.244.198:7447,验证ESP32能否建立基础TCP连接,排除Zenoh库以外的网络问题。 - 切换连接协议:尝试使用WebSocket协议连接公共服务器,端点格式改为
ws/demo.zenoh.io:80,部分网络环境对WebSocket的兼容性更好。 - 同步系统时间:检查ESP32的系统时间是否正确,若未同步NTP,可能导致连接握手失败(即使使用明文TCP,部分服务依赖时间校验)。
- 开启Zenoh调试日志:通过编译选项或配置变量开启Zenoh库的详细日志,查看连接失败的具体触发点(如握手超时、协议不兼容等)。
内容的提问来源于stack exchange,提问作者George Violettas
相关产品推荐
相关产品推荐

