硬件:ESP32-Devkit-V4 MODEL:ESP32-32U
库:ESP-IDF v5.4.1
系统:windows中的虚拟机 ubuntu 22.04
实现STA,主动连接AP后,打印IP地址,获取IP后,创建socket,搭建UDP 服务器,实现接收数据的反向回传
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "lwip/sockets.h" // 添加UDP套接字支持
#include "lwip/netdb.h" // 添加网络地址转换#define WIFI_SSID "wifi name"
#define WIFI_PASS "wifi password"
#define UDP_PORT 12345 // UDP服务器监听端口
static const char *TAG = "WIFI_DEMO";// 全局UDP套接字变量
static int udp_socket = -1;// 事件处理器
static void wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {if (event_id == WIFI_EVENT_STA_DISCONNECTED) {// 关闭现有UDP套接字(如果存在)if (udp_socket >= 0) {close(udp_socket);udp_socket = -1;ESP_LOGW(TAG, "UDP socket closed due to disconnection");}esp_wifi_connect(); // 断线自动重连} else if (event_id == IP_EVENT_STA_GOT_IP) {ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;ESP_LOGI(TAG, "Got IP: " IPSTR, IP2STR(&event->ip_info.ip));// 创建UDP服务器udp_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);if (udp_socket < 0) {ESP_LOGE(TAG, "Failed to create UDP socket: errno %d", errno);return;}// 配置服务器地址struct sockaddr_in server_addr = {.sin_family = AF_INET,.sin_port = htons(UDP_PORT),.sin_addr.s_addr = htonl(INADDR_ANY) // 监听所有接口};// 绑定套接字if (bind(udp_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {ESP_LOGE(TAG, "Socket bind failed: errno %d", errno);close(udp_socket);udp_socket = -1;return;}ESP_LOGI(TAG, "UDP server started on port %d", UDP_PORT);}
}// UDP数据处理任务
static void udp_server_task(void *pvParameters) {struct sockaddr_in source_addr;socklen_t addr_len = sizeof(source_addr);char rx_buffer[128];while (1) {if (udp_socket < 0) {vTaskDelay(1000 / portTICK_PERIOD_MS);continue;}// 接收数据int len = recvfrom(udp_socket, rx_buffer, sizeof(rx_buffer) - 1, 0,(struct sockaddr *)&source_addr, &addr_len);if (len > 0) {rx_buffer[len] = '\0'; // 确保字符串终止// 记录接收信息char source_ip[16];inet_ntoa_r(source_addr.sin_addr, source_ip, sizeof(source_ip));ESP_LOGI(TAG, "Received %d bytes from %s:%d", len, source_ip, ntohs(source_addr.sin_port));ESP_LOGI(TAG, "Data: %s", rx_buffer);// 数据处理示例(反转字符串)char response[128];for (int i = 0; i < len; i++) {response[i] = rx_buffer[len - 1 - i];}response[len] = '\0';// 发送处理后的数据sendto(udp_socket, response, len, 0, (struct sockaddr *)&source_addr, addr_len);ESP_LOGI(TAG, "Sent response: %s", response);} else if (len < 0 && errno != EAGAIN) {ESP_LOGE(TAG, "recvfrom failed: errno %d", errno);}vTaskDelay(10 / portTICK_PERIOD_MS);}
}void app_main() {// 初始化NVSESP_ERROR_CHECK(nvs_flash_init());// 初始化网络栈和事件循环esp_netif_init();esp_event_loop_create_default();esp_netif_create_default_wifi_sta();// WiFi驱动配置wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();ESP_ERROR_CHECK(esp_wifi_init(&cfg));// 注册事件处理器ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL));// 设置WiFi凭证wifi_config_t wifi_config = {.sta = { .ssid = WIFI_SSID,.password = WIFI_PASS,.threshold.authmode = WIFI_AUTH_WPA2_PSK}};ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));// 启动WiFiESP_ERROR_CHECK(esp_wifi_start());esp_wifi_connect();// 创建UDP处理任务xTaskCreate(udp_server_task, "udp_server", 4096, NULL, 5, NULL);
}