I've got the AsyncTCP library @Juraj suggested in post #25 working. I have code for my project doing what I want and working reliably, and I made a simplified version of the client code, posted below. This pretty much does the same as the client code in post #8 but uses the AsyncTCP library. As this uses the AsyncTCP library it is non-blocking, leaving other code on the ESP8266 to carry on doing its thing regardless of what happens to the client-server connection. There is a 5 second timeout, which monitors for a reply from the server, if there is no reply in 5 seconds it attempts to reconnect to the server. The server is the same as the server code in post #8; I have not made new server code based on the AsyncTCP library. Enjoy.
// https://forum.arduino.cc/t/link-to-a-very-basic-tutorial-about-tcp/949935
// Demonstration code to transfer data from server to client using AsyncTCP, which is non-blocking
// This code sends a 'request' in for form of a single character to the corresponding server, which responds with the value of Millis
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#define STASSID "Put your WiFi SSID here"
#define STAPSK "Put your WiFi password here"
const char * ssid = STASSID;
const char * pass = STAPSK;
IPAddress serverIP(192, 168, 2, 62);
#define portNumber 7005
#define NUM_CLIENTS 2
#define CLIENTTIMEOUT 5
AsyncClient* clients[NUM_CLIENTS];
uint8_t timeout[NUM_CLIENTS];
const IPAddress addresses[NUM_CLIENTS] = {{192,168,2,62}, {192,168,2,62}}; // IP addresses of the servers, both the same here but can be different. Change to use the IP address(s) where your server is to be found.
void setup_serial_port();
void setup_wifi();
void setupClients();
void setup() {
setup_serial_port();
setup_wifi();
setupClients();
}
void loop() {
everySecond();
}
void everySecond() {
uint32_t currentMillis = millis();
static uint32_t lastMillis;
const uint32_t waitTime = 1000;
if (currentMillis - lastMillis >= waitTime) {
lastMillis += waitTime;
if (timeout[0]) {
--timeout[0];
}
if (timeout[1]) {
--timeout[1];
}
TCP_Client(0);
TCP_Client(1);
}
}
void TCP_Client(uint8_t clientIndex) {
static uint8_t state[NUM_CLIENTS];
enum states {notConnected, Connecting, Connected};
char message[32];
Serial.print("State = ");
Serial.println(state[clientIndex]);
if (clientIndex < NUM_CLIENTS) {
switch (state[clientIndex]) {
case notConnected:
if (clients[clientIndex]->connected()) {
timeout[clientIndex] = CLIENTTIMEOUT;
state[clientIndex] = Connected;
} else {
clients[clientIndex]->connect(addresses[clientIndex], portNumber);
timeout[clientIndex] = CLIENTTIMEOUT;
state[clientIndex] = Connecting;
}
break;
case Connecting:
if (clients[clientIndex]->connected()) {
timeout[clientIndex] = CLIENTTIMEOUT;
state[clientIndex] = Connected;
} else if (!timeout[clientIndex]) {
state[clientIndex] = notConnected;
}
break;
case Connected:
if (clients[clientIndex]->connected()) {
if (timeout[clientIndex]) {
sprintf(message, "T");
clients[clientIndex]->add(message, strlen(message));
clients[clientIndex]->send();
} else {
Serial.print("Client ");
Serial.print(clientIndex);
Serial.println(" timed Out");
clients[clientIndex]->stop();
timeout[clientIndex] = CLIENTTIMEOUT;
state[clientIndex] = notConnected;
}
} else {
state[clientIndex] = notConnected;
}
break;
}
}
}
/* event callbacks */
static void handleData(void* arg, AsyncClient* client, void *data, size_t len) {
//Serial.printf("data received from %s\n", client->remoteIP().toString().c_str());
if (client == clients[0]) {
Serial.print("Data from client 0 ");
Serial.write((uint8_t*)data, len);
timeout[0] = CLIENTTIMEOUT;
} else
if (client == clients[1]) {
Serial.print("Data from client 1 ");
Serial.write((uint8_t*)data, len);
timeout[1] = CLIENTTIMEOUT;
}
}
void onConnect(void* arg, AsyncClient* client) {
Serial.print("Client has been connected");
}
//Setup functions
void setup_serial_port() {
//uint32_t baudrate = 115200;
uint32_t baudrate = 9600;
Serial.begin(baudrate);
Serial.println("");
Serial.print("Serial port connected: ");
Serial.println(baudrate);
}
void setup_wifi() {
uint8_t wait = 0;
while (WiFi.status() != WL_CONNECTED) {
if (wait) {
--wait;
} else {
wait = 40;
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pass);
}
delay(100);
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void setupClients() {
uint8_t i;
for (i = 0; i < NUM_CLIENTS; ++i) {
clients[i] = new AsyncClient();
clients[i]->onData(&handleData, clients[i]);
clients[i]->onConnect(&onConnect, clients[i]);
}
}