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

ESP32 TCP通信异常:WiFiClient.Read()返回1而非实际字符

问题分析与解决方案

嘿,我一眼就揪出问题所在了——是运算符优先级在搞鬼!

你代码里的循环条件 while(ch = RemoteClient.read() != -1 ) 犯了个经典的C/C++语法陷阱:!= 的优先级比 = 高,所以实际执行顺序是先判断 RemoteClient.read() != -1,得到一个布尔值(读到数据时是true对应1,没读到时是false对应0),然后把这个布尔值赋值给ch。这就导致不管你发送什么字节,ch永远是1,自然串口打印的都是'1',回发的也都是1。

修正后的完整代码

只要给RemoteClient.read()加上括号改变运算顺序,再做几个小优化就能解决问题:

#include <WiFi.h>
const uint ServerPort = 23;
WiFiServer Server(ServerPort);
WiFiClient RemoteClient;
const char *SSID = "SSID";
const char *WiFiPassword = "Password";

void ConnectToWifi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(SSID, WiFiPassword);
  Serial.print("Connecting to ");
  Serial.println(SSID);
  uint8_t i = 0;
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(500);
    if ((++i % 16) == 0) {
      Serial.println(F(" still trying to connect"));
    }
  }
  Serial.print(F("Connected. My IP address is: "));
  Serial.println(WiFi.localIP());
}

void CheckForConnections() {
  if (Server.hasClient()) {
    Serial.println("Client spotted"); // 修正拼写错误:spoted→spotted
    if (RemoteClient.connected()) {
      Serial.println("Connection rejected");
      Server.available().stop();
    } else {
      Serial.println("Connection accepted");
      RemoteClient = Server.available();
    }
  }
}

void setup() {
  Serial.begin(9600);
  ConnectToWifi();
  Server.begin();
}

void loop() {
  CheckForConnections();
  // 改成判断connected更严谨,避免对象存在但连接已断开的情况
  if(RemoteClient.connected()) { 
    uint8_t ch;
    bool newDataReceived = false;
    // 关键修正:给read()的结果加括号,确保先赋值再比较
    while( (ch = RemoteClient.read()) != -1 ){
      Serial.print(ch);
      RemoteClient.write(ch);
      newDataReceived = true;
    }
    if(newDataReceived){
      Serial.println();
      RemoteClient.print("Received data");
    }
  }
}

额外优化说明

  1. 连接状态判断:把if(RemoteClient)改成if(RemoteClient.connected()),因为有时候RemoteClient对象可能还存在,但实际TCP连接已经断开,这样判断更准确。
  2. 细节修正:把拼写错误的Client spoted改成了Client spotted,规范细节。
  3. 优先级陷阱规避:在赋值和比较混合的表达式里,一定要用括号明确运算顺序,这是C/C++新手很容易踩的坑。

现在再用Packet Sender发送数据,应该就能正常打印收到的字节,并且正确回发了!

内容的提问来源于stack exchange,提问作者Jakub Nevařil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 20:52:49