获取ESP32/ESP-IDF上的开放TCP/IP套接字数量
获取ESP32/ESP-IDF上的开放TCP/IP套接字数量
嘿,这个问题我刚好在项目里实操过,在ESP-IDF环境下有几种实用的方法能获取当前活跃的TCP/IP连接数,我给你详细拆解一下:
1. 利用LWIP协议栈的内置接口(最直接的方法)
ESP-IDF底层依赖的是LWIP协议栈,它本身就提供了遍历TCP连接控制块(PCB)的接口,我们可以通过这些接口统计活跃连接数:
步骤说明:
首先要确保你的工程启用了LWIP的必要功能:在sdkconfig中开启CONFIG_LWIP_STATS和CONFIG_LWIP_TCP_STATS(路径一般是「Component config → LWIP → Statistics」),这两个选项是启用TCP连接统计的前提。
示例代码:
#include "lwip/tcp.h" #include "lwip/stats.h" uint32_t get_active_tcp_connections(void) { uint32_t active_count = 0; struct tcp_pcb *pcb; // 统计处于监听状态的TCP套接字(比如服务器的listen fd) for (pcb = tcp_pcb_listen(); pcb != NULL; pcb = pcb->next) { active_count++; } // 统计已建立连接的活跃TCP套接字 for (pcb = tcp_pcb_active(); pcb != NULL; pcb = pcb->next) { // 可选:可以根据连接状态过滤,比如只统计ESTABLISHED状态 if (pcb->state == ESTABLISHED) { active_count++; } } return active_count; }
这里可以根据需求调整过滤逻辑,比如如果只需要统计已建立的连接(而非监听状态的套接字),就可以去掉tcp_pcb_listen()的遍历部分。
2. 自定义连接生命周期跟踪(更灵活)
如果LWIP的默认统计满足不了你的精细化需求(比如要区分客户端/服务器连接、特定端口的连接),可以自己在套接字的创建和关闭节点做计数:
示例实现:
#include "freertos/FreeRTOS.h" #include "freertos/semphr.h" // 全局计数变量,用互斥锁保证线程安全 static uint32_t g_active_tcp_conns = 0; static portMUX_TYPE g_conn_mutex = portMUX_INITIALIZER_UNLOCKED; // 创建/接受连接时调用,增加计数 void tcp_conn_inc(void) { portENTER_CRITICAL(&g_conn_mutex); g_active_tcp_conns++; portEXIT_CRITICAL(&g_conn_mutex); } // 关闭连接时调用,减少计数 void tcp_conn_dec(void) { portENTER_CRITICAL(&g_conn_mutex); if (g_active_tcp_conns > 0) { g_active_tcp_conns--; } portEXIT_CRITICAL(&g_conn_mutex); } // 获取当前活跃连接数 uint32_t get_custom_tcp_conn_count(void) { uint32_t count; portENTER_CRITICAL(&g_conn_mutex); count = g_active_tcp_conns; portEXIT_CRITICAL(&g_conn_mutex); return count; }
然后在你的业务代码里:
- 调用
socket()创建TCP客户端套接字成功后,执行tcp_conn_inc() - 调用
accept()接收到新的服务器连接后,执行tcp_conn_inc() - 调用
close()或shutdown()关闭套接字后,执行tcp_conn_dec()
这种方法的优势是完全可控,你可以根据业务场景自定义计数规则。
注意事项
- 如果你使用了ESP-IDF的
esp_netif组件,它的事件(比如ESP_NETIF_CONNECTED)是针对整个网络接口的,不是单个TCP连接,所以不能直接用它来统计连接数,还是要结合上面的方法。 - 开启LWIP统计功能会有极小的内存开销,对于大多数嵌入式应用来说完全可以忽略。
内容来源于stack exchange
相关产品推荐
相关产品推荐

