espidf的esp32版的webServer
·
参考
platformio的esp32版的websocketServer.csdn
配置
idf.py menuconfig
# 打开
(Top) → Component config → HTTP Server → [*] WebSocket server support
wifi 配置共用
app_wifi.h
#ifndef _APP_WIFI_H_
#define _APP_WIFI_H_
#ifdef __cplusplus
extern "C" {
#endif
void app_wifi_main();
#ifdef __cplusplus
}
#endif
#endif
app_wifi.c
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_netif.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "app_wifi.h"
// ============================================================
// WiFi 配置
// ============================================================
#define WIFI_SSID "ming0"
#define WIFI_PASSWORD "123456"
#define WIFI_MAX_RETRY 5
// ============================================================
// TAG
// ============================================================
static const char *TAG = "app_wifi";
// ============================================================
// WiFi 状态
// ============================================================
static int s_retry_num = 0;
static EventGroupHandle_t s_wifi_event_group = NULL;
// ============================================================
// Event Bits
// ============================================================
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
// ============================================================
// WiFi Event Handler
// ============================================================
static void wifi_event_handler(
void *arg,
esp_event_base_t event_base,
int32_t event_id,
void *event_data)
{
// ========================================================
// STA 启动
// ========================================================
if (event_base == WIFI_EVENT &&
event_id == WIFI_EVENT_STA_START)
{
ESP_LOGI(
TAG,
"WiFi STA started"
);
esp_wifi_connect();
return;
}
// ========================================================
// STA 断开
// ========================================================
if (event_base == WIFI_EVENT &&
event_id == WIFI_EVENT_STA_DISCONNECTED)
{
if (s_retry_num < WIFI_MAX_RETRY)
{
esp_wifi_connect();
s_retry_num++;
ESP_LOGW(
TAG,
"WiFi disconnected, retry %d/%d",
s_retry_num,
WIFI_MAX_RETRY
);
}
else
{
ESP_LOGE(
TAG,
"WiFi connect failed"
);
if (s_wifi_event_group != NULL)
{
xEventGroupSetBits(
s_wifi_event_group,
WIFI_FAIL_BIT
);
}
}
return;
}
// ========================================================
// STA 获取 IP
// ========================================================
if (event_base == IP_EVENT &&
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)
);
ESP_LOGI(
TAG,
"Netmask: " IPSTR,
IP2STR(&event->ip_info.netmask)
);
ESP_LOGI(
TAG,
"Gateway: " IPSTR,
IP2STR(&event->ip_info.gw)
);
s_retry_num = 0;
if (s_wifi_event_group != NULL)
{
xEventGroupSetBits(
s_wifi_event_group,
WIFI_CONNECTED_BIT
);
}
return;
}
}
// ============================================================
// 初始化 STA
// ============================================================
static void wifi_init_sta(void)
{
wifi_config_t wifi_config = {
0
};
// --------------------------------------------------------
// SSID
// --------------------------------------------------------
strncpy(
(char *)wifi_config.sta.ssid,
WIFI_SSID,
sizeof(wifi_config.sta.ssid) - 1
);
// --------------------------------------------------------
// Password
// --------------------------------------------------------
strncpy(
(char *)wifi_config.sta.password,
WIFI_PASSWORD,
sizeof(wifi_config.sta.password) - 1
);
// --------------------------------------------------------
// WiFi STA 配置
// --------------------------------------------------------
ESP_ERROR_CHECK(
esp_wifi_set_config(
WIFI_IF_STA,
&wifi_config
)
);
ESP_LOGI(
TAG,
"STA configured"
);
ESP_LOGI(
TAG,
"SSID: %s",
WIFI_SSID
);
}
// ============================================================
// app_wifi_main
// ============================================================
void app_wifi_main(void)
{
esp_err_t ret;
// ========================================================
// 1. 初始化 NVS
// ========================================================
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);
// ========================================================
// 2. 初始化 TCP/IP 网络栈
// ========================================================
ESP_ERROR_CHECK(
esp_netif_init()
);
// ========================================================
// 3. 创建默认 Event Loop
// ========================================================
ESP_ERROR_CHECK(
esp_event_loop_create_default()
);
// ========================================================
// 4. 创建 Event Group
// ========================================================
s_wifi_event_group =
xEventGroupCreate();
if (s_wifi_event_group == NULL)
{
ESP_LOGE(
TAG,
"Failed to create event group"
);
return;
}
// ========================================================
// 5. 创建 STA 网络接口
// ========================================================
esp_netif_t *sta_netif =
esp_netif_create_default_wifi_sta();
if (sta_netif == NULL)
{
ESP_LOGE(
TAG,
"Failed to create STA netif"
);
return;
}
// ========================================================
// 6. 初始化 WiFi Driver
// ========================================================
wifi_init_config_t cfg =
WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(
esp_wifi_init(&cfg)
);
// ========================================================
// 7. 注册 WiFi Event
// ========================================================
ESP_ERROR_CHECK(
esp_event_handler_instance_register(
WIFI_EVENT,
ESP_EVENT_ANY_ID,
&wifi_event_handler,
NULL,
NULL
)
);
// ========================================================
// 8. 注册 IP Event
// ========================================================
ESP_ERROR_CHECK(
esp_event_handler_instance_register(
IP_EVENT,
IP_EVENT_STA_GOT_IP,
&wifi_event_handler,
NULL,
NULL
)
);
// ========================================================
// 9. 配置 STA
// ========================================================
ESP_ERROR_CHECK(
esp_wifi_set_mode(
WIFI_MODE_STA
)
);
wifi_init_sta();
// ========================================================
// 10. 启动 WiFi
// ========================================================
ESP_ERROR_CHECK(
esp_wifi_start()
);
// ========================================================
// 11. 关闭 WiFi 省电
// ========================================================
ESP_ERROR_CHECK(
esp_wifi_set_ps(
WIFI_PS_NONE
)
);
ESP_LOGI(
TAG,
"WiFi started"
);
// ========================================================
// 12. 等待连接结果
// ========================================================
EventBits_t bits =
xEventGroupWaitBits(
s_wifi_event_group,
WIFI_CONNECTED_BIT |
WIFI_FAIL_BIT,
pdFALSE,
pdFALSE,
portMAX_DELAY
);
// ========================================================
// 13. 判断连接结果
// ========================================================
if (bits & WIFI_CONNECTED_BIT)
{
ESP_LOGI(
TAG,
"Connected to WiFi"
);
}
else if (bits & WIFI_FAIL_BIT)
{
ESP_LOGE(
TAG,
"Failed to connect to WiFi"
);
}
// ========================================================
// 14. 删除 Event Group
// ========================================================
vEventGroupDelete(
s_wifi_event_group
);
s_wifi_event_group = NULL;
ESP_LOGI(
TAG,
"app_wifi_main finished"
);
}
webServer三选1
app_websocketServer.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_err.h"
#include "esp_http_server.h"
#include "app_wifi.h"
static const char *TAG = "WebSocket Server";
static httpd_handle_t server = NULL;
// ============================================================
// WebSocket 接收处理
//
// 客户端发什么,ESP32 回什么
// ============================================================
static esp_err_t handle_ws_req(httpd_req_t *req)
{
// --------------------------------------------------------
// WebSocket 握手
// --------------------------------------------------------
if (req->method == HTTP_GET)
{
ESP_LOGI(
TAG,
"WebSocket handshake done"
);
return ESP_OK;
}
// --------------------------------------------------------
// 获取 Frame 长度
// --------------------------------------------------------
httpd_ws_frame_t ws_pkt;
memset(
&ws_pkt,
0,
sizeof(ws_pkt)
);
esp_err_t ret =
httpd_ws_recv_frame(
req,
&ws_pkt,
0
);
if (ret != ESP_OK)
{
ESP_LOGE(
TAG,
"httpd_ws_recv_frame failed: %s",
esp_err_to_name(ret)
);
return ret;
}
ESP_LOGI(
TAG,
"Received frame, type=%d, len=%d",
ws_pkt.type,
(int)ws_pkt.len
);
// --------------------------------------------------------
// 分配 Payload
// --------------------------------------------------------
uint8_t *buf = NULL;
if (ws_pkt.len > 0)
{
buf =
calloc(
1,
ws_pkt.len + 1
);
if (buf == NULL)
{
ESP_LOGE(
TAG,
"malloc failed"
);
return ESP_ERR_NO_MEM;
}
ws_pkt.payload = buf;
// ----------------------------------------------------
// 接收真正的数据
// ----------------------------------------------------
ret =
httpd_ws_recv_frame(
req,
&ws_pkt,
ws_pkt.len
);
if (ret != ESP_OK)
{
ESP_LOGE(
TAG,
"httpd_ws_recv_frame failed: %s",
esp_err_to_name(ret)
);
free(buf);
return ret;
}
buf[ws_pkt.len] = '\0';
ESP_LOGI(
TAG,
"Client -> ESP32: %s",
(char *)buf
);
}
// --------------------------------------------------------
// Echo
//
// 客户端发什么
// ESP32 回什么
// --------------------------------------------------------
if (ws_pkt.type == HTTPD_WS_TYPE_TEXT)
{
ret =
httpd_ws_send_frame(
req,
&ws_pkt
);
if (ret != ESP_OK)
{
ESP_LOGE(
TAG,
"Echo failed: %s",
esp_err_to_name(ret)
);
}
else
{
ESP_LOGI(
TAG,
"ESP32 -> Client: echo"
);
}
}
free(buf);
return ret;
}
// ============================================================
// 每 1 秒广播一次
//
// 发送:
// 0 hello
// 1 hello
// 2 hello
// ...
// ============================================================
static void websocket_periodic_task(void *arg)
{
uint32_t sequence = 0;
while (1)
{
vTaskDelay(
pdMS_TO_TICKS(1000)
);
if (server == NULL)
{
continue;
}
// ----------------------------------------------------
// 生成消息
// ----------------------------------------------------
char message[64];
snprintf(
message,
sizeof(message),
"%lu hello",
(unsigned long)sequence
);
sequence++;
ESP_LOGI(
TAG,
"Broadcast: %s",
message
);
// ----------------------------------------------------
// WebSocket Frame
// ----------------------------------------------------
httpd_ws_frame_t ws_pkt;
memset(
&ws_pkt,
0,
sizeof(ws_pkt)
);
ws_pkt.type =
HTTPD_WS_TYPE_TEXT;
ws_pkt.payload =
(uint8_t *)message;
ws_pkt.len =
strlen(message);
// ----------------------------------------------------
// 获取所有客户端
// ----------------------------------------------------
size_t fds =
CONFIG_LWIP_MAX_LISTENING_TCP;
int *client_fds =
calloc(
fds,
sizeof(int)
);
if (client_fds == NULL)
{
ESP_LOGE(
TAG,
"Failed to allocate client_fds"
);
continue;
}
esp_err_t ret =
httpd_get_client_list(
server,
&fds,
client_fds
);
if (ret != ESP_OK)
{
ESP_LOGE(
TAG,
"httpd_get_client_list failed: %s",
esp_err_to_name(ret)
);
free(client_fds);
continue;
}
// ----------------------------------------------------
// 广播
// ----------------------------------------------------
for (size_t i = 0; i < fds; i++)
{
int fd =
client_fds[i];
int client_info =
httpd_ws_get_fd_info(
server,
fd
);
if (client_info ==
HTTPD_WS_CLIENT_WEBSOCKET)
{
ret =
httpd_ws_send_frame_async(
server,
fd,
&ws_pkt
);
if (ret != ESP_OK)
{
ESP_LOGW(
TAG,
"Send failed fd=%d: %s",
fd,
esp_err_to_name(ret)
);
}
}
}
free(client_fds);
}
}
// ============================================================
// WebSocket Server
// ============================================================
httpd_handle_t setup_websocket_server(void)
{
httpd_config_t config =
HTTPD_DEFAULT_CONFIG();
// --------------------------------------------------------
// WebSocket /ws
// --------------------------------------------------------
httpd_uri_t ws = {
.uri = "/ws",
.method = HTTP_GET,
.handler = handle_ws_req,
.user_ctx = NULL,
.is_websocket = true
};
// --------------------------------------------------------
// 启动 HTTP Server
// --------------------------------------------------------
esp_err_t ret =
httpd_start(
&server,
&config
);
if (ret != ESP_OK)
{
ESP_LOGE(
TAG,
"httpd_start failed: %s",
esp_err_to_name(ret)
);
return NULL;
}
// --------------------------------------------------------
// 注册 WebSocket
// --------------------------------------------------------
ret =
httpd_register_uri_handler(
server,
&ws
);
if (ret != ESP_OK)
{
ESP_LOGE(
TAG,
"register /ws failed: %s",
esp_err_to_name(ret)
);
return NULL;
}
ESP_LOGI(
TAG,
"WebSocket server started"
);
// --------------------------------------------------------
// 创建周期发送任务
// --------------------------------------------------------
BaseType_t task_ret =
xTaskCreate(
websocket_periodic_task,
"ws_periodic",
4096,
NULL,
5,
NULL
);
if (task_ret != pdPASS)
{
ESP_LOGE(
TAG,
"Failed to create websocket task"
);
}
return server;
}
// ============================================================
// app_main
// ============================================================
void app_main(void)
{
// --------------------------------------------------------
// 连接现有路由器
// --------------------------------------------------------
app_wifi_main();
// --------------------------------------------------------
// 启动 WebSocket Server
// --------------------------------------------------------
setup_websocket_server();
ESP_LOGI(
TAG,
"ESP32 WebSocket Server is running"
);
}
app_udpServer.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "app_wifi.h"
// ============================================================
// UDP 配置
// ============================================================
#define UDP_PORT 5000
#define UDP_BUFFER_SIZE 1024
static const char *TAG = "UDP Server";
// ============================================================
// UDP Socket
// ============================================================
static int udp_socket = -1;
// ============================================================
// 最后一个 UDP 客户端
//
// UDP 没有连接的概念
// 所以记录最后一个给 ESP32 发数据的客户端
// ============================================================
static struct sockaddr_in client_addr;
static bool client_valid = false;
// ============================================================
// UDP 接收 + Echo
//
// 客户端发什么
// ESP32 回什么
// ============================================================
static void udp_receive_task(void *arg)
{
char rx_buffer[UDP_BUFFER_SIZE];
while (1)
{
struct sockaddr_in source_addr;
socklen_t addr_len =
sizeof(source_addr);
// ----------------------------------------------------
// 等待 UDP 数据
// ----------------------------------------------------
int len =
recvfrom(
udp_socket,
rx_buffer,
sizeof(rx_buffer) - 1,
0,
(struct sockaddr *)&source_addr,
&addr_len
);
if (len < 0)
{
ESP_LOGE(
TAG,
"recvfrom failed errno=%d",
errno
);
continue;
}
rx_buffer[len] = '\0';
// ----------------------------------------------------
// 保存客户端地址
// ----------------------------------------------------
memcpy(
&client_addr,
&source_addr,
sizeof(client_addr)
);
client_valid = true;
// ----------------------------------------------------
// 打印客户端地址
// ----------------------------------------------------
char addr_str[INET_ADDRSTRLEN];
inet_ntop(
AF_INET,
&source_addr.sin_addr,
addr_str,
sizeof(addr_str)
);
ESP_LOGI(
TAG,
"Client %s:%d -> ESP32: %s",
addr_str,
ntohs(source_addr.sin_port),
rx_buffer
);
// ----------------------------------------------------
// Echo
//
// 客户端发什么
// ESP32 回什么
// ----------------------------------------------------
int ret =
sendto(
udp_socket,
rx_buffer,
len,
0,
(struct sockaddr *)&source_addr,
addr_len
);
if (ret < 0)
{
ESP_LOGE(
TAG,
"sendto failed errno=%d",
errno
);
}
else
{
ESP_LOGI(
TAG,
"ESP32 -> Client: echo"
);
}
}
}
// ============================================================
// 每 1 秒发送一次
//
// 发送:
//
// 0 hello
// 1 hello
// 2 hello
// 3 hello
// ...
//
// 发送给最后一个 UDP 客户端
// ============================================================
static void udp_periodic_task(void *arg)
{
uint32_t sequence = 0;
while (1)
{
vTaskDelay(
pdMS_TO_TICKS(1000)
);
// ----------------------------------------------------
// 还没有客户端
// ----------------------------------------------------
if (!client_valid)
{
continue;
}
// ----------------------------------------------------
// 生成消息
// ----------------------------------------------------
char message[64];
snprintf(
message,
sizeof(message),
"%lu hello",
(unsigned long)sequence
);
sequence++;
ESP_LOGI(
TAG,
"Periodic send: %s",
message
);
// ----------------------------------------------------
// UDP 发送
// ----------------------------------------------------
int ret =
sendto(
udp_socket,
message,
strlen(message),
0,
(struct sockaddr *)&client_addr,
sizeof(client_addr)
);
if (ret < 0)
{
ESP_LOGE(
TAG,
"Periodic send failed errno=%d",
errno
);
}
}
}
// ============================================================
// 创建 UDP Server
// ============================================================
static void udp_server_start(void)
{
// --------------------------------------------------------
// 创建 UDP Socket
// --------------------------------------------------------
udp_socket =
socket(
AF_INET,
SOCK_DGRAM,
IPPROTO_IP
);
if (udp_socket < 0)
{
ESP_LOGE(
TAG,
"Unable to create socket errno=%d",
errno
);
return;
}
// --------------------------------------------------------
// Server 地址
// --------------------------------------------------------
struct sockaddr_in server_addr;
memset(
&server_addr,
0,
sizeof(server_addr)
);
server_addr.sin_family =
AF_INET;
server_addr.sin_addr.s_addr =
htonl(INADDR_ANY);
server_addr.sin_port =
htons(UDP_PORT);
// --------------------------------------------------------
// bind
// --------------------------------------------------------
int ret =
bind(
udp_socket,
(struct sockaddr *)&server_addr,
sizeof(server_addr)
);
if (ret < 0)
{
ESP_LOGE(
TAG,
"bind failed errno=%d",
errno
);
close(udp_socket);
udp_socket = -1;
return;
}
// --------------------------------------------------------
// 启动接收任务
// --------------------------------------------------------
BaseType_t task_ret =
xTaskCreate(
udp_receive_task,
"udp_receive",
4096,
NULL,
5,
NULL
);
if (task_ret != pdPASS)
{
ESP_LOGE(
TAG,
"Failed to create UDP receive task"
);
close(udp_socket);
udp_socket = -1;
return;
}
// --------------------------------------------------------
// 启动 1 秒周期发送任务
// --------------------------------------------------------
task_ret =
xTaskCreate(
udp_periodic_task,
"udp_periodic",
4096,
NULL,
5,
NULL
);
if (task_ret != pdPASS)
{
ESP_LOGE(
TAG,
"Failed to create UDP periodic task"
);
return;
}
ESP_LOGI(
TAG,
"UDP server started, port=%d",
UDP_PORT
);
}
// ============================================================
// app_main
// ============================================================
void app_main(void)
{
// --------------------------------------------------------
// 连接现有路由器
// --------------------------------------------------------
app_wifi_main();
// --------------------------------------------------------
// 启动 UDP Server
// --------------------------------------------------------
udp_server_start();
ESP_LOGI(
TAG,
"ESP32 UDP Server is running"
);
}
app_tcpServer.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "app_wifi.h"
// ============================================================
// TCP 配置
// ============================================================
#define TCP_PORT 5000
#define TCP_BUFFER_SIZE 1024
static const char *TAG = "TCP Server";
// ============================================================
// TCP Server Socket
// ============================================================
static int server_socket = -1;
// ============================================================
// 当前客户端 Socket
//
// 简单版本:只支持一个客户端
// ============================================================
static int client_socket = -1;
// ============================================================
// TCP 接收任务
//
// 客户端发什么
// ESP32 回什么
// ============================================================
static void tcp_receive_task(void *arg)
{
char rx_buffer[TCP_BUFFER_SIZE];
while (1)
{
// ----------------------------------------------------
// 等待客户端连接
// ----------------------------------------------------
struct sockaddr_in client_addr;
socklen_t addr_len =
sizeof(client_addr);
ESP_LOGI(
TAG,
"Waiting for client..."
);
client_socket =
accept(
server_socket,
(struct sockaddr *)&client_addr,
&addr_len
);
if (client_socket < 0)
{
ESP_LOGE(
TAG,
"accept failed errno=%d",
errno
);
continue;
}
// ----------------------------------------------------
// 获取客户端 IP
// ----------------------------------------------------
char addr_str[INET_ADDRSTRLEN];
inet_ntop(
AF_INET,
&client_addr.sin_addr,
addr_str,
sizeof(addr_str)
);
ESP_LOGI(
TAG,
"Client connected: %s:%d",
addr_str,
ntohs(client_addr.sin_port)
);
// ----------------------------------------------------
// 接收客户端数据
// ----------------------------------------------------
while (1)
{
int len =
recv(
client_socket,
rx_buffer,
sizeof(rx_buffer) - 1,
0
);
// ------------------------------------------------
// 接收失败
// ------------------------------------------------
if (len < 0)
{
ESP_LOGE(
TAG,
"recv failed errno=%d",
errno
);
break;
}
// ------------------------------------------------
// 客户端主动断开
// ------------------------------------------------
if (len == 0)
{
ESP_LOGI(
TAG,
"Client disconnected"
);
break;
}
rx_buffer[len] =
'\0';
ESP_LOGI(
TAG,
"Client -> ESP32: %s",
rx_buffer
);
// ------------------------------------------------
// Echo
//
// 客户端发什么
// ESP32 回什么
// ------------------------------------------------
int ret =
send(
client_socket,
rx_buffer,
len,
0
);
if (ret < 0)
{
ESP_LOGE(
TAG,
"send failed errno=%d",
errno
);
break;
}
ESP_LOGI(
TAG,
"ESP32 -> Client: echo"
);
}
// ----------------------------------------------------
// 关闭客户端
// ----------------------------------------------------
close(client_socket);
client_socket = -1;
ESP_LOGI(
TAG,
"Client socket closed"
);
}
}
// ============================================================
// 每 1 秒发送一次
//
// 0 hello
// 1 hello
// 2 hello
// ...
// ============================================================
static void tcp_periodic_task(void *arg)
{
uint32_t sequence = 0;
while (1)
{
vTaskDelay(
pdMS_TO_TICKS(1000)
);
// ----------------------------------------------------
// 当前没有客户端
// ----------------------------------------------------
if (client_socket < 0)
{
continue;
}
// ----------------------------------------------------
// 生成消息
// ----------------------------------------------------
char message[64];
snprintf(
message,
sizeof(message),
"%lu hello",
(unsigned long)sequence
);
sequence++;
ESP_LOGI(
TAG,
"Periodic send: %s",
message
);
// ----------------------------------------------------
// TCP 发送
// ----------------------------------------------------
int ret =
send(
client_socket,
message,
strlen(message),
0
);
if (ret < 0)
{
ESP_LOGW(
TAG,
"Periodic send failed errno=%d",
errno
);
/*
* 不要在这里 close()
*
* tcp_receive_task() 会检测到:
*
* recv() == 0
*
* 或 recv() < 0
*
* 然后负责关闭 socket。
*/
}
}
}
// ============================================================
// 启动 TCP Server
// ============================================================
static void tcp_server_start(void)
{
// --------------------------------------------------------
// 创建 TCP Socket
// --------------------------------------------------------
server_socket =
socket(
AF_INET,
SOCK_STREAM,
IPPROTO_IP
);
if (server_socket < 0)
{
ESP_LOGE(
TAG,
"Unable to create socket errno=%d",
errno
);
return;
}
// --------------------------------------------------------
// Server 地址
// --------------------------------------------------------
struct sockaddr_in server_addr;
memset(
&server_addr,
0,
sizeof(server_addr)
);
server_addr.sin_family =
AF_INET;
server_addr.sin_addr.s_addr =
htonl(INADDR_ANY);
server_addr.sin_port =
htons(TCP_PORT);
// --------------------------------------------------------
// bind
// --------------------------------------------------------
int ret =
bind(
server_socket,
(struct sockaddr *)&server_addr,
sizeof(server_addr)
);
if (ret < 0)
{
ESP_LOGE(
TAG,
"bind failed errno=%d",
errno
);
close(server_socket);
server_socket = -1;
return;
}
// --------------------------------------------------------
// listen
// --------------------------------------------------------
ret =
listen(
server_socket,
1
);
if (ret < 0)
{
ESP_LOGE(
TAG,
"listen failed errno=%d",
errno
);
close(server_socket);
server_socket = -1;
return;
}
ESP_LOGI(
TAG,
"TCP server listening on port %d",
TCP_PORT
);
// --------------------------------------------------------
// TCP 接收任务
// --------------------------------------------------------
BaseType_t task_ret =
xTaskCreate(
tcp_receive_task,
"tcp_receive",
4096,
NULL,
5,
NULL
);
if (task_ret != pdPASS)
{
ESP_LOGE(
TAG,
"Failed to create TCP receive task"
);
return;
}
// --------------------------------------------------------
// 周期发送任务
// --------------------------------------------------------
task_ret =
xTaskCreate(
tcp_periodic_task,
"tcp_periodic",
4096,
NULL,
5,
NULL
);
if (task_ret != pdPASS)
{
ESP_LOGE(
TAG,
"Failed to create TCP periodic task"
);
return;
}
ESP_LOGI(
TAG,
"TCP server started"
);
}
// ============================================================
// app_main
// ============================================================
void app_main(void)
{
// --------------------------------------------------------
// 连接现有路由器
// --------------------------------------------------------
app_wifi_main();
// --------------------------------------------------------
// 启动 TCP Server
// --------------------------------------------------------
tcp_server_start();
ESP_LOGI(
TAG,
"ESP32 TCP Server is running"
);
}
测试
# ws 连接
ws://192.168.3.45/ws
# tcp或udp
192.168.3.45:5000
# 收到1次hello
<-1 hello
<-2 hello
...
<-n hello
# 发送回环
-> abc
<- abc
更多推荐



所有评论(0)