ESP32TCP-SERVER 通信

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

4.4.1. 实验内容

(1) 在 AP 模式下,手机是 TCP 客户端,ESP32 开发板是 TCP 服务器实现通信。
(2) 在 STA 模式下,电脑是 TCP 客户端,ESP32 开发板是 TCP 服务器实现通信。

4.4.2. TCP 通信简介

TCP 即传输控制协议,是一种面向连接的、可靠的、基于字节流的通信协议。简单来说 TCP 就是有确 认机制的 UDP 协议,每发出一个数据包都要求确认,如果有一个数据包丢失,就收不到确认,发送方就必 须重发这个数据包。为了保证传输的可靠性,TCP 协议在 UDP 基础之上建立了三次对话的确认机制,即在 正式收发数据前,必须和对方建立可靠的连接。TCP 数据包和 UDP 一样,都是由首部和数据两部分组成, 唯一不同的是,TCP 数据包没有长度限制,理论上可以无限长,但是为了保证网络的效率,通常 TCP 数据 包的长度不会超过 IP 数据包的长度,以确保单个 TCP 数据包不必再分割。
TCP 通信分为服务器和客户端。服务器端先初始化 Socket,然后与端口绑定(bind),对端口进行监听 (listen),调用 accept 阻塞,等待客户端连接。在这时如果有个客户端初始化一个 Socket,然后连接服务器 (connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收 请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
下图是 TCP 通信的框图,在这个实验里我们通过 ESP32 实现框图右边的 TCP 服务端程序:
在这里插入图片描述

4.4.3. ESP32 函数介绍

ESP32 使用的是 LwIP,LwIP 是特别适用于嵌入式设备的小型开源 TCP/IP 协议栈,对内存资源占用很 小。我们的这个例程是直接是标准 socket 接口(内部是 LwIP 封装的),没有用 LwIP 的,关于 LwIP 的 接口讲解在 Websocket 中讲解,用法都是一样,知道流程后,API 调用即可,处理好异常。
使用到的标准 socket 接口,函数的参数和 window 上一致,如下:
 新建 socket 函数:socket();
 关闭 socket 函数:close();
 获取 socket 错误代码:getsocketopt();
 接收数据函数:recv();
 发送数据函数:send();
 绑定函数:bing();
 监听函数:listen();
 获取连接函数:accept();

4.4.4. 代码讲解

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

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

(1) 程序启动
在 app_main 主函数里,通过宏 WIFI_AP 决定是启动 WiFi 的 AP 还是 STA 模式,然后创建了一个 TCP 的连接任务。

//用户函数入口,相当于 main 函数 void app_main()
{
//nvs 初始化
esp_err_t  ret  = nvs_flash_init();
if  (ret  ==  ESP_ERR_NVS_NO_FREE_PAGES  ||  ret  ==  ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase()); ret  = nvs_flash_init();
} ESP_ERROR_CHECK(ret);

//显示屏初始化以及显示相关的提示 Lcd_Init();
lcd_display(0);

#ifdef WIFI_AP
wifi_init_ap();//启动 WIFI 的 AP
 
#else

#endif
 

wifi_init_sta();//启动 WIFI 的 STA
 

//新建一个 tcp 连接任务
xTaskCreate(&tcp_server_connect,  "tcp_server_connect",  4096,  NULL,  5, NULL);
}

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

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

//是否使用静态 IP,如果不定义就是 DHCP 模式
//#define ESP32_STATIC_IP
#ifdef ESP32_STATIC_IP
//AP 模式 IP
#define  DEVICE_IP "192.168.10.1"
//AP 模式网关
#define  DEVICE_GW "192.168.10.1"
//AP 模式掩码
#define  DEVICE_NETMASK "255.255.255.0"
#endif

#ifdef WIFI_AP
#define	DEFAULT_SSID  "sz-yy.taobao.com"	//创建的 WIFI 名称
#define	DEFAULT_PWD  "12345678"	//创建的 wifi 对应的密码
#else
#define	
DEFAULT_SSID "TP_LINK"	
//STA 模式要接入 WIFI 名称
#define
#endif	DEFAULT_PWD "12345678"	//要接入 wifi 对应的密码

(2) 启动 TCP 服务器任务
在源文件 user_wifi.c 里,wifi 的事件回调函数里等待 wifi 的网络创建成功,通过设置事件通知任务创 建 TCP 服务器,关键代码如下:

static esp_err_t event_handler(void *ctx, system_event_t *event)
{
switch (event->event_id)
{
///略/
case SYSTEM_EVENT_AP_STACONNECTED:
///略/
//有客户端连接,启动 TCP 服务器 xEventGroupSetBits(tcp_event_group, WIFI_CONNECTED_BIT); break;

///略/ case SYSTEM_EVENT_STA_GOT_IP:
///略/
//连接上有客户端连接,启动 TCP 服务器 xEventGroupSetBits(tcp_event_group, WIFI_CONNECTED_BIT); break;
///略/ default:
break;
}
return ESP_OK;
}

TCP 连接任务里,分三步实现 TCP 服务器,首先是等待 wifi 网络的连接,接着创建 TCP 服务器,最后 创建接收数据任务。

// 任务:建立 TCP 连接并从 TCP 接收数据
void tcp_server_connect(void *pvParameters)
{
while (1)
{
//第一步:等待 WIFI 网络连接,死等
xEventGroupWaitBits(tcp_event_group, WIFI_CONNECTED_BIT, false, true, portMAX_DELAY);
/略//
//第二步:建立 server
int socket_ret = create_tcp_server(true);
if (socket_ret == ESP_FAIL)
{
/略//
}
else
{
//建立成功
ESP_LOGI(TAG, "create tcp socket succeed...");
//第三步:建立 tcp 接收数据任务
if (pdPASS != xTaskCreate(&server_recv_data, "server_recv_data", 4096, NULL, 4,
&tx_rx_task))
/略//
}

/略//
}

vTaskDelete(NULL);
}

(3) 创建 TCP 服务器
通过 4 步实现的 TCP 服务器: 新建 socket、 bind、 listen 和 accept, 最后得到了通信的 socket: connect_socket,用于接收/发送数据。

esp_err_t create_tcp_server(bool isCreatServer)
{
//首次建立 server if (isCreatServer)
{
ESP_LOGI(TAG, "server socket....,port=%d", TCP_SERVER_PORT);
//第一步:新建 socket
server_socket = socket(AF_INET, SOCK_STREAM, 0);
///略
//第二步:bind:地址的绑定
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
///略
}

//第三步:listen
if (listen(server_socket, 5) < 0)
///略

//第四步:accept 等待 TCP client 连接
connect_socket = accept(server_socket, (struct sockaddr *)&client_addr, &socklen);
///略
}

(4) 启动接收的任务
TCP 接收数据任务里调用了 recv()接收数据,然后收到的数据通过 LOG 输出到串口后,再原路返回到 发送方。

//TCP 接收数据任务
void server_recv_data(void *pvParameters)
{
int len = 0;	//长度 char databuff[1024]; //缓存 while (1)
{
//清空缓存
memset(databuff, 0x00, sizeof(databuff));
//读取接收数据
len = recv(connect_socket, databuff, sizeof(databuff), 0); g_rxtx_need_restart = false;
if (len > 0)
{
//打印接收到的数据
ESP_LOGI(TAG, "recvData: %s", databuff);
//接收数据回发
send(connect_socket, databuff, strlen(databuff), 0);
}
else
{
//服务器异常处理
}
}
close_socket();
//标记重连 g_rxtx_need_restart = true; vTaskDelete(NULL);
}

4.4.5. 实验过程

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

4.4.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) 打开按下开发板的复位键,让程序运行起来,显示屏显示如下:

(7) 在手机上安装网络调试助手,软件位于目录:\开发软件\网络调试助手(android 版本).apk。
(8) 打开手机的 wifi,并连接上名称为“sz-yy.taobao.com”,密码是“12345678”,如果有修改请 按修改后的去连接。
(9) 打开手机上的网络调助手,配置和验证 TCP 服务器。

在这里插入图片描述

(10) 实验过程中,注意查看第 5 步的串口输出。
(11) 如果有无线功能的笔记本,也可以做这个实验。

4.4.5.2. STA 模式
通过 wifi 的 STA 模式实现 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) 打开按下开发板的复位键,让程序运行起来,当 ESP32 连接上我们设置的 AP 后,显示屏显示连接的 wifi 名称是:TP_LINK,密码是:12345678,TCP 服务器的 IP 是(也是 ESP32
开发板分配的 IP):192.168.1.102,端口是:8080。

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

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

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

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

  • 1
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ESP32可以通过TCP/IP协议进行通信。以下是使用ESP-IDF框架进行TCP通信的基本步骤: 1. 创建TCP服务器或客户端 使用`tcpip_adapter_init()`初始化TCP/IP协议栈,然后使用`tcpip_adapter_dhcpc_start()`启动DHCP客户端以获取IP地址。然后,使用`tcp_new()`函数创建一个TCP服务器或客户端。服务器使用`tcp_bind()`绑定IP地址和端口号,客户端使用`tcp_connect()`连接服务器。 2. 监听和接受连接 对于服务器,使用`tcp_listen()`开始监听连接请求,然后使用`tcp_accept()`接受连接请求并创建新的TCP连接。服务器可以使用`tcp_write()`和`tcp_read()`函数发送和接收数据。对于客户端,可以使用`tcp_write()`和`tcp_read()`函数发送和接收数据。 3. 关闭连接 使用`tcp_close()`函数关闭TCP连接。 以下是一个简单的ESP32 TCP服务器示例代码: ```c #include <stdio.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_system.h" #include "esp_wifi.h" #include "esp_event_loop.h" #include "esp_log.h" #include "nvs_flash.h" #include "lwip/err.h" #include "lwip/sys.h" #include "lwip/api.h" #define PORT 80 static const char *TAG = "tcp_server"; void tcp_server_task(void *pvParameters) { struct netconn *conn, *newconn; err_t err; char buffer[1024]; int len; conn = netconn_new(NETCONN_TCP); netconn_bind(conn, NULL, PORT); netconn_listen(conn); do { err = netconn_accept(conn, &newconn); if (err == ERR_OK) { ESP_LOGI(TAG, "New client connected"); do { len = netconn_recv(newconn, buffer, sizeof(buffer), NETCONN_COPY); if (len > 0) { buffer[len] = 0; ESP_LOGI(TAG, "Received data: %s", buffer); netconn_write(newconn, buffer, len, NETCONN_COPY); } } while (len > 0); netconn_close(newconn); netconn_delete(newconn); ESP_LOGI(TAG, "Client disconnected"); } } while (err == ERR_OK); netconn_close(conn); netconn_delete(conn); } void app_main() { nvs_flash_init(); tcpip_adapter_init(); tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA); xTaskCreate(tcp_server_task, "tcp_server", 2048, NULL, 5, NULL); } ``` 该示例代码创建一个TCP服务器,监听端口80。当有新的客户端连接到服务器时,服务器将接收客户端发送的数据,并将数据发送回客户端。在ESP-IDF中,可以使用`netconn`结构体和`lwip/api.h`头文件来进行TCP通信

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

bytechip

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

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

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

打赏作者

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

抵扣说明:

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

余额充值