heinbali01 wrote on Saturday, April 02, 2016:
A user of FreeRTOS+TCP asked the following question:
Look at the output of FreeRTOS_netstat(). It was recorded on a K63F
machine:
Prot Port IP-Remote : Port R/T Status Alive tmout Child
TCP 3123 0.0.0.0 : 0 0/0 eTCP_LISTEN 0 0 0/2
TCP 80 0.0.0.0 : 0 0/0 eTCP_LISTEN 0 0 3/3
TCP 80 192.168.180.111 : 55940 1/0 eCLOSE_WAIT 0 19973
TCP 80 192.168.180.111 : 55942 1/0 eCLOSE_WAIT 0 19975
TCP 80 192.168.180.111 : 55944 1/0 eCLOSE_WAIT 0 20000
FreeRTOS_netstat: 5 sockets 2 < 3 < 3 buffers free
192.168.180.111 is the PC running several wget instances in parallel,
all connecting to K63F. Port 80 has a listen limit of 3 clients. After
1000-4000 seconds no new HTTP connections can be initiated, since there
are no free “slots”.I don’t understand why those closed sockets (all wgets are killed on
the PC) in eCLOSE_WAIT state remain there; they should disappear,
shouldn’t they? There’s a ‘tmout’ field, which reaches zero, but then
the countdown start from 20000 again.What could be the reason for these persistent, non-closing sockets?
From WiKiPedia:
CLOSE-WAIT
(both server and client) represents waiting for a connection
termination request from the local user.
A socket in the status “eCLOSE_WAIT
” is waiting for you! It has done
all it could and it may be closed by calling FreeRTOS_closesocket()
.
How can you prevent this?
- Check the return code of all API’s :
// Same for FreeRTOS_send()
xRc = FreeRTOS_recv(s, b, sizeof b, 0);
if( ( xRc < 0 ) && ( xRc != -pdFREERTOS_ERRNO_EWOULDBLOCK ) )
{
FreeRTOS_closesocket( s );
s = NULL;
return -1;
}
Note: if a socket’s connection is closed but it still has RX data, FreeRTOS_recv()
will return positive values until all data have been read.
-
After your socket is connected, you may call
FreeRTOS_issocketconnected()
to see if it is still connected. If it returns false you can close the socket. -
You can call
FreeRTOS_connstatus()
to check the status, but that is only recommended for debugging. -
Always try to close sockets gracefully. Also under other operating systems that communicate with your embedded systems. If your program decides to close a TCP connection, follow this procedure (symbolically):
FreeRTOS_shutdown(s, 0);
/* A FIN will be sent. Wait up to a few seconds for the other
party to ACK our FIN.
If the other party still had data to sent, it will do so.
Keep on calling FreeRTOS_recv() for this socket until it returns
a negative value (not equal to -EWOULDBLOCK) */
for( ;; )
{
/* Only do this if reading from 's' will block. */
xRc = FreeRTOS_recv(s, buf, sizeof buf, 0);
if( xRc > 0 )
{
/* Use the received data in 'buf'. */
}
else if( ( xRc < 0 ) && ( xRc != -pdFREERTOS_ERRNO_EWOULDBLOCK ) )
{
FreeRTOS_closesocket( s );
s = NULL;
break;
}
}
The flag for shutdown()
(RD, WR, and RDWR) has not been implemented in +TCP.
PS about FreeRTOS_issocketconnected()
:
For an active connection, using FreeRTOS_connect()
, you can call FreeRTOS_issocketconnected()
as well. It will return false until the socket gets connected. Once it is connected, it will return true until the connection is closed.
For passive connections (using FreeRTOS_accept()
), the socket will start in a connected state.