ESP32网络开发实例-UDP数据发送与接收
本文介绍了如何在Arduino开发环境中使用UDP协议进行数据发送与接收。UDP是一种跨互联网的通信协议,支持快速数据传输但可靠性较差。与TCP相比,UDP无需握手过程,也不检查数据是否正确到达。文章详细讲解了如何准备开发环境,包括软件(Arduino IDE、WiFi和WiFiUDP库)和硬件(ESP32开发板、5mm LED、330欧姆电阻等)。代码部分展示了如何设置串口、连接WiFi、处理WiFi事件、接收和发送UDP数据。通过UDP协议,开发者可以实现高效的实时数据传输。
UDP数据发送与接收
文章目录
- UDP数据发送与接收
-
- 1、UDP简单介绍
- 2、软件准备
- 3、硬件准备
- 4、代码实现
本文将对Arduino开发环境中ESP32通过UDP协议进行数据发送与接收过程进行深入讲解。
1、UDP简单介绍
用户数据报协议(UDP)是一种广泛应用于互联网的通信协议,主要用于实现对实时性要求高的传输,如视频流传输或 DNS查询。其特点在于无需在数据传输前正式建立连接,从而显著提升了通信速度。这使得数据传输变得极为迅速。
与所有网络协议类似,UDP 作为一种标准化的技术,主要用于在两台计算机之间传输数据。与之相比,UDP 通过一种直接的方式完成数据传输过程:它直接向目标计算机发送数据包(数据传输的单位),无需建立连接,也不指示数据包的顺序,也不进行数据完整性检查。(UDP 数据包被称为“数据报”)
UDP相较于主流的传输协议TCP而言,运行速度更快捷,但其可靠性相对较低。在TCP通信过程中,两台计算机首先通过称为‘握手过程’的自动机制建立连接。仅在握手过程结束后,一台计算机才会向另一台计算机实际发送数据包。
UDP 通信无需经过该过程。另一方面,一台计算机可以直接启动向另一台计算机发送数据:

此外,TCP 通信指示负责指示接收数据包顺序并确认其按预期到达。当数据包未按预期到达时,如中间网络拥塞所导致,TCP 要求重新发送。UDP 通信不包含此类功能。
这些差异带来了显著的优势。由于 UDP 不必进行“握手”过程或确认数据是否正确到达,因此其传输速度较 TCP 更为高效。
然而,这种传输速度会带来一些问题。当 UDP 数据报在传输过程中丢失时,它将无法重新发送。由此可见,依赖 UDP 的应用程序必须能够接受错误、丢失和重复的情况。
2、软件准备
- Arduino IDE
在前面的文章中,如何搭建ESP32的Arduino IDE开环境,主参考:
本文将详细介绍ESP32与Arduino开发实例,包括Arduino开发环境的搭建过程。通过本篇文章,读者可以掌握Arduino开发所需的必要技术与操作方法。
本文将详细介绍ESP32与Arduino开发实例,包括Arduino开发环境的搭建过程。通过本篇文章,读者可以掌握Arduino开发所需的必要技术与操作方法。
3、硬件准备
- ESP32开发板
- 5mm LED
- 330欧姆电阻
- 面包板
- 杜邦线(连接线)
4、代码实现
#include <Arduino.h>
#include <WiFi.h>
#define SSID "*********"
#define SSID_PWD "********"
#define UDP_PORT 8081
#define UDP_BUFFER_SIZE 256
#define UDP_REMOTE_IP "192.168.2.78"
#define UDP_REMOTE_PORT 5000
void onWifiEvent(WiFiEvent_t event);
WiFiUDP udp;
bool is_wifi_connect = false;
uint8_t udp_buffer[UDP_BUFFER_SIZE];
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
// 设置工作模式
WiFi.mode(WIFI_STA);
// 注册WiFi事件回调函数
WiFi.onEvent(onWifiEvent);
// 连接WiFi
WiFi.begin(SSID,SSID_PWD);
//WiFi.setSleep(false);
// 等待连接
Serial.println("start connect wifi....");
while(WiFi.status() != WL_CONNECTED){
Serial.print(".");
delay(500);
}
}
void loop() {
// put your main code here, to run repeatedly:
if(is_wifi_connect){
// 解析报文
udp.parsePacket();
memset(udp_buffer,0,UDP_BUFFER_SIZE);
uint32_t len = udp.readBytes(udp_buffer,UDP_BUFFER_SIZE);
if(len > 0){
Serial.print("recv:");
Serial.println((char*)udp_buffer);
//udp.write(udp_buffer,len);
udp.beginPacket(UDP_REMOTE_IP, UDP_REMOTE_PORT);
udp.write(udp_buffer, len);
udp.endPacket();
udp.flush();
}
}
}
void onWifiEvent(WiFiEvent_t event){
switch(event) {
case SYSTEM_EVENT_STA_GOT_IP:
//When connected set
Serial.print("WiFi connected! IP address: ");
Serial.println(WiFi.localIP());
// 初始化
udp.begin(UDP_PORT);
is_wifi_connect = true;
Serial.print("udp begin at:");
Serial.println(UDP_PORT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
is_wifi_connect = false;
break;
}
}
代码如何工作?
1)导入依赖库头文件
#include <Arduino.h>
#include <WiFi.h>
2)定义WiFi连接信息
#define SSID "*********"
#define SSID_PWD "********"
3)定义UDP连接信息
#define UDP_PORT 8081
#define UDP_BUFFER_SIZE 256
#define UDP_REMOTE_IP "192.168.2.78"
#define UDP_REMOTE_PORT 5000
第4步,进行WiFi事件响应的函数定义,具体链接为:函数
void onWifiEvent(WiFiEvent_t event);
5)创建UDP
WiFiUDP udp;
bool is_wifi_connect = false;
uint8_t udp_buffer[UDP_BUFFER_SIZE];
6)在setup函数
初始化串口
Serial.begin(115200);
设置WiFi工作状态,启动连接
// 设置工作模式
WiFi.mode(WIFI_STA);
// 注册WiFi事件回调函数
WiFi.onEvent(onWifiEvent);
// 连接WiFi
WiFi.begin(SSID,SSID_PWD);
等待连接完成
// 等待连接
Serial.println("start connect wifi....");
while(WiFi.status() != WL_CONNECTED){
Serial.print(".");
delay(500);
}
7)WiFi事件回调函数实现
void onWifiEvent(WiFiEvent_t event){
switch(event) {
case SYSTEM_EVENT_STA_GOT_IP:
//When connected set
Serial.print("WiFi connected! IP address: ");
Serial.println(WiFi.localIP());
// 初始化
udp.begin(UDP_PORT);
is_wifi_connect = true;
Serial.print("udp begin at:");
Serial.println(UDP_PORT);
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
is_wifi_connect = false;
break;
}
}
在这里,我们只监听两个事件:
当接收到SYSTEM_EVENT_STA_GOT_IP事件时,启动UDP连接
udp.begin(UDP_PORT);
当前接收到SYSTEM_EVENT_STA_DISCONNECTED事件时,更新is_wifi_connect
8)在loop函数中
解析UDP报文
// 解析报文
udp.parsePacket();
接收数据
uint32_t len = udp.readBytes(udp_buffer,UDP_BUFFER_SIZE);
readBytes函数用于接收数据并返回数据长度。当数据长度大于0时,表示数据可用。
处理并发送数据
udp.beginPacket(UDP_REMOTE_IP, UDP_REMOTE_PORT);
udp.write(udp_buffer, len);
udp.endPacket();
udp.flush();
在发送数据之前,首先通过调用beginPacket()函数发送UDP报文。随后,通过调用write()函数发送数据内容。最后,通过调用endPacket()函数来完成UDP报文的结束。
