
arduino-esp32 WebServer 多网卡服务器示例在 STA 与 Soft AP 双接口上同时运行多个 WebServer【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32本文基于 arduino-esp32 官方示例 MultiHomedServers 及其 README 文档完整讲解“多网卡服务器Multi-Homed Servers”这一主题如何让一台 ESP32 同时以 Wi-Fi Station 和 Wi-Fi Soft AP 两个 IP 接口对外提供服务并将不同WebServer实例绑定到不同接口、不同端口。读完本文你能掌握WebServer(IPAddress, port)与WebServer(port)两种构造方式的底层区别、三个WebServer实例的共存要点以及如何用 mDNS 和串口日志验证各接口上的服务可达性。什么是多网卡服务器所谓 multi-homed server指在一台设备上为“不同的 IP 接口”分别运行独立的 Web 服务器。在基础 ESP32 设备上有且仅有两个 IP 接口Wi-Fi Station 接口设备作为客户端接入局域网路由器后获得的 IP例如192.168.42.24Wi-Fi Soft AP 接口设备自身作为热点SSID 如ESP32向其他设备提供的 IP固定为192.168.4.1。这个示例正是围绕 n2 的情形设计的README 明确指出由于基础 ESP32 只有这两个 IP 接口因此测试 n2 就是完整覆盖。要让它工作需要两个前提README 原文归纳WebServer和NetworkServer类必须正确支持“把某个 IP 地址传给构造函数”的用法即绑定到指定接口WebServer必须支持多个实例同时运行。该脚本的“主要目的”就是测试WebServer与NetworkServer的带 IP 地址构造函数README 同时诚实地说明本脚本验证了所使用的那部分功能在多实例下可工作但WebServer还有大量功能未被此脚本覆盖。三个服务器实例的规划示例创建了三个同时运行的 Web 服务器各绑定不同接口/端口下表完整继承自 READMEnameIP 地址端口server0INADDR_ANY所有接口8080server1Station 地址8081server2Soft AP 地址8081其中server0不指定 IP等价于绑定 INADDR_ANY在两个接口上都能收到请求它同时承担了“验证未绑定特定 IP 的服务器仍正常工作”这一测试职责server1只监听 STA 接口server2只监听 Soft AP 接口。三者都注册了/根路由和 404 处理器响应文本各自不同便于浏览器请求时肉眼区分命中的是哪个实例。另外示例还启动了 mDNS 应答器域名为esp32.local与 HelloServer 示例一样README 说明esp32.local在两个接口上均可解析但这一点“未被进一步测试”。示例源码逐段解析完整代码见 MultiHomedServers.ino核心结构如下1. 组网STA Soft AP 同时启用const char *ssid WiFi_SSID; const char *password WiFi_Password; const char *apssid ESP32; WebServer *server0, *server1, *server2;setup()中先以WIFI_STA模式连接局域网热点等待WL_CONNECTED后打印 Station IP随后调用WiFi.softAP(apssid)开启 Soft AP失败则 LED 闪烁进入死循环并打印 Soft AP IPWiFi.softAPIP()典型值192.168.4.1。最后启动 mDNSWiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() ! WL_CONNECTED) { delay(500); } ... if (!WiFi.softAP(apssid)) { /* 失败循环 */ } ... if (MDNS.begin(esp32)) { Serial.println(MDNS responder started); }2. 三种构造方式创建三个 WebServer这是整个示例的技术核心对应 MultiHomedServers.inoserver0 new WebServer(8080); // 不指定 IP监听所有接口 server1 new WebServer(WiFi.localIP(), 8081); // 绑定 Station 地址 server2 new WebServer(WiFi.softAPIP(), 8081); // 绑定 Soft AP 地址随后对每个实例分别注册路由与 404 处理器并启动server0-on(/, handleRoot0); server1-on(/, handleRoot1); server2-on(/, handleRoot2); server0-onNotFound(handleNotFound0); server1-onNotFound(handleNotFound1); server2-onNotFound(handleNotFound2); server0-begin(); server1-begin(); server2-begin();handleRoot*系列回调通过公共函数handleRoot(WebServer*, const char*)回复不同的text/plain文本回复期间点亮内置 LEDhandleNotFound*则回显请求的 URI、方法与全部 query 参数返回 404。由于每个实例的响应文本互不相同浏览器请求哪个地址立刻就能看出被哪个实例处理。3. loop 中轮询处理三个实例void loop(void) { server0-handleClient(); server1-handleClient(); server2-handleClient(); delay(2); //allow the cpu to switch to other tasks }多实例并发的关键就在于WebServer是“非阻塞轮询”模型handleClient()每次只处理一个到达的连接库头文件注释说明其“Supports only one simultaneous client”因此必须在loop()里为每个实例各调用一次handleClient()否则会饿死其他实例的请求处理。末尾delay(2)是给 FreeRTOS 其他任务的让出时间。4. 串口输出全部测试地址setup()末尾按 SSID 分组打印可直接访问的 URL对应 MultiHomedServers.inoSSID: 你的热点 http://station_ip:8080 http://station_ip:8081 SSID: ESP32 http://192.168.4.1:8080 http://192.168.4.1:8081 Any of the above SSIDs http://esp32.local:8080 http://esp32.local:8081源码级原理IP 地址参数如何传递到底层WebServer 的双构造函数。在 WebServer.h 中声明了两个构造函数重载WebServer(IPAddress addr, int port 80); WebServer(int port 80);其实现WebServer.cpp只是把参数透传给内部成员_serverWebServer::WebServer(IPAddress addr, int port) : _server(addr, port) { log_v(WebServer::Webserver(addr%s, port%d), addr.toString().c_str(), port); } WebServer::WebServer(int port) : _server(port) { log_v(WebServer::Webserver(port%d), port); }NetworkServer 的对应重载。WebServer的私有成员_server类型是NetworkServer见 WebServer.h。NetworkServer.h 中同样提供两个构造重载并额外接受max_clients默认 4NetworkServer(uint16_t port 80, uint8_t max_clients 4) NetworkServer(const IPAddress addr, uint16_t port 80, uint8_t max_clients 4)也就是说new WebServer(WiFi.localIP(), 8081)的完整调用链是WebServer构造 →NetworkServer(addr, port)→ 底层监听套接字绑定到该具体 IP。不传 IP 的构造则绑定通配地址INADDR_ANY两个接口上的报文都能到达。begin()阶段 WebServer.cpp 还会执行_server.setNoDelay(true)使套接字非阻塞这正是handleClient()可以被高频轮询的基础。多实例为什么可行。从源码结构看WebServer的全部运行时状态当前客户端_currentClient、请求/响应头链表、路由链表_firstHandler/_lastHandler等都是实例成员而非全局变量路由处理链RequestHandler也是每个实例各自持有的链表析构时逐个delete见 WebServer.cpp。因此三个实例之间互不干扰这与 README 中“WebServer 用于本 sketch 的那部分功能在多实例同时运行时可用”的结论一致。预期请求与响应行为README 给出了三组浏览器验证场景完整继承如下。场景 1客户端连接到与 Station 相同的 WLAN请求 URL响应http://stationaddress:8080Hello from server0 who listens on both WLAN and own Soft APhttp://stationaddress:8081Hello from server1 who listens only on WLAN场景 2客户端连接到 Soft AP请求 URL响应http://softAPaddress:8080Hello from server0 who listens on both WLAN and own Soft APhttp://softAPaddress:8081Hello from server2 who listens only on own Soft AP场景 3客户端连接 WLAN 或 Soft AP 均可mDNS请求 URL响应http://esp32.local:8080Hello from server0 who listens on both WLAN and own Soft APhttp://esp32.local:8081Hello from server1 who listens only on WLAN注意场景 3 中:8081命中的是server1WLAN 侧mDNS 解析出的地址落在哪个接口请求就只会被绑定该接口的实例接住。串口日志示例示例烧录运行后的典型输出继承自 README 的 Example Log OutputMulti-homed Servers example starting Connecting ... Connected to WiFi_SSID, IP address: 192.168.42.24 Soft AP SSID: ESP32, IP address: 192.168.4.1 MDNS responder started SSID: WiFi_SSID http://192.168.42.24:8080 http://192.168.42.24:8081 SSID: ESP32 http://192.168.4.1:8080 http://192.168.4.1:8081 Any of the above SSIDs http://esp32.local:8080 http://esp32.local:8081 HTTP server0 started HTTP server1 started HTTP server2 started日志中的 IP 会随网络环境变化应以实际串口输出为准来构造测试 URL。使用方法与适用目标操作步骤继承自 README 的 How to Use Example修改 MultiHomedServers.ino 顶部的ssid、password为你自己的 Wi-Fi 凭据apssid可保留默认ESP32在 Arduino IDE 中选择正确的板卡Tools - Board与串口Tools - Port烧录示例打开串口监视器115200 波特率按日志中打印的地址逐一在浏览器中访问验证。适用芯片README 的目标表覆盖 ESP32、ESP32-S2、ESP32-C3、ESP32-S3。从 CI 配置看ci.yml该示例的构建要求为CONFIG_SOC_WIFI_SUPPORTEDy或CONFIG_ESP_HOSTED_ENABLEDy即任何具备 Wi-Fi或 ESP-Hosted 外接 Wi-Fi的目标都可编译运行。示例对 LED 的处理也做了兼容有LED_BUILTIN宏则用板载 LED否则回退到 GPIO 13。已知问题与排错要点README 明确列出的已知问题与注意事项http://esp32.local在部分 Android 手机上无法访问。mDNS 解析依赖客户端系统对.local域名的支持Android 部分机型/部分 Wi-Fi 组合下不可用遇到时请改用直连 IP 地址测试确认使用质量可靠的 USB 数据线以及稳定的电源——README 将此列为排错第一要务供电不足是 ESP32 Wi-Fi 场景下连接不稳的常见根因。此外有两点使用限制值得注意其一README 声明该脚本只验证了“多实例 带 IP 构造”这一条主线WebServer其余功能文件服务、上传等在此并未被证明其二WebServer单实例本身只支持同一时间一个客户端连接见 WebServer.h 头部注释三个实例并存不等于支持高并发本示例的价值在于接口绑定行为验证而非性能基准。小结MultiHomedServers 示例用最少的代码约 140 行 sketch验证了 arduino-esp32 网络栈的一个关键能力WebServer可以按 IP 接口精确绑定端口且多个实例可安全共存。其技术要点可归纳为用WiFi.localIP()与WiFi.softAPIP()分别取两个接口的地址通过WebServer(IPAddress, port)构造器把实例钉死在目标接口上再用WebServer(port)保留一个全接口兜底实例loop()中对每个实例轮询handleClient()。结合 WebServer.cpp 与 NetworkServer.h 的源码可以确认这一行为由NetworkServer的 IP 重载构造器直接支撑。当你需要在同一块 ESP32 上为“局域网侧”和“本地热点侧”提供不同策略的 Web 服务例如配网期间走 Soft AP、联网后走 STA时这个示例就是可直接套用的参考实现。【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考