views:

157

answers:

2

Hi,

I'm trying to find out whether a Socket is currently connected - according to the MSDN docs for Socket.Connected - I should do the following:

// This is how you can determine whether a socket is still connected.
bool blockingState = client.Blocking;
try
{
    byte [] tmp = new byte[1];

    client.Blocking = false;
    client.Send(tmp, 0, 0);
    Console.WriteLine("Connected!");
}
catch (SocketException e) 
{
    // 10035 == WSAEWOULDBLOCK
    if (e.NativeErrorCode.Equals(10035))
        Console.WriteLine("Still Connected, but the Send would block");
    else
    {
        Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode);
    }
}
finally
{
    client.Blocking = blockingState;
}

 Console.WriteLine("Connected: {0}", client.Connected);

I've tested this works by connecting the socket to a remote server running on Windows and killing the remote server and it works fine.

However, if I do the same with a remote Server running on Unix (in this case MAC OS X) then the code does not work - the client.Send(tmp, 0, 0) call completes without throwing an exception and prints "Connected: true".

I'm guessing this has something to do with the fact that the other side of the connection has closed so the send may still work but a receive would fail - can I do a zero-byte Receive or something to see if the socket is closed?

+2  A: 

Yes, you can.

Calling Send only really checks if the local socket is open. Calling Receive will check the other end too.

Jon Grant
When I use Receive after the remote peer has disconnected it also completes successfully but returns 0 - is this a reliable way of detecting the connection has been lost?
Nosrama
There isn't really a single failsafe way to detect if the connection is still alive without actually trying to use the connection and catching any errors/exceptions, unfortunately. It's pretty standard to wrap your socket connection in a class with a receive buffer so you can read actual data off the wire to test the connection and store it for later when someone actually wants to use it.Also as stated by Oliver there are differences between various implementations of the TCP stack that mean that you will get different behaviour from different peers.
Jon Grant
+1  A: 

Maybe you can sniff with Wireshark the traffic and see if there are any difference if the dying server side is a windows or unix system.

Maybe the dying windows system is able to send a tcp close while the unix system can't. That would explain the difference (but maybe not help your actual problem).

btw, if you would use a udp connection you could never determine if the other site is living, due to the fact this would be a send & forget communication.

Oliver