2024_6_28
网络编程常用协议介绍
下面为参考文章链接
DNSServer(DNS服务)——CaptivePortal(自锁门户):
项目概述:
- 使用WiFi库在ESP32上创建AP模式(接入点模式)的WLFI连接,使得可以有用户连接ESP发出的WLFI信号并发出HTTL请求。
- 使用DNSServer库在ESP32上创建DNS服务器,实现所有被导向DNS服务器的HTTL请求导向预先设置好的HTTL页面,实现自锁门户。
#include <WiFi.h> // 引入WiFi库
#include <DNSServer.h> // 引入DNSServer库
const byte DNS_PORT = 53; // 定义DNS服务的端口号为53
IPAddress apIP(8,8,4,4); // 定义接入点的IP地址为8.8.4.4
DNSServer dnsServer; // 创建一个DNSServer对象
WiFiServer server(80); // 创建一个WiFiServer对象,监听80端口
// 定义一个HTML页面作为响应,当设备尝试访问任何网页时,它们将看到这个页面
String responseHTML = ""
"<!DOCTYPE html><html><head><title>CaptivePortal</title></head><body>"
"<h1>Hello World!</h1><p>This is a captive portal example. All requests will "
"be redirected here.</p></body></html>";
void setup() {
WiFi.mode(WIFI_AP); // 将WiFi模式设置为AP(接入点模式)
WiFi.softAP("ESP32-DNSServer"); // 创建一个名为"ESP32-DNSServer"的WiFi接入点
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); // 配置接入点的IP地址
// 启动DNS服务器,将所有的DNS请求重定向到我们定义的IP地址
dnsServer.start(DNS_PORT, "*", apIP);
server.begin(); // 启动Web服务器
}
void loop() {
dnsServer.processNextRequest(); // 处理所有传入的DNS请求
WiFiClient client = server.available(); // 监听是否有客户端连接到服务器
if (client) { // 如果有客户端连接
String currentLine = "";
while (client.connected()) { // 当客户端连接时
if (client.available()) { // 如果客户端有可用数据
char c = client.read(); // 读取数据
if (c == '\n') { // 如果读取到换行符
if (currentLine.length() == 0) { // 如果当前行为空,表示HTTP请求头结束
client.println("HTTP/1.1 200 OK"); // 发送HTTP响应状态码
client.println("Content-type:text/html"); // 发送内容类型头
client.println(); // 发送一个空行,表示HTTP响应头结束
client.print(responseHTML); // 发送HTML响应体
break; // 结束循环
} else { // 如果当前行不为空
currentLine = ""; // 清空当前行
}
} else if (c != '\r') { // 如果读取到的不是回车符
currentLine += c; // 将读取到的字符添加到当前行
}
}
}
client.stop(); // 断开客户端连接
}
}
一、DNSServer(DNS服务器相关操作)
- DNS(Domain Name System):域名解析协议
- 代码中的DNS服务实现的功能:组建私有服务器(实现定向页面访问)
const byte DNS_PORT = 53;
- 设置端口号为DNS服务默认:53号端口
二、WIFI(WIFI服务器相关)
1.WiFiServer对象,它在你的ESP32上创建了一个HTTP服务器。这个服务器监听80端口上的连接请求,当有客户端连接时,它会返回一个HTML页面。
WiFiServer server(80);
.三、HTTP响应页面
String responseHTML = ""
"<!DOCTYPE html>" // 声明这是一个HTML5文档
"<html>" // HTML文档的根元素
"<head>" // 包含文档的元数据
"<title>CaptivePortal</title>" // 定义文档的标题
"</head>"
"<body>" // 包含文档的主体内容
"<h1>Hello World!</h1>" // 一级标题
"<p>This is a captive portal example(囚禁门户示例程序). All requests will be redirected here.</p>" // 段落
"</body>"
"</html>";
三、主函数
setup函数:
1.WIFI设置
WiFi.mode(WIFI_AP);
WiFi.softAP("ESP32-DNSServer");
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
- WiFi.mode(WIFI_AP)——AP模式(接入点模式),在此模式下能够创建可被连接的WIFI。
- WiFi.softAP("ESP32-DNSServer");——创建WIFI并设置名称为"ESP32-DNSServer"。
- WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));——配置必要参数。
-
三个参数,分别是本地IP地址、网关IP地址和子网掩码。
- 本地IP地址:将局域网内的计算机或设备连接起来,使它们之间可以互相访问,从而实现网络资源共享。
- 网关IP地址:访问互联网的入口,大多数情况下,这个地址和本地IP地址是一样的。
- 子网掩码:确定IP地址的哪些位表示网络地址,哪些位表示主机地址。
2.DNS设置
dnsServer.start(DNS_PORT, "*", apIP);
-
启动了DNS服务器(域名解析协议)。
-
并对域名为"*"(所有的DNS请求)返回接入点的IP地址。
DNS_PORT
:DNS服务器监听的端口号,通常为53。"*"
:表示对所有域名的请求进行响应。使用星号(*
)作为域名参数,DNS服务器将拦截所有DNS查询,并将它们重定向到指定的IP地址。apIP
:这是DNS服务器要返回给客户端的IP地址。在您的代码中,apIP
是一个IPAddress
对象,它被设置为8,8,4,4
,这是Google的公共DNS服务器地址。
3.HTTL设置
server.begin();
- 启动了HTTP服务器(超文本传输协议)
- HTTP服务器监听80端口(这是HTTP服务的默认端口)。
Loop函数:
1.DNS设置
dnsServer.processNextRequest();
- 处理DNS服务器接收到的DNS请求。
- 处理方法:当客户端尝试解析域名时,DNS服务器会将所有请求(前文配置了“*”)重定向到配置的IP地址(8,8,4,4)。
void loop() {
dnsServer.processNextRequest();
WiFiClient client = server.available();
// 不断监听有没有客户端的链接,有的话client为Tru,没有的话为False
// 有链接时进入下面的if执行
if (client) {
// 初始化字符串存储客户端发来的HTTL请求
String currentLine = "";
// 持续地与客户端进行交互,直到客户端选择断开连接
while (client.connected()) {
// 更新与客户端之间的链接状态
// 同时查询有无客户端的HTTL请求
if (client.available()) {
// 读取客户端发送的一个字符
char c = client.read();
// 当出现"\n",表示该条语句结束
if (c == '\n') {
// 当新的语句长度为0,即为空
// 语句为空表示HTTL数据接收结束
// 发送响应内容
if (currentLine.length() == 0) {
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
client.print(responseHTML);
break;
}
// 语句结束且不为无效语句
// 清空字符串,用于储存下一条语句
else {
currentLine = "";
}
}
// HTTL语句未结束,不断将读取到的字符添加到语句末端
else if (c != '\r') {
currentLine += c;
}
}
}
// 未和客户端连接时释放系统资源
client.stop();
}
}