ESP8266-Arduino网络编程实例-异步TCP服务器(基于热点模式+DNS)

异步TCP服务器(基于热点模式+DNS)

在前面的文章ESP8266-Arduino网络编程实例-异步TCP服务器章中,我们实现了一个简单的异步TCP服务器,该服务器工作在WiFi的Station模式中。在本实例中,将实现如何在热点模式下实现异步TCP服务器。

本次实例的主要步骤如下:

  • 创建WiFi热点
  • 启动DNS服务器
  • 创建TCP服务器
  • 注册客户连接回调函数。回调函数包含如下处理情形:
    • 客户端数据处理
    • 错误处理
    • 连接断开处理
    • 超时处理
  • 启动TCP服务器
  • 监听并处理DNS客户端

1、硬件准备

  • ESP8266 NodeMCU开发板一块
  • 数据线一条

2、软件准备

  • Arduino IDE或VSCode + PlatformIO

在前面的文章中,对如何搭建ESP8266开发环境做了详细的介绍,请参考:

ESP8266 NodeMCU的引脚介绍在前面的文章中做了详细的介绍,请参考:

3、代码实现

本次使用到的ESPAsyncTCp库下载地址如下:

第一步,导入依赖头文件

1
2
3
4
5
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <DNSServer.h>
#include <vector>

第二步,DNS服务器、WiFi信息定义

1
2
3
4
5
6
7
8
9
10
#define SSID "ESP-TEST"
#define PASSWORD "123456789"

#define SERVER\_HOST\_NAME "esp\_server"

#define TCP\_PORT 7050
#define DNS\_PORT 53

static DNSServer DNS;

第三步,定义TCP连接客户端

1
2
static std::vector<AsyncClient\*> clients; // TCP客户端列表

第四步,TCP服务器回调函数定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// 错误处理
static void handleError(void\* arg, AsyncClient\* client, int8\_t error) {
Serial.printf("\n connection error %s from client %s \n", client->errorToString(error), client->remoteIP().toString().c\_str());
}

// 数据处理
static void handleData(void\* arg, AsyncClient\* client, void \*data, size\_t len) {
Serial.printf("\n data received from client %s \n", client->remoteIP().toString().c\_str());
Serial.write((uint8\_t\*)data, len);

// reply to client
if (client->space() > 32 && client->canSend()) {
char reply[32];
sprintf(reply, "this is from %s", SERVER_HOST_NAME);
client->add(reply, strlen(reply));
client->send();
}
}

// 连接断开处理
static void handleDisconnect(void\* arg, AsyncClient\* client) {
Serial.printf("\n client %s disconnected \n", client->remoteIP().toString().c\_str());
}

// 超时处理
static void handleTimeOut(void\* arg, AsyncClient\* client, uint32\_t time) {
Serial.printf("\n client ACK timeout ip: %s \n", client->remoteIP().toString().c\_str());
}

// 处理服务器事件
static void handleNewClient(void\* arg, AsyncClient\* client) {
Serial.printf("\n new client has been connected to server, ip: %s", client->remoteIP().toString().c\_str());

// 添加到客户端列表
clients.push\_back(client);

// 注册事件处理函数
client->onData(&handleData, NULL);
client->onError(&handleError, NULL);
client->onDisconnect(&handleDisconnect, NULL);
client->onTimeout(&handleTimeOut, NULL);
}

第五步,在setup函数中创建热点、启动DNS服务器和启动TCP服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void setup() {
Serial.begin(74880);
delay(20);
WiFi.begin(SSID, PWD);
// 创建热点
while (!WiFi.softAP(SSID, PASSWORD, 6, false, 15)) {
delay(500);
}

// 启动DNS服务器
if (!DNS.start(DNS_PORT, SERVER_HOST_NAME, WiFi.softAPIP())){
Serial.printf("\n failed to start dns service \n");
while(true);
}

// 创建TCP服务器
AsyncServer\* server = new AsyncServer(TCP_PORT);
// 注册TCP服务器事件回调函数
server->onClient(&handleNewClient, server);
// 启动TCP服务器
server->begin();
}

第六步,在loop函数中,处理DNS客户端

1
2
3
4
void loop() {
DNS.processNextRequest();
}

运行结果:

通过连接ESP8266开发板的热点,得到如下信息:

在这里插入图片描述

服务器:

在这里插入图片描述

客户端:

在这里插入图片描述

文章来源: https://iotsmart.blog.csdn.net/article/details/127305400