How getting immediate alert when TCP connection is closed ?

Jami17
Posts: 20
Joined: Wed Jul 12, 2017 10:55 pm

How getting immediate alert when TCP connection is closed ?

Postby Jami17 » Thu Jan 25, 2018 2:22 pm

The ESP32 runs as a listening TCP server. Each received 256 Byte packet is sent via the UART with 9600 Baud. Everything works nicely.
Because the UART speed it slow the ESP32 queues further incoming TCP data until its rcv-buffer is filled, only then the TCP-sender slows down.

If now the TCP connection gets prematurely closed, recv() still continues getting data from the queue until the rcv-buffer gets empty. Only then recv() returns -1 telling that the connection is closed. This is way too late.
Apparenty the close-info is also stored in the rcv-buffer.

I need an immediate way to find out if a connection got terminated, without waiting until recv() has read out the entire rcv-buffer. I checked errno, but that only reflects the rcv-buffer content, not the current socket state.

Is there any way to check the current socket state, or get a disconnected event?

peterglen
Posts: 27
Joined: Thu Mar 22, 2018 5:55 pm

Re: How getting immediate alert when TCP connection is closed ?

Postby peterglen » Wed Mar 28, 2018 9:14 pm

Use MSG_PEEK | MSG_DONTWAIT for seeing if the socket has data before recv blocks:

Here is a snippet that might help:

//////////////////////////////////////////////////////////////////////////
// Wait until data arrives, bail out if got end of HTML or closed socket
//

static int peekrecv(int sock, char *buf, int buflen)

{
int ret2 = 0, ret3 = 0, cnt = 0;

while(true)
{
int ret4 = 0, cnt2 = 0;

//ESP_LOGI(httpTAG, "recv data loop iter\n");

// Try for availablity
while(true)
{
if(cnt2++ > 5)
{
//ESP_LOGI(httpTAG, "breaking peek loop %d\n", cnt2);
break;
}
ret4 = recv(sock, buf + ret2, buflen - ret2, MSG_PEEK | MSG_DONTWAIT);
//ESP_LOGI(httpTAG, "recv peek %d\n", ret4);

if(ret4 < 0) { goto endrec; }
if(ret4 > 0) break;
vTaskDelay(20/portTICK_RATE_MS);
}

// Would not block, get it
if(ret4 > 0)
{
//ESP_LOGI(httpTAG, "about to block on %d\n", ret4);
ret3 = recv(sock, buf + ret2, buflen - ret2, 0);
if(ret3 < 0)
{
ret2 = ret3;
break;
}
ret2 += ret3;
//ESP_LOGI(httpTAG, "recv data %d '%s'\n", ret4, buf);
}

// Early out ... got the whole buffer
//if(strstr(buf, "</html>"))
// break;

if(ret2 >= buflen)
break;

if(cnt++ > 5)
{
//ESP_LOGI(httpTAG, "breaking recv loop %d\n", cnt2);
break;
}
}

endrec:

//ESP_LOGI(httpTAG, "recv data loop end %d bytes\n", ret2);
return ret2;
}

Who is online

Users browsing this forum: No registered users and 90 guests