ESP32配置UDP通信
介绍
用户数据报协议UDP
UDP(User Datagram Protocol)是一种在计算机网络中常用的传输层协议,它与TCP(Transmission Control Protocol)一样属于传输层协议的一种。UDP主要用于在网络中传输数据,但与TCP不同,它是一种面向无连接的协议,不提供可靠性、流控制和错误恢复等特性。
以下是TCP(Transmission Control Protocol)和UDP(User Datagram Protocol)的一些主要对比特点:
| 特点 | TCP | UDP | 
|---|---|---|
| 连接方式 | 面向连接 | 面向无连接 | 
| 可靠性 | 提供可靠的数据传输,保证数据的完整性、顺序性 | 不提供数据可靠性保障,无顺序保证 | 
| 流控制 | 提供流量控制机制,避免网络拥塞 | 不提供流量控制,数据发送不受限制 | 
| 差错检测与恢复 | 提供差错检测和自动重传机制,确保数据的正确传输 | 不提供差错检测和重传,数据可能丢失或损坏 | 
| 适用场景 | 文件传输、网页浏览等对可靠性要求较高的应用 | 实时性要求较高的应用,如音频、视频传输 | 
| 顺序保证 | 保证数据包的顺序传输 | 不保证数据包的顺序传输 | 
| 连接建立和断开 | 三次握手建立连接,四次挥手断开连接 | 无连接建立和断开过程 | 
| 面向字节 | 是的,以字节为单位进行数据传输 | 是的,以字节为单位进行数据传输 | 
| 开销 | 较高,需要维护连接状态、流控制等 | 较低,无连接状态维护,适用于实时性要求高的应用 | 
| 适用性 | 适用于对可靠性要求较高的应用 | 适用于对实时性要求较高的应用 | 
总而言之,TCP适用于需要可靠性和顺序性的应用,而UDP适用于对实时性要求较高、能够容忍一定数据丢失的应用。
四层网络模型

 TCP/IP 四层网络协议体系结构,用于指导互联网上数据的传输和通信。该模型的四个层次分别是:
- 
链路层 (Link Layer): - 功能:负责定义与物理网络介质的接口,处理通过该介质的原始比特流。该层通常包括设备驱动程序和网络接口卡 (NIC)。
- 协议:通常使用的协议包括以太网 (Ethernet)、Wi-Fi、PPP (Point-to-Point Protocol) 等。
 
- 
网络层 (Internet Layer): - 功能:负责在不同网络之间路由数据包,实现源到目标主机的数据传输。这一层的主要目标是确保数据从源主机传输到目标主机,即实现端到端的通信。
- 协议:主要协议是 Internet Protocol (IP),包括 IPv4 和 IPv6。
 
- 
传输层 (Transport Layer): - 功能:提供端到端的通信,负责数据的分段、重组和流量控制。该层主要确保数据在源和目标主机之间的可靠传输。
- 协议:主要协议包括 Transmission Control Protocol (TCP) 和 User Datagram Protocol (UDP)。
 
- 
应用层 (Application Layer): - 功能:提供网络服务和应用程序之间的接口,允许用户访问网络上的各种服务。这一层包含了各种应用层协议,支持不同的网络应用。
- 协议:包括常见的应用层协议如 Hypertext Transfer Protocol (HTTP)、File Transfer Protocol (FTP)、Simple Mail Transfer Protocol (SMTP) 等。
 
基本方法
ESP32的基本UDP设置流程:
- 
引入库文件: 引入必要的网络功能库文件 <WiFi.h> 。#include <Arduino.h> #include <WiFi.h> 
- 
声明UDP对象: 使用 WiFiUDP 类声明一个UDP对象,该对象将用于处理UDP通信。WiFiUDP udp; 
- 
设置WiFi连接: 在 setup 函数中,配置ESP32的WiFi连接。将ESP32设置为SoftAP(访问点)模式,并指定SSID和密码。WiFi.softAP("ESP32_UDP", "987654321");
- 
初始化UDP: 在 setup 函数中,使用udp.begin(port) 初始化UDP。这里的port 参数指定UDP服务器监听的端口号。udp.begin(1133); 
- 
串口打印IP地址(可选): 在 setup 函数中,可以使用Serial.println(WiFi.softAPIP()) 将分配给SoftAP的IP地址打印到串口监视器,以便调试和验证连接。Serial.println(WiFi.softAPIP()); 
- 
处理UDP数据: 在 loop 函数中,使用udp.parsePacket() 检查是否有传入的UDP数据包。如果有,可以使用udp.read() 读取数据,并进行相应的处理。这里我将读取到的数据回发给客户端。if (udp.parsePacket()) { char val = udp.read(); // 处理接收到的数据 // 回发数据给客户端 udp.beginPacket(udp.remoteIP(), udp.remotePort()); udp.println(val); udp.endPacket(); }- 
udp.beginPacket(udp.remoteIP(), udp.remotePort()); :- beginPacket() 函数用于开始构建UDP数据包,指定了目标设备的IP地址和端口号。
- udp.remoteIP() 用于获取远程设备的IP地址。
- udp.remotePort() 用于获取远程设备的端口号。
 
- 
udp.println(val); :- println() 函数用于将数据写入UDP数据包。在这里,它将变量- val 的值写入数据包。
- udp 对象是已经声明的- WiFiUDP 对象,它管理UDP通信。
 
- 
udp.endPacket(); :- endPacket() 函数用于结束UDP数据包的构建,并将数据包发送到之前指定的远程设备的IP地址和端口号。
 
 这三行代码一起完成了以下操作: - 开始构建一个UDP数据包,指定目标设备的IP地址和端口号。
- 将数据写入UDP数据包,这里是将变量 val 的值写入。
- 结束UDP数据包的构建,并将数据包发送到远程设备。
 
- 
这样,ESP32通过UDP协议回发了接收到的数据给远程设备。要注意的是在UDP通信设备之间可以交换数据包 而无需先建立连接。
当读取多个字节时
修改代码:
void loop() {
  if (udp.parsePacket()) {
    char* val = new char[256];  // 使用 new 动态分配一个数组,假设你想读取最多 255 个字节,为 null 终止符留下空间
    int bytesRead = udp.read(val, 255);  // 读取最多 255 个字节
    val[bytesRead] = ' ';  // 加上 null 终止符
    // 处理并打印接收到的数据
    Serial.println(val);
    // 将接收到的数据发送回客户端
    udp.beginPacket(udp.remoteIP(), udp.remotePort());
    udp.write(val, bytesRead);
    udp.endPacket();
    delete[] val;  // 使用 delete[] 释放动态分配的数组内存
  }
}
修改后的代码中:
- 使用 new char[256]; 动态分配了一个数组来存储接收到的数据。
- udp.read(val, 255); 读取最多- 255 个字节,确保有空间容纳 null 终止符。
- 添加 val[bytesRead] = ' '; 来添加 null 终止符,使其适用于使用Serial.println 打印。
- 使用 delete[] val; 来释放使用new 分配的数组内存。
请注意,在使用 
常用API
以下是Arduino ESP32中涉及UDP通信的一些关键API的总结:
- 
WiFiUDP类: - WiFiUDP 类用于处理UDP通信。
- 成员函数:
- begin(port) : 初始化UDP并指定监听的端口号。
- beginPacket(ip, port) : 打包一个UDP数据包准备将数据发送到指定的IP地址和端口。
- endPacket() : 结束UDP数据包,发送数据到指定的IP地址和端口。
- write(data, size) : 将指定大小的数据写入UDP数据包。
- parsePacket() : 检查是否有新的UDP数据包到达。
- read() : 读取一个字节的数据。
- remoteIP() : 获取远程设备的IP地址。
- remotePort() : 获取远程设备的端口号。
 
 
- 
WiFi类: - WiFi 类用于处理ESP32的WiFi连接。
- 成员函数:
- softAP(ssid, password) : 将ESP32设置为SoftAP模式,并指定SSID和密码。
- softAPIP() : 获取分配给SoftAP的IP地址。
 
 
- 
Serial类(用于调试): - Serial 类用于在串口监视器上打印调试信息。
- 成员函数:
- begin(baud) : 初始化串口通信,并指定波特率。
- println(data) : 将数据打印到串口监视器并换行。
 
 
这些API提供了在ESP32上设置和使用UDP通信所需的基本功能。通过这些函数,可以初始化UDP,发送和接收数据,处理连接,以及在串口监视器上输出调试信息。更详细的介绍请查看Arduino-ESP32手册
完整程序和测试效果
#include <Arduino.h>
#include <WiFi.h>
WiFiUDP udp;  //声明UDP对象,服务端开启,监听
void setup() {
  WiFi.softAP("ESP32_UDP","987654321");
  udp.begin(1133);
  Serial.begin(115200);
  //串口打印AP-IP
  Serial.println(WiFi.softAPIP());
}
void loop() {
  //接收发送过来的UDP数据
  if(udp.parsePacket()){
    char val=udp.read(); //读取一个字节
    Serial.println(val);
    
	//读取多个字节
    // char* val;
    // udp.read(val,255);
    // Serial.println(val);
    
    //将接收到的数据处理在回发
    udp.beginPacket(udp.remoteIP(),udp.remotePort());
    udp.println(val);
    udp.endPacket();
  }
}
串口发送且得到返回
 