Detecting Disconnected Sockets

I'm creating a multi-threaded Tcp-Server, each thread reads from it's Network Stream in blocking mode.

How can I detect if a client is lost (not disconnected correctly)

My server works by catching the IO exception or receiving 0 bytes from the read function to alert a disconnect.

The problem is closing the connection (and thread for that matter) when the client's power is lost or it loses network connectivity.

Any help would be appreciated.

Thank you.



Answer this question

Detecting Disconnected Sockets

  • Cornel Arnet

    Ok, that is moving in the right direction...

    Currently, each client (in a separate thread) is using blocked mode to read from the stream. It just waits there indefinitely until it receives 0 bytes or an exception (my issue is when neither of these conditions are met and the thread just keeps listening).

    I tried setting a timeout for the read method, catch the exception and then try the "ping pong" idea. Unfortunately, the next iteration it tries to read, it continually throws the IO exception:

    Unable to read data from the transport connection: A non-blocking socket operation could not be completed immediately.

    I am using a TcpClient to handle the socket connection, but I got the socket and tried setting the Socket.Blocking Property to false. That didn't work.

    Any more ideas

    I'm trying not to create another thread that "pings" all the Network Streams. Can I even do that if I'm not using Async Communication


  • Kamii47

    Ganwold wrote:

    Yes, I handle those 2 situations correctly and the connections are properly closed.

    However, if the client's ethernet cable is unplugged or it's power is turned off, I do not recieve ANY exception in the server and the port stays open.

    I am using a multi-threaded server.

    Would you like me to post the Connection Handler class to look at my code

    Thank you in advance.

    It doesnot matter and you should always get a "0" byte from Socket.Receive() or NetworkStream.Read()

    Always Check this:

    int received = Socket.Receive(..........);

    if(received == 0)

    {

    // Disconnected

    }

    else

    {

    // Continue Working

    }

    Best Regards,

    Rizwan



  • Neo the 1

    If the client gracefully closed, you would receive 0 bytes from the receive
    if the client timed out or RESET the connection, you will get an exception.
    if you have a thread per client, then you just let that thread die. if you have a thread handling multiple
    connections/clients then you simply go to the next client h



  • Paul Nystrom

    I only have about 15 users tops. I think I'm just going to change things around so I can just set the timeout value (to a day or something) and then the client will just have to reconnect. The client is a embedded controller running it's own OS. I am writing this wrapper around a SOAP API which controls another device. On my next project, I'll be sure to look into the Async model.
  • Deza

    byte[] b = new byte[0];

    Socket.Receive(b, 0, 0);



  • Marcos B

     Durgaprasad Gorti wrote:

    Yes on the server side you can post a receive. One thing you can do is
    always have an async post on on the socket to get if there is any received data
    if that gives 0 or exception then the client is closed. Or periodically post a 0 byte receive.

    How exactly do you post a 0 byte recieve


  • Venkatram

    Yes on the server side you can post a receive. One thing you can do is
    always have an async post on on the socket to get if there is any received data
    if that gives 0 or exception then the client is closed. Or periodically post a 0 byte receive.



  • Shurek

    Yes you will need a seperate thread or even better just use System.Threading.Timer. But you should be warned that having a socket per thread model is about the worst thing you can do for performance. How many concurrent users do you have It's more work and more complicated but using asynchronous IO is always your best bet.


  • keshavbs

    That's not true, there are cases like he has stated that you do not receive any indication that the connection has dropped.  Especially if the connection is being nated.  The only way to know for sure the connection is open is to periodically send data.  I had one server that periodically sent a "ping" "pong".  Server sends a ping, client then returns with a pong.  But of course this only works if you have access to the client, if not then there is no "guaranteed" way of knowing if the client is still connected.

     


  • dragoncells

    Yes, I handle those 2 situations correctly and the connections are properly closed.

    However, if the client's ethernet cable is unplugged or it's power is turned off, I do not recieve ANY exception in the server and the port stays open.

    I am using a multi-threaded server.

    Would you like me to post the Connection Handler class to look at my code

    Thank you in advance.


  • Knvb1123

    I see the issue. Currently there is really "event" to tell you that the
    underlying socket is closed. The only way is to attempt a receive or send.
    Thats the only way to do it. Note that when the client has closed his side of the send,
    you could still send data but the receive will fail. So yes you might think that the connection is open
    until you send or receive data but once again the only sure fire way is to post a 0 byte receive periodcially.

    Also check out Larry Cleeton's blog on setting Keep Alives



  • Crazywetfrog

     Durgaprasad Gorti wrote:

    the only sure fire way is to post a 0 byte receive periodcially.

    Do I have to have this coming from the client   I do not have total control of it.  Is there a way to use the Time out property and then try to recieve again


  • Detecting Disconnected Sockets