I have my TCP client working and sending sending sensor data as json packets to a TCP Server I coded with VB,NET. I noticed one small odd thing, that I am trying to understand and its probably a very basic lack of knowledge on my part how TCP sockets stay alive. The code below is public and looks like so many other minimal TCP clients. My question is in void Setup() where the TCP_Client is first connected. I have tried this on different Arduino Wifi boards, different routers, different PC’s, all the same. The initial “Hello” never is made and only the reconnection “Hello again” is the first TCP data sent and received. It would never be noticeable because the public sample code use “Hello” in both the initial void Setup() as well in the reconnection in void Loop(). Hey, it all works in the end but I am curious why and if you can replicate the same behavior.
/*
* Created by ArduinoGetStarted.com
*
* This example code is in the public domain
*
* Tutorial page: https://arduinogetstarted.com/tutorials/arduino-tcp-client
*/
#include <WiFiS3.h>
#include "arduino_secrets.h"
const char* WIFI_SSID = SECRET_SSID; // my network SSID
const char* WIFI_PASSWORD = SECRET_PASS; // my network password
const char* TCP_SERVER_ADDR = "192.168.1.2"; // CHANGE TO TCP SERVER'S IP ADDRESS
const int TCP_SERVER_PORT = 1470;
WiFiClient TCP_client;
void setup() {
Serial.begin(115200);
Serial.println("Arduino: TCP CLIENT");
// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true)
;
}
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
Serial.print("Attempting to connect to SSID: ");
Serial.println(WIFI_SSID);
// attempt to connect to WiFi network:
while (WiFi.begin(WIFI_SSID, WIFI_PASSWORD) != WL_CONNECTED) {
delay(10000); // wait 10 seconds for connection:
}
Serial.print("Connected to WiFi ");
Serial.println(WIFI_SSID);
// connect to TCP server
if (TCP_client.connect(TCP_SERVER_ADDR, TCP_SERVER_PORT)) {
Serial.println("Connected to TCP server");
TCP_client.write("Hello!"); // send to TCP Server
TCP_client.flush();
} else {
Serial.println("First time connection to TCP server FAILED!!");
}
}
void loop() {
if (!TCP_client.connected()) {
Serial.println("Connection is disconnected");
TCP_client.stop();
// reconnect to TCP server
if (TCP_client.connect(TCP_SERVER_ADDR, TCP_SERVER_PORT)) {
Serial.println("Reconnected to TCP server");
TCP_client.write("Hello Again!"); // send to TCP Server
TCP_client.flush();
} else {
Serial.println("Failed to reconnect to TCP server");
delay(1000);
}
}
// Other Loop code goes below
}
Instead of my VS2022 VB.NET TCP server I used ezTerm with same results. Here is the serial output on the Arduino R4 Wifi:
20:37:52.779 -> Arduino: TCP CLIENT
20:37:52.814 -> Attempting to connect to SSID: FiOS-JOS
20:37:52.908 -> Connected to WiFi FiOS-JOS
20:38:02.888 -> First time connect to TCP server FAILED!!
20:38:02.921 -> Connection is disconnected
20:38:02.921 -> Reconnected to TCP server
It’s after the reconnection that ezTerm receives the first data “Hello again!”.
I’ll try turning Nagles algorithm as suggested and report back
Yes, figuring out what's wrong with the protocol stack isn't for beginners, but you can use a hack and it will work just fine. I launched one project back in 2016, and it's been running nonstop to this day, with 9 years of uptime.
I don’t see any functional difference between your code and:
// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true)
;
}
Serial.print("Connected to WiFi ");
There clearly is something running in the background after the WiFi library code says its connected, that is not yet ready to proceed to open the TCP socket. On my system, the minimal delay required after WiFi connects and for TCP to connect first time (as the code above is written) requires about 50-100 msecs inserted delay.
// attempt to connect to WiFi network:
while (WiFi.begin(WIFI_SSID, WIFI_PASSWORD) != WL_CONNECTED) {
delay(10000); // wait 10 seconds for connection:
}
I see. Sorry I didn’t pick up on that part of the thread. I just looked at your code and the use of WiFi.begin() in a while loop looked strange to me. I’ve never tried / needed to do that. I’ve got 4 working ESP32 projects using the code that I posted. Three of them are ‘always on’ projects in the house.
Yes there must be something going on. I assume the TCP/IP stack has to do some initialisation after it finds out that it’s got a network connection.