2、WiFi连接实战:ESP32连接路由器,实现TCP客户端与服务器通信

好,咱们进入第二章。上一章我们把开发环境搭好了,也点亮了LED。但ESP32真正的价值在于联网。这一章,我们就让它连上家里的路由器,然后跟电脑上的TCP工具聊聊天。

说白了,物联网的第一步就是让设备能上网。ESP32自带WiFi,这是它的核心优势。我刚开始做项目时,总觉得连WiFi很简单,不就是填个SSID和密码吗?结果在实际项目中踩了不少坑。嗯,咱们今天就把这些坑提前填上。

2.1 WiFi连接的基础流程

ESP32连接WiFi,其实就三步:

  1. 初始化WiFi驱动
  2. 设置工作模式(Station模式)
  3. 调用连接函数,等待连接成功

听起来简单,但里面有几个关键点,我当年就吃过亏。

核心概念:ESP32的WiFi支持三种模式:Station(客户端)、AP(热点)、Station+AP(混合)。我们连路由器,用的是Station模式。

2.2 实战:编写WiFi连接代码

先看一个最基础的连接示例。我习惯把WiFi连接封装成一个独立函数,这样主程序看起来清爽。

#include <WiFi.h>

// 替换成你的路由器信息
const char* ssid = "Your_SSID";
const char* password = "Your_PASSWORD";

void setup() {
  Serial.begin(115200);
  delay(1000);
  
  Serial.println();
  Serial.print("正在连接: ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  // 等待连接
  int attempts = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    attempts++;
    if (attempts > 40) {  // 超时20秒
      Serial.println("\n连接失败!");
      return;
    }
  }
  
  Serial.println("\n连接成功!");
  Serial.print("IP地址: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  // 检查连接状态
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("WiFi断开,尝试重连...");
    WiFi.reconnect();
  }
  delay(5000);
}

我的习惯:连接超时一定要加。我曾经在一个项目中没加超时,结果路由器重启后,ESP32一直卡在while循环里,整个系统都挂了。加个计数器,20秒连不上就报错,然后可以进入备用逻辑。

2.3 从WiFi到TCP:建立客户端连接

WiFi连上了,接下来就是TCP通信。TCP是什么?说白了就是两台设备之间建立一条可靠的“管道”,你发数据我确认,确保数据不丢不乱。

ESP32作为TCP客户端,需要知道服务器的IP地址和端口号。我一般用电脑上的网络调试助手做服务器测试。

#include <WiFi.h>
#include <WiFiClient.h>

const char* ssid = "Your_SSID";
const char* password = "Your_PASSWORD";
const char* host = "192.168.1.100";  // 电脑的IP
const uint16_t port = 8080;

WiFiClient client;

void setup() {
  Serial.begin(115200);
  connectWiFi();
  connectTCPServer();
}

void connectWiFi() {
  WiFi.begin(ssid, password);
  Serial.print("连接WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWiFi已连接");
  Serial.print("IP: ");
  Serial.println(WiFi.localIP());
}

void connectTCPServer() {
  Serial.print("连接TCP服务器...");
  if (client.connect(host, port)) {
    Serial.println("成功!");
    client.println("Hello from ESP32!");
  } else {
    Serial.println("失败!");
  }
}

void loop() {
  if (client.connected()) {
    if (client.available()) {
      String line = client.readStringUntil('\n');
      Serial.println("收到: " + line);
    }
  } else {
    Serial.println("连接断开,5秒后重连...");
    delay(5000);
    connectTCPServer();
  }
}

注意:电脑的防火墙可能会拦截TCP连接。我第一次测试时,ESP32一直连不上,折腾了半天才发现是Windows防火墙没关。建议先关闭防火墙,或者添加端口例外。

2.4 进阶:ESP32作为TCP服务器

有时候,我们需要ESP32充当服务器,让其他设备主动连接它。比如传感器数据采集节点,电脑去连它读取数据。

#include <WiFi.h>
#include <WiFiServer.h>

WiFiServer server(8080);
WiFiClient client;

void setup() {
  Serial.begin(115200);
  WiFi.begin("Your_SSID", "Your_PASSWORD");
  while (WiFi.status() != WL_CONNECTED) delay(500);
  
  Serial.println("WiFi已连接");
  Serial.print("服务器IP: ");
  Serial.println(WiFi.localIP());
  
  server.begin();
  Serial.println("TCP服务器已启动,端口: 8080");
}

void loop() {
  if (!client.connected()) {
    client = server.available();
    if (client) {
      Serial.println("新客户端连接");
      client.println("欢迎连接到ESP32服务器!");
    }
    return;
  }
  
  if (client.available()) {
    String data = client.readStringUntil('\n');
    Serial.println("收到: " + data);
    client.println("已收到: " + data);
  }
}

2.5 知识结构图:WiFi与TCP通信全景

下面这张图,把整个通信链路画清楚了。从ESP32到路由器,再到电脑上的TCP工具,数据是怎么流动的。

ESP32 WiFi + TCP 通信架构 ESP32 WiFi Station模式 TCP 客户端/服务器 路由器 DHCP分配IP 数据包转发 电脑 网络调试助手 TCP 服务器/客户端 WiFi连接 以太网/WiFi 数据流方向 ESP32 → 路由器 → 电脑(TCP客户端发送数据) 协议栈层次 应用层(TCP数据) → 传输层(TCP协议) → 网络层(IP协议) → 链路层(WiFi)

2.6 常见问题与避坑指南

问题 原因 解决方案
WiFi连接超时 路由器信号弱或密码错误 检查SSID和密码,靠近路由器测试
TCP连接失败 IP地址或端口不对,防火墙拦截 用ping测试连通性,关闭防火墙
连接不稳定频繁断开 WiFi信号干扰,电源供电不足 使用独立电源,添加重连机制
数据接收乱码 编码不一致,缺少换行符 统一使用UTF-8,添加'\n'作为结束符

我曾经踩过的坑:有一次在工厂部署,ESP32连上WiFi后,每隔几分钟就掉线。排查了很久,发现是路由器开启了“5G优先”模式,而ESP32只支持2.4G。后来强制绑定2.4G频段才解决。记住,ESP32的WiFi只支持2.4GHz频段。

2.7 本章小结

这一章我们做了三件事:让ESP32连上WiFi、作为TCP客户端发送数据、作为TCP服务器接收连接。这些是物联网通信的基石。

你想想看,有了WiFi连接和TCP通信,ESP32就不再是一个孤立的单片机了。它可以跟世界对话。下一章,我们会在这个基础上,引入MQTT协议——这才是物联网通信的真正主角。

嗯,今天的代码建议都动手跑一遍。特别是TCP客户端和服务器两种模式,都试试。遇到问题很正常,对照上面的表格排查。我在项目里遇到的坑,基本都列出来了。