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"); } } }
额外优化说明
- 连接状态判断:把
if(RemoteClient)改成if(RemoteClient.connected()),因为有时候RemoteClient对象可能还存在,但实际TCP连接已经断开,这样判断更准确。 - 细节修正:把拼写错误的
Client spoted改成了Client spotted,规范细节。 - 优先级陷阱规避:在赋值和比较混合的表达式里,一定要用括号明确运算顺序,这是C/C++新手很容易踩的坑。
现在再用Packet Sender发送数据,应该就能正常打印收到的字节,并且正确回发了!
内容的提问来源于stack exchange,提问作者Jakub Nevařil
相关产品推荐
相关产品推荐

