这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【ESP-IDF系列】【ESP32】使用ESP-32-S3进行UDP通讯实现数据

共5条 1/1 1 跳转至

【ESP-IDF系列】【ESP32】使用ESP-32-S3进行UDP通讯实现数据收发

工程师
2025-04-21 16:31:06     打赏

简介

UDP(User Datagram Protocol,用户数据报协议)是一种无连接、轻量级的传输层协议,它属于 TCP/IP 协议族。UDP 协议的主要特点是传输速度快、延迟低,适合需要快速、实时传输数据的应用场景。不过,它并不保证数据传输的可靠性,也就是说,数据可能丢失、乱序或重复。但是相对于TCP, 它的传输速度更快, 传输过程中开销更小. 在本文中我们将探索如何使用ESP32-S3在ESP-IDF的环境下使用UDP和上位机实现数据的收发功能.


需求设备

ESP32-S3 * 1 

Python 上位机服务端


网络拓扑

未命名绘图.png


其主要的步骤为使用ESP32作为UDP客户端, 使用Python作为服务端. 当两者服务启动后, ESP32-S3 将会向指定IP地址和端口的UDP服务端发起连接. 当两者连接成功之后即可进行数据的收发.

首先, 我们需要在Python中新建一个UDP服务器, 并且成功的启动服务. 

import socket

# 配置
HOST = "0.0.0.0"  # 绑定所有局域网 IP
PORT = 12345      

# 创建 UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((HOST, PORT))

print(f"UDP server is listening on {HOST}:{PORT}...")

while True:
    data, addr = sock.recvfrom(1024)  # 接收数据(最大1024字节)
    print(f"Received from {addr}: {data.decode()}")

    # 给数据加 tag
    response = f"[RECV] {data.decode()}".encode()

    # 发送回客户端
    sock.sendto(response, addr)

使用上述代码, 可以成功的启动一个UDP的服务端, 并且对局域网内的所有设备可用. 其监听的端口为12345, 当有客户端连接到服务端的时候, 那么它将接受客户端的消息,然后将消息打上一个tag再返回给服务端. 接下来我们来完成ESP-32的客户端程序开发.


对于客户端而言, 首先需要初始化UDP的客户端, 然后当连接上之后来每隔一秒向服务端发送消息.  核心代码如下

static void udp_client_task(void *pvParameters)
{
    struct sockaddr_in server_addr, client_addr;
    int sock;
    char udp_buffer[BUFFER_SIZE];
    socklen_t client_addr_len = sizeof(client_addr);

    // 创建 UDP Socket
    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sock < 0)
    {
        ESP_LOGE(TAG, "Socket creation failed");
        vTaskDelete(NULL);
        return;
    }

    // 配置服务器地址
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(UDP_SERVER_PORT);
    server_addr.sin_addr.s_addr = inet_addr(UDP_SERVER_IP);

    ESP_LOGI(TAG, "UDP client started, sending and receiving data...");

    while (1)
    {
        // 发送 "hello world"
        const char *message = "hello world";
        int message_len = strlen(message);
        int sent_len = sendto(sock, message, message_len, 0, (struct sockaddr *)&server_addr, sizeof(server_addr));
        if (sent_len < 0)
        {
            ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);
            break;
        }
        ESP_LOGI(TAG, "Sent message: %s", message);

        // 接收数据
        int len = recvfrom(sock, udp_buffer, sizeof(udp_buffer) - 1, 0, (struct sockaddr *)&client_addr, &client_addr_len);
        if (len < 0)
        {
            ESP_LOGE(TAG, "Error occurred during receiving: errno %d", errno);
            break;
        }
        else if (len > 0)
        {
            udp_buffer[len] = '\0'; // 确保字符串以 NULL 结尾
            ESP_LOGI(TAG, "Received data: %s", udp_buffer);
        }

        vTaskDelay(1000 / portTICK_PERIOD_MS); // 每秒发送一次数据
    }

    // 关闭 Socket
    close(sock);
    vTaskDelete(NULL);
}

由于服务端是接受到消息之后才给消息打上一个TAG然后再发送回来, 因此需要客户端先发送消息. 上述代码在连接上了服务端之后便会每秒向服务端发送一条消息. 


效果如下所示(客户端发送消息和接受来自服务端打了标签的数据)

image.png


服务端接受到的数据

image.png


总结

在本文中主要对UDP的通讯进行了概述,并且探究了如何在ESP-IDF下使用UDP和服务端进行通讯. 从而实现了上位机和UDP进行双向的数据通讯. 甚至并不需要使用上位机, 也可以使用两个ESP32来完成上述的所有操作.

Esp32s3-client.zip




关键词: ESP-IDF     ESP-32     UDP通讯    

专家
2025-04-21 20:01:03     打赏
2楼

感谢分享


专家
2025-04-21 20:05:00     打赏
3楼

感谢分享


院士
2025-04-22 23:36:31     打赏
4楼

我也想玩玩ESP32,试用一下ESP32的Arduino开发环境



院士
2025-04-23 17:46:08     打赏
5楼

那就听大佬的了。直接上手idf


共5条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]