How to run a TCP server without blocking the whole program?

Hi all

I’m looking about how to setup a TCP server listening in a port, like 9876 in order to receive strings from an external client.
I do this with the following code i the loop()

WiFiClient client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
String data_received = client.readStringUntil(‘\r\n’);
Serial.println("Data received " + data_received);
}
}
}

The problem is this code block all the program and i can not do any other task. How can i have this running and continue to execute rest of code in the loop function?

Thanks in advance.

https://github.com/me-no-dev/AsyncTCP.

https://github.com/GreenPonik/esp32-asyncTCP-server-example/blob/master/src/main.cpp.

Thanks very much for your response. I have looking in some solutions about async without success and that is the reason of this post.

I have downloaded the example and the compilation is ok. Upload to device is also ok. I start the serial monitoring, reboot the device, but nothing happens… i use a ESP32-2432S024C device.
When i reset, i receive the following on serial monitor and nothing more…:

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13232
load:0x40080400,len:3028
entry 0x400805e4

Any idea about what is the problem?
Thanks in advance.

The example opens an AccessPoint and waits for a WiFi client to connect to the ESP on port 8000.

As long as this does not happen, the code does not output anything on the serial interface. This is therefore not an error but the expected behavior of this example.

Thanks for your reply. Yes, tested and all is working.

But what i’m looking for is to open a port like in the example, but connecting to a WiFi. I do not need client to connect to the ESP AccessPoint. Client(s) and ESP must be connected to same WiFi.

Can you help?
Thanks in advance.

Then replace the

with a simple WiFi connect. The server will still work.

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.println("Connecting to WiFi..");
    }

This is what i done:

WiFi.begin(ssid, password);
WiFi.config(local_IP, gateway, subnet);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println(“Connecting to WiFi…”);
}
Serial.println(“Connected to WiFi”);
// server.begin();

AsyncServer *server = new AsyncServer(TCP_SERVER_PORT); // start listening on tcp port 7050

server->onClient(&handleNewClient, server);
server->begin();

It works, but on serial monitor, i receive lot of messages like this:

[ 1558][E][WiFiUdp.cpp:221] parsePacket(): could not receive data: 9

Any idea about how to solve this?
Thanks again!

Remove the DNS stuff:

In setup() remove these lines

	// start dns server
	if (!DNS.start(DNS_PORT, SERVER_HOST_NAME, WiFi.softAPIP()))
		Serial.printf("\n failed to start dns service \n");

In loop() remove

  DNS.processNextRequest();

The DNS stuff is only needed for the SoftAP which you’re not using.

Perfect. Thanks very much.

I think, the last one :slight_smile:

static void handleData(void *arg, AsyncClient *client, void *data, size_t len)

{

Serial.printf(“\n data received from client %s \n”, client->remoteIP().toString().c_str());

Serial.write((uint8_t *)data, len);

How to get the content of data in order to use it as string?
Thanks again in advance

(char *)data is the way.

Careful: Casting void* data to char* data, treating it like a C string, and using it to e.g. in a print function like Serial.println(data) will not work, because you are assuming data has a NULL byte at the end when it doesn’t have to (i.e., it’s not a C-string). You always have to see the pointer and the length as a pair and never read beyond its length. That’s why they explicitly use the print overload that takes a pointer and the length.