乐鑫Esp32学习之旅⑨ esp32上实现本地 TCP 客户端和服务端角色,可断线重连原路返回数据。(附带Demo)
Posted 半颗心脏
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了乐鑫Esp32学习之旅⑨ esp32上实现本地 TCP 客户端和服务端角色,可断线重连原路返回数据。(附带Demo)相关的知识,希望对你有一定的参考价值。
- 本系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途。如有不对之处,请留言,本人及时更改。
1、 爬坑学习新旅程,虚拟机搭建esp32开发环境,打印 “Hellow World”。
2、 巧用eclipes编辑器,官方教程在在Windows下搭建esp32开发环境,打印 “Hellow World”。
3、 认识基本esp32的GPIO接口,开始点亮您的第一盏 LED和中断回调实现按键功能 。
4、体会esp32的强大的定时器功能, 实现定时2s闪烁一盏LED灯。
5、接触实践esp32的pwm宽度脉冲功能, 实现呼吸效果闪烁一盏LED灯。
6、smartConfig和微信airKiss在esp32的实现,一键配网轻松快捷连接路由器。
7、利用GPIO中断做一个按键的短按和长按的回调事件,再也无须担心触发源。
8、esp32上实现本地 UDP 客户端和服务端角色,在局域网内实现通讯。
9、esp32上实现本地 TCP 客户端和服务端角色,可断线重连原路返回数据。
10、乐鑫esp32 SDK编程利用rmt驱动ws2812七彩灯,实现彩虹渐变效果。
11、入门 乐鑫esp-adf 音频框架开发,esp32造一个蓝牙耳机,实现切换歌曲,获取歌曲信息等功能。
12、开源一个微信公众号airkiss配网esp32以及局域网发现功能的工程,分享一个airkiss配网小工具。
13、esp32 内置 dns 服务器,无需外网访问域名返回指定网页。
14、esp32 sdk编程实现门户强制认证,连接esp32热点之后,自动强制弹出指定的登录界面。
15、认识本地离线语音唤醒识别框架 esp-skainet ,实现较低成本的硬件语音本地识别控制。
16、学习本地语音唤醒离线识别框架 esp-skainet ,如何修改唤醒词? 如何自定义命令词?如何做意图动作?
17、全网首发,乐鑫esp32 sdk直连京东微联·小京鱼 · IoT开放平台,实现叮咚音响语音智能控制。
18、入门京东微联·小京鱼的控制面板H5开发,读懂vue语法,做自己的控制页面。
19、重磅开源,如何在微信小程序上ble蓝牙配网esp32,blufi的那些事!
20、一篇好文,开发过程中编译esp32固件太大,无法正常启动?教你如何自定义分区表partitions.csv。
文章目录
本篇博文目录:
文章目录
一. 前言;
-
2018年的高考分数线出来了,广东省的本科的理科分数线 375分,貌似比当年2014年高考低好多啊。。哈哈!
-
回归正题,
TCP
基本协议,我就不多说了,可以看看我的前面的8266
系列的,本博文通讯框架基于lwip
,主要修改实现以下功能: -
TCP
服务端时候,客户端连接进来的数据原路返回,而且断开连接之后,允许重新连接。 -
TCP
客户端时候,设置每三秒向服务器发送数据!
二. 服务端;
- 左边是
visual studio code
编译器的终端显示esp32
显示打印的数据,右边是手机通讯调试助手。
2.1 实现的过程:
- 首先根据配置信息来开启热点模式,等待设备的连接。
- 设备连接成功后,开启
TCP server
服务器端,然后通讯! - 注意的是:当前的网关的
IP
地址就是服务器地址,默认是192.168.4.1
这个是乐鑫在出厂时候写死的!知道就好!
2.2 核心的代码:
- ①:创建热点(和上篇的
UDP
一样):
void wifi_init_softap()
tcp_event_group = xEventGroupCreate();
tcpip_adapter_init();
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
wifi_config_t wifi_config =
.ap =
.ssid = SOFT_AP_SSID, //设置名字
.ssid_len = 0,
.max_connection = SOFT_AP_MAX_CONNECT, //最大连接数目
.password = SOFT_AP_PAS, //密码
.authmode = WIFI_AUTH_WPA_WPA2_PSK,//加密方式
;
if (strlen(EXAMPLE_DEFAULT_PWD) == 0)//如果密码为空,则设置开放性wifi热点
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "SoftAP set finish:%s pas:%s \\n",EXAMPLE_DEFAULT_SSID, EXAMPLE_DEFAULT_PWD);
- ②:创建
TCP
服务器,等待客户端连接:
//形参的含义:true为创建服务器并且等待连接,false仅仅只是等待连接;返回值是是否成功接收到一个设备的连接
esp_err_t create_tcp_server(bool isCreatServer)
if (isCreatServer)
ESP_LOGI(TAG, "server socket....,port=%d\\n", TCP_PORT);
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket < 0)
show_socket_error_reason("create_server", server_socket);
return ESP_FAIL;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(TCP_PORT);//指定的端口号
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//开始创建
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
show_socket_error_reason("bind_server", server_socket);
close(server_socket);
return ESP_FAIL;
//监听指定的端口
if (listen(server_socket, 5) < 0)
show_socket_error_reason("listen_server", server_socket);
close(server_socket);
return ESP_FAIL;
connect_socket = accept(server_socket, (struct sockaddr *)&client_addr, &socklen);
//判断是否连接成功
if (connect_socket < 0)
show_socket_error_reason("accept_server", connect_socket);
close(server_socket);
return ESP_FAIL;
/*connection established,now can send/recv*/
ESP_LOGI(TAG, "tcp connection established!");
return ESP_OK;
- ③:接收数据:
void recv_data(void *pvParameters)
int len = 0;
char databuff[1024];
while (1)
while (1)
//每次接收都要清空接收数组
memset(databuff, 0x00, sizeof(databuff));
len = recv(connect_socket, databuff, sizeof(databuff), 0);
//打印接收到的数组
ESP_LOGI(TAG, "recvData: %s\\n", databuff);
//原路返回,不指定某个客户端
send(connect_socket, databuff , sizeof(databuff), 0);
if (len > 0)
g_total_data += len;
g_rxtx_need_restart = false;
else
show_socket_error_reason("recv_data", connect_socket);
g_rxtx_need_restart = true;
g_rxtx_need_restart = true;
vTaskDelete(NULL);
2.3 注意问题:
- 虽然乐鑫也提供了
TCP
的例程,但是发现是当客户端断开连接之后再次连接时候,客户端提示已经连接成功,但发现服务器并没有去监听这个设备的信息,原因在于没有去等待监听,还是要通过listen()
和accept()
方法来获取一个远程的设备地址。
三. TCP Client
客户端;
-
下图可以看到,服务器的地址为
192.168.1.104
,端口:8266
,此配置信息可在demo
里面的头文件修改! -
发送数据原路返回和上面的服务器代码一样,只是当与服务器断开连接时候,需要关闭
socket
重新连接,而我们的服务器是不需要关闭socket
只是继续等待客户端连接,这一点需要注意!
3.1 实现的过程:
- 上电开启
station
模式来连接指定的路由器,连接成功之后创建socket
连接tcp server
服务器。 - 连接成功后,需要开启收发的任务,并且在收到数据之后原路返回。
- 如果连接成功之后,服务器突然断开,那么
esp32
需要断开socket
,毕竟服务器已经断开,留着也没用,之后尝试重新创建socket
来连接服务器,直到成功为止!
3.2 核心代码:
- ① 连接指定的路由器:
void wifi_init_sta()
tcp_event_group = xEventGroupCreate();
tcpip_adapter_init();
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
wifi_config_t wifi_config =
.sta =
.ssid = GATEWAY_SSID, //路由器名字
.password = GATEWAY_PAS,//路由器密码
;
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "wifi_init_sta finished.");
ESP_LOGI(TAG, "connect to ap SSID:%s password:%s \\n",
GATEWAY_SSID, GATEWAY_PAS);
- ② 创建客户端并且指定连接到服务器端:
//创建TCP客户端连接到指定的服务器
esp_err_t create_tcp_client()
ESP_LOGI(TAG, "will connect gateway ssid : %s port:%d\\n",
TCP_SERVER_ADRESS, TCP_PORT);
connect_socket = socket(AF_INET, SOCK_STREAM, 0);
if (connect_socket < 0)
show_socket_error_reason("create client", connect_socket);
return ESP_FAIL;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(TCP_PORT);
server_addr.sin_addr.s_addr = inet_addr(TCP_SERVER_ADRESS);
ESP_LOGI(TAG, "connectting server...");
if (connect(connect_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
show_socket_error_reason("client connect", connect_socket);
ESP_LOGE(TAG, "connect failed!");
return ESP_FAIL;
ESP_LOGI(TAG, "connect success!");
return ESP_OK;
四 demo
的配置信息:
- 下面的配置宏定义需要在头文件修改!
//true为开启热点并且创建tcp服务器,fasle为连接到指定的路由器并且连接到指定的tcp服务器
#define TCP_SERVER_CLIENT_OPTION FALSE
//打印的tag
#define TAG "XuHongTCP-->"
//以下是softAP热点模式的配置信息
#define SOFT_AP_SSID "XuHongTCP2018"
#define SOFT_AP_PAS "xuhong123456" //如果密码设置为空,则配置的热点是开放的,没有密码的。
#define SOFT_AP_MAX_CONNECT 1 //作为AP热点时候,最大的连接数目
//以下是station模式配置信息,是您家里的路由器的信息
#define GATEWAY_SSID "AliyunOnlyTest"
#define GATEWAY_PAS "aliyun#123456"
#define TCP_SERVER_ADRESS "192.168.1.104" //要连接TCP服务器地址
//统一的端口号,包括TCP客户端或者服务端
#define TCP_PORT 8266
五 下载:
- 注意运行
demo
前务必要修改配置信息,保证路由器名字密码正确! - 本博文硬件代码下载:https://download.csdn.net/download/xh870189248/10502414
- esp32汇总工程,欢迎star,收到第一更新信息:https://github.com/xuhongv/StudyInEsp32
以上是关于乐鑫Esp32学习之旅⑨ esp32上实现本地 TCP 客户端和服务端角色,可断线重连原路返回数据。(附带Demo)的主要内容,如果未能解决你的问题,请参考以下文章
乐鑫Esp32学习之旅28 分享在 esp32 SDK实现驱动 Flash W25Q32 的封装,扩大容量存储更多的资源。(开源源码工程)。
乐鑫Esp32学习之旅 乐鑫 ESP-S2/S3 模组的实现 USB 无线网卡上网,为你的台式机装上无线WiFI上网吧。(附带源码)
乐鑫Esp32学习之旅 乐鑫 ESP-S2/S3 模组的实现 USB 无线网卡上网,为你的台式机装上无线WiFI上网吧。(附带源码)
乐鑫Esp32学习之旅 乐鑫 ESP-S2/S3 模组的实现 USB 无线网卡上网,为你的台式机装上无线WiFI上网吧。(附带源码)
乐鑫Esp32学习之旅28 分享在 esp32 SDK实现驱动 Flash W25Q32 的封装,扩大容量存储更多的资源。(开源源码工程)。
乐鑫Esp32学习之旅28 分享在 esp32 SDK实现驱动 Flash W25Q32 的封装,扩大容量存储更多的资源。(开源源码工程)。