Advertisement

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报文的结束。

全部评论 (0)

还没有任何评论哟~