[En-Nut-Discussion] How to close a (TCP) connection/socket?

Philipp Burch phip at hb9etc.ch
Thu Dec 27 23:52:43 CET 2012


Hello everyone,

what is the correct way to close a (TCP) connection? If a client is 
connected (for example using Telnet) and it closes the connection, then 
everything works as expected. Waiting threads are woken up and blocking 
read functions return with an error code.

But now I have the problem that I can't correctly close a socket from 
the server (Ethernut) side. If the server is only listening 
(NutTcpAccept(...)) and I call NutTcpCloseSocket() from another thread, 
then the server will refuse to accept a connection, but the accept 
function does not return. The same happens if a client is connected, for 
example in an FTP session. Closing the socket has the effect that the 
next command causes the client to abort, but NutFtpServerSession() does 
not return.

When looking into the implementation of the TCP protocol, I see this 
part of the NutTcpStateCloseEvent function in <net/tcpsm.c>:

int NutTcpStateCloseEvent(TCPSOCKET * sock)
{
     if (sock == NULL) {
         return -1;
     }
     NutThreadYield();

     switch (sock->so_state) {
     case TCPS_LISTEN:
     case TCPS_SYN_SENT:
     case TCPS_CLOSED:
         /*
          * No connection yet, immediately destroy the socket.
          */
         NutTcpDestroySocket(sock);
         break;

     case TCPS_SYN_RECEIVED:
     case TCPS_ESTABLISHED:
// ...

If the current state is TCPS_LISTEN (which is the case when waiting in 
the NutTcpAccept() function), then the socket is simply destroyed. But 
this does not wake up any waiting threads. Shouldn't there be something like

NutEventBroadcast(&sock->so_pc_tq);

before destroying the socket?


Thanks,
Philipp


More information about the En-Nut-Discussion mailing list