ESP32UDP 通信

本实验使用 ESP32 通过 AP 和 STA 两种方法实现 UDP 通信。 这个实验的代码为工程“4_6_wifi_UDP”目录。

4.6.1. 实验内容

(1) 在 AP 模式下,手机和 ESP32 开发板之间实现 UDP 通信。
(2) 在 STA 模式下,电脑和 ESP32 开发板之间实现 UDP 通信。

4.6.2. UDP 通信简介

UDP 是 User Datagram Protocol 的简称,中文名是用户数据报协议,是 OS(I Open System Interconnection,
开放式系统互联)参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768 是 UDP 的正式规范。UDP 在 IP 报文的协议号是 17。
UDP 协议全称是用户数据报协议,在网络中它与 TCP 协议一样用于处理数据包,是一种无连接的协 议。在 OSI 模型中,在第四层——传输层,处于 IP 协议的上一层。UDP 有不提供数据包分组、组装和不 能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP 用来 支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的 网络应用都需要使用 UDP 协议。UDP 协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些 类似协议所掩盖,但是即使是在今天 UDP 仍然不失为一项非常实用和可行的网络传输层协议。
与所熟知的 TCP(传输控制协议)协议一样,UDP 协议直接位于 IP(网际协议)协议的顶层。根据OSI(开放系统互连)参考模型,UDP 和 TCP 都属于传输层协议。UDP 协议的主要作用是将网络数据流量 压缩成数据包的形式。一个典型的数据包就是一个二进制数据的传输单位。每一个数据包的前 8 个字节用 来包含报头信息,剩余字节则用来包含具体的传输数据。
UDP 是 OSI 参考模型中一种无连接的传输层协议,它主要用于不要求分组顺序到达的传输中,分组传 输顺序的检查与排序由应用层完成,提供面向事务的简单不可靠信息传送服务。UDP 协议基本上是 IP 协议 与上层协议的接口。UDP 协议适用端口分别运行在同一台设备上的多个应用程序。
UDP 提供了无连接通信,且不对传送数据包进行可靠性保证,适合于一次传输少量数据,UDP 传输的可靠 性由应用层负责。
下图是 UDP 通信的框图,从图中可以看到,服务器和客户端区别在于是否有绑定 bind 这个过程,我们在编 程中按 UDP 服务器做:
在这里插入图片描述

4.6.3. ESP32 函数介绍

这个实验也是使用到的标准 socket 接口,函数的参数和 window 上一致,如下:
 创建 UDP socket 套接字,用 socket 函数。
 设置 socket 的属性,用 setsockopt()函数,(可选)
 绑定包含 IP 信息,地址信息的(IPv4)结构体。用 bind()函数
 循环接收消息,用 recvfrom()函数
 关闭 socket 套接字

4.6.4. 代码讲解

使用 vs code 展开本实验的工程目录,如下图:
在这里插入图片描述

我们的这个实验,components 文件夹下的 LCD 是显示屏的驱动代码,在 3.4 章有比较详情的讲解,文 件夹 wifi 是如何启动 AP 或者 STA 连接,另外的 wifi 就是本章要讲的 UDP 实现,程序的入口依然是在 main 下的 app_main.c 文件里。
下面按照程序启动的流程讲解。

(1) 程序启动
在 app_main 主函数里,通过宏 WIFI_AP 决定是启动 WiFi 的 AP 还是 STA 模式。

//用户函数入口,相当于 main 函数 void app_main()
{
......
#ifdef WIFI_AP wifi_init_ap();//启动 WIFI 的 AP
#else
wifi_init_sta();//启动 WIFI 的 STA
#endif
}

关于 AP 和 STA 模式的使用,我们这里不再讲解,在头文件 user_wifi.h 里,有以下的宏定义,在做实 验的时候一定要注意,需要根据实际情况去修改。

//定义就是 AP 模式,如果不定义就是 STA 模式
#define WIFI_AP

//是否使用静态 IP,如果不定义就是 DHCP 模式
//#define ESP32_STATIC_IP

#ifdef ESP32_STATIC_IP
//IP
#define DEVICE_IP "192.168.10.1"
//网关
#define DEVICE_GW "192.168.10.1"

(2) 启动 UDP 任务
在源文件 user_wifi.c 里,wifi 的事件回调函数里等待 wifi 的网络创建成功,接着使用函数 create_udp() 创建 UDP 任务,关键代码如下:

static esp_err_t event_handler(void *ctx, system_event_t *event)
{
......
case SYSTEM_EVENT_AP_STACONNECTED:
printf("station:"MACSTR" join, AID=%d.\r\n", MAC2STR(event->event_info.sta_connected.mac), event->event_info.sta_connected.aid);

//有客户端连接,启动服务器 create_udp();
break;
......
case SYSTEM_EVENT_STA_GOT_IP:
printf("\r\nip:%s.\r\n",ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); printf("gw:%s.\r\n",ip4addr_ntoa(&event->event_info.got_ip.ip_info.gw)); printf("netmask:%s.\r\n",ip4addr_ntoa(&event->event_info.got_ip.ip_info.netmask));

s_ip_addr = event->event_info.got_ip.ip_info.ip;//保存 IP s_gw_addr = event->event_info.got_ip.ip_info.gw;//保存网关
s_netmask_addr = event->event_info.got_ip.ip_info.netmask;//保存掩码 lcd_display(1);

//连接上有客户端连接,启动服务器 create_udp();
break;
......
}

void create_udp()
{
xTaskCreate(&udp_ini_client,  "udp_ini_client",  4096,  NULL,  5, NULL);

(3) 创建 UDP 连接
通过 3 步实现的 UDP 连接:新建 socket、绑定 bind 和接收任务。注意一下,远程参数的 IP 默认使用 的是广播地址,当 ESP32 开发板收到第一帧数据后设置为实际的地址。

//创建 UDP 连接
void udp_ini_client(void *pvParameters){
......

//第一步:创建 socket
udp_socket = socket(AF_INET,SOCK_DGRAM,0);
......
//远端参数设置
dest_addr.sin_addr.s_addr = inet_addr("255.255.255.255"); //目标地址默认使用广播 dest_addr.sin_family  = AF_INET;
dest_addr.sin_port  = htons(UDP_PORT);//目标端口
printf("Socket  created,  sending  to  255.255.255.255:%d", UDP_PORT);
......

//第二步:绑定 bind
res = bind(udp_socket,(struct sockaddr *)&Loacl_addr,sizeof(Loacl_addr));
......

//第三步:创建接收任务函数 xTaskCreate(&udp_recv_data,"udp_recv_data",2048*2,NULL,10,&xUDPRecvTask);

//删除当前任务 vTaskDelete(NULL);
}

(4) 启动接收的任务
UDP 接收数据任务里调用了 recvfrom()接收数据,然后收到的数据通过 printf 输出到串口后,再使用函 数 udp_send_data()返回到发送方。

//UDP 接收任务
void  udp_recv_data(void  *pvParameters){ socklen_t socklen = sizeof(dest_addr); uint8_t rx_buffer[1024] = {0}; printf("create  udp recv\n");

//测试 UDP 是否 OK
//可以删除
udp_send_data("udp  test",  strlen("udp test"));

while (1)
{
//接收数据
int  len  =  recvfrom(udp_socket,  rx_buffer,  sizeof(rx_buffer)  - 1, 0,	(struct sockaddr  *)&dest_addr, &dest_addr_socklen);
if(len  > 0){
rx_buffer[len]  =  0; //未尾增加"\0"
printf("Received  %d  bytes:  %s.\n",  len, rx_buffer);

//接收到的数据在 rx_buffer 里,长度为 len 字节
//可以增加用户代码

//在这个实验里,返回数据给发送端 udp_send_data((char*)rx_buffer, len);
}
}
}

//UDP 发数据发送函数
void udp_send_data(char* data, int len){ if(udp_socket>0){
int  err  =  sendto(udp_socket,  data,  len,  0,  (struct  sockaddr  *)&dest_addr, des
t_addr_socklen);

if  (err  <  0) {
printf(  "Error  occurred  during  sending:  errno  %d", errno);
}
}

4.6.5. 实验过程

下面分别通过 ESP32 的 AP 模式和 STA 模式演示程序。

4.6.5.1. AP 模式
通过 wifi 的 AP 模式实现 TCP 服务器,首先要按下图修改 user_wifi.h,修改之后就可以按之前的方法编 绎和下载了。
在这里插入图片描述

配置下载串口、波特率、编绎和程序下载的详细过程请往回看 3.1.4,在这个实验里都是一笔带过。 (1) 把开发板通过 USB 线接到电脑上,通过设备管理器查看生成的串口。开发板在我们演示电脑上生
成的是 COM3。
(2) 在 menuconfig 菜单里配置下载程序串口。提供的例程配置的串口是 COM3,波特率为 921600。
(3) 通过 make all 编绎工程。
(4) 当编绎通过之后,使用命令 make flash 把程序下载到开发板上。或者参考 2.3.2 节,使用工具 下载。
(5) 使用串口工具打开开发板生成的串口,默认的波特率是 115200。 串口工具在目录:.\开发软件\串口工具-sscom32.rar。
(6) 按下开发板的复位键,让程序运行起来,显示屏显示

生成的 AP 是:taobao.com,密码是:12345678,开发板的 IP(也是 UDP 服务器的 IP):192.168.10.1, UDP 端口号:10000。

(7) 在手机上安装网络调试助手,软件位于目录:\开发软件\网络调试助手(android 版本).apk。
(8) 打开手机的 wifi,并连接上名称为“taobao.com”,密码是“12345678”,如果有修改请 按修改后的去连接。
(9) 打开手机上的网络调助手,配置和验证 UDP 通信。
在这里插入图片描述

4.6.5.2. STA 模式
通过 wifi 的 STA 模式实现 UDP 通信,首先要按下图修改 user_wifi.h,修改之后就可以按之前的方法编 绎和下载了。
在这里插入图片描述

配置下载串口、波特率、编绎和程序下载的详细过程请往回看 3.1.4,在这个实验里都是一笔带过。 (1) 把开发板通过 USB 线接到电脑上,通过设备管理器查看生成的串口。开发板在我们演示电脑上生
成的是 COM3。
(2) 在 menuconfig 菜单里配置下载程序串口。提供的例程配置的串口是 COM3,波特率为 921600。
(3) 通过 make all 编绎工程。
(4) 当编绎通过之后,使用命令 make flash 把程序下载到开发板上。或者参考 2.3.2 节,使用工具 下载。
(5) 使用串口工具打开开发板生成的串口,默认的波特率是 115200。
串口工具在目录:.\开发软件\串口工具-sscom32.rar。
(6) 打开按下开发板的复位键,让程序运行起来,当 ESP32 连接上我们设置的 AP 后,显示屏显示连接的 wifi 名称是:TP_LINK,密码是:12345678,UDP 的 IP 是(也是 ESP32 开发 板分配的 IP):192.168.1.104,端口是:10000。

(7) 要求实验的电脑和 ESP32 是连接在同一个路中器下,通过电脑可以 ping 通 ESP32 开发板。
在这里插入图片描述

(8) 在电脑上打开网络调试助手,软件位于目录:\开发软件\网络调试助手.rar,解压后打开设置并 如下图实验:
在这里插入图片描述

(9) 实验过程中,注意查看第 5 步的串口输出。

最后推荐一款开发套件,可以手淘扫码查看。
在这里插入图片描述

  • 2
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bytechip

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值