You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP-01客户端无法接收WiFi服务器返回数据的技术求助

ESP8266 WiFi客户端无法接收服务器回复的问题解决

问题概述

使用ESP8266WiFi库(3.0.2版本)实现两台ESP-01的WiFi通信:客户端向端口5000的服务器发送2字节数据,可正常触发服务器端继电器引脚翻转,但客户端始终无法接收服务器的操作确认回复。库提示server.write()未实现,需使用server.accept()替代server.available(),但未找到可用示例,尝试参考client.print()相关内容也未解决问题。客户端发送数据后会循环10秒尝试接收,无返回后会再次请求翻转继电器,此循环可稳定运行数小时。

核心错误与排查建议

  1. 服务器端回复对象错误:
    服务器端当前使用server.println()发送回复,这是错误的——WiFiServer对象仅负责监听新连接,实际与客户端的通信必须通过已建立连接的WiFiClient实例完成。这是客户端收不到回复的直接原因。
  2. 关于server.accept()与server.available():
    在ESP8266WiFi库3.x版本中,server.available()仍然可以正常使用,server.accept()是其替代方法,两者均用于获取连接的客户端对象,区别在于accept()仅返回新建立的连接,而available()可能返回已存在的连接。

修正后的代码

通用定义(无需修改)

#include <ESP8266WiFi.h>

const char* ssid = "blablabla";
const char* password = "blublublu";
#define SERVER_PORT 5000
#define RELAY 0

// 通信协议定义
enum Protocol{
    PIN,     // 要控制的引脚编号
    VALUE,   // 引脚目标电平(HIGH=1 / LOW=0)
    BUFFER_SIZE // 协议缓冲区大小,必须作为枚举最后一项
};

修正后的服务器端代码

WiFiServer server(SERVER_PORT);

void setup()
{
  Serial.begin(115200);
  pinMode(RELAY, OUTPUT);
  digitalWrite(RELAY, LOW);
  
  // 连接WiFi
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED){
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nServer - WiFi connected");
  
  // 启动服务器
  server.begin();
  Serial.println("Server started");
  Serial.print("Use this IP to connect: ");
  Serial.println(WiFi.localIP());
}

void loop()
{
    // 使用server.accept()获取新连接的客户端
    WiFiClient client = server.accept();
    if (client) 
    {      
        Serial.println("New client connected");
        // 等待客户端发送数据(最多1秒)
        int nr_of_tries = 1000;
        while(!client.available() && nr_of_tries > 0)
        { 
          nr_of_tries--;
          delay(1);
        }
        if (client.available())
        {
          uint8_t buffer[Protocol::BUFFER_SIZE];
          int len = client.read(buffer, Protocol::BUFFER_SIZE);
          
          int pinNumber = buffer[Protocol::PIN];
          int value = buffer[Protocol::VALUE];
          
          Serial.print("Pin Number: ");
          Serial.println(pinNumber);
          Serial.print("Value: ");
          Serial.println(value);
          
          if (pinNumber == RELAY)
          { 
            pinMode(pinNumber, OUTPUT);
            digitalWrite(pinNumber, value);
          } 
          
          // 关键修正:通过client对象发送回复,而非server
          size_t sendLen;
          if (value == 0) {
            sendLen = client.println("Set");
          } else {
            sendLen = client.println("Reset");
          }
          Serial.print("Sent bytes: ");
          Serial.println(sendLen);
          
          // 确保数据发送完成
          client.flush();
        }
        // 关闭客户端连接
        client.stop();
        Serial.println("Client disconnected");
    }
}

客户端代码(微调优化)

int pin_value = 0;
uint8_t ip[4] = {10, 0, 0, 6};

void setup()
{
    Serial.begin(115200);
    
    // 连接WiFi
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED){
      delay(500);
      Serial.print(".");
    }
    Serial.println("\nClient - WiFi connected");
}

void loop(){ 
    WiFiClient client;
    if (!client.connect(ip, SERVER_PORT)){  
      Serial.println("Failed to connect to server");
      delay(1000);
      return; 
    }

    uint8_t buffer[Protocol::BUFFER_SIZE];
    buffer[Protocol::PIN] = RELAY;
    buffer[Protocol::VALUE] = pin_value;
    client.write(buffer, Protocol::BUFFER_SIZE);
    client.flush(); // 确保数据发送完成
      
    // 等待服务器回复(最多10秒)
    int nr_of_tries = 10000;
    String response = "";
     
    while (client.connected() && nr_of_tries > 0)
    {
      if (client.available())
        { 
          response = client.readStringUntil('\n');
          nr_of_tries = 0;
          Serial.print("Server response: ");
          Serial.println(response);
        }
      else
        {
          delay(1);
          nr_of_tries--;
        }
    }
    Serial.print("Remaining tries: ");
    Serial.println(nr_of_tries);
    Serial.print("Client connected: ");
    Serial.println(client.connected());
       
    client.stop();
    Serial.println("Request completed");
    
    // 切换引脚值
    pin_value = (pin_value == 0) ? 1 : 0;
    Serial.print("Pin_value set to: ");
    Serial.println(pin_value);
    
    delay(10000);
}

server.accept()使用示例

以下是server.accept()的基础用法,用于处理新的客户端连接:

WiFiServer server(5000);

void setup() {
  server.begin();
}

void loop() {
  // 获取新连接的客户端
  WiFiClient client = server.accept();
  if (client) {
    Serial.println("New client connected");
    
    // 读取客户端数据
    while (client.available()) {
      char c = client.read();
      Serial.print(c);
    }
    
    // 发送回复
    client.println("Hello from server");
    client.flush();
    
    // 关闭连接
    client.stop();
    Serial.println("Client disconnected");
  }
}

内容的提问来源于stack exchange,提问作者ToniE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 15:25:19