ESP32-网络初探01——DNSServer(DNS服务)——CaptivePortal(自锁门户)

2024_6_28

网络编程常用协议介绍

下面为参考文章链接

什么是DNS,FTP,HTTP,DHCP及用途_dns和ftp的名字以及作用-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/qq_38314823/article/details/80517118

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服务器相关操作)

  1. DNS(Domain Name System):域名解析协议
  2. 代码中的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();
  }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值