9 years, 5 months ago.

TCPSocketServer and TCPSocketConnection - Detecting Client Disconnect

I'm running a TCP server on mbed, and connecting to it via teraterm/putty.

I would expect the code below to loop (printing "TCP is Connected") until I close the TCP connection on the client side (i.e. teraterm).

#include "mbed.h"
#include "EthernetInterface.h"

#define ECHO_SERVER_PORT   7

Serial pc(USBTX, USBRX);

int main (void) {
    
    
    pc.baud(115200);
    
    EthernetInterface eth;
    eth.init(); //Use DHCP
    eth.connect();
    printf("\nServer IP Address is %s\n", eth.getIPAddress());
    
    TCPSocketServer server;
    server.bind(ECHO_SERVER_PORT);
    server.listen();
    
    while (true) {
        printf("\nWait for new connection...\n");
        TCPSocketConnection client;
        server.accept(client);
        client.set_blocking(false, 1500); // Timeout after (1.5)s
        
        printf("Connection from: %s\n", client.get_address());
        
        while(client.is_connected())
        {
            printf("TCP is Connected\r\n");
            wait(1); 
        }
        
        printf("TCP is Closed\r\n");
        

    }
}

However, when I disconnect the client, this function remains true:

client.is_connected()

Using Wireshark, I can see the TCP packets FIN and RST from the client. Surely there is a way for my server (the mbed) to detect this and recognize that the client is disconnected?

It works the other way around. If I instead call:

client.close();

on the mbed side, my teraterm client gets the message just fine and closes.

Am I going about this the wrong way, or misunderstanding something?

Thanks.

1 Answer

5 years, 9 months ago.

I have this exact same issue, but I have more information to add to those of you who are still looking for this.

In particular client.is_connected() will not change state until the socket shutdown request is sent, and then shutdown command.

My python code example for what works:

Python Code Example (python sockets)

    def disconnect(self):
                                           
        self.s.shutdown(socket.SHUT_RDWR)    #shutdown(socket.SHUT_RDWR) prohibit read, write before close.
        self.s.close()                                                              #Close socket instance
        self.initialized = False                                         #Reset initialized Flag
        self.connected = False                                       #Reset connected flag

        return(True)

Note that if you do not run this disconnect command the mBed will continue to stay in the state of "connected". A timeout might be a good implementation with break....

Something like this:

if timer > threshold break

If anyone can shed further light on this subject it would be appreciated. Upon reading the TCPSocketServer codee it appears there is a timeout that should have handled this but I'm not quite sure how to get it to work.