8

If my client's connection is broken on the other end( kill -9 server). It takes several minutes for the client to determine that something is wrong. Socket.Connected returns true even though connection is actually broken.

What is the fastest way to determine that the connection doesn't exist, once the other end breaks the link?

Client code:

try{
      Socket socket= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
     /*Assume there is a connection on the other end*/
      while (socket.Connected)
      {
    
          /*Do some processing*/
      }
 }catch (SocketException se){
       Console.WriteLine(ex.Message);
 } catch (Exception ex){
       Console.WriteLine(ex.Message);
 }
 finally
 {
   Console.WriteLine("something bad happen");
 }
Community
  • 1
  • 1

6 Answers6

3

This seems to work for me... Does anyone see any issues?

public bool IsConnected
{
         get {return !(Socket.Poll(1, SelectMode.SelectRead) 
                                  && m_socket.Available ==0)}
}

Can also be put into an extension method.

public static class SocketExtensions
{
  public static bool IsConnected(this Socket @this)
  {
    return !(@this.Poll(1, SelectMode.SelectRead) && @this.Available == 0);
  }
}

Now you can easily use it in your code dealing with sockets.

var mySocket = new Socket();
while(mySocket.IsConncted())
{
  // Do Stuff
}
Samuel
  • 35,821
  • 11
  • 83
  • 84
  • Not an issue, but your code is a little smelly. You can replace the body of your method with "return !(socket.Poll(1, SelectMode.SelectRead) && m_socket.Available == 0);". – Samuel Mar 25 '09 at 16:47
  • You even make it into an extension method. public static class SocketExtensions { public static bool IsConnected(this Socket @this) { return !(@his.Poll(1, SelectMode.SelectRead) && @this.Available == 0); } } – Samuel Mar 25 '09 at 20:23
  • be more specific or put in to answer section the code sample. thx –  Mar 25 '09 at 21:04
  • This method suffers from a race condition that can give false determinations of a disconnection, as noted [here](https://stackoverflow.com/questions/722240/instantly-detect-client-disconnection-from-server-socket/53315852#comment46406629_722265). – Ian Nov 15 '18 at 09:42
1

Spawn another thread that is constantly pinging the server - really the best you can do since a socket is not an active connection.

George Mauer
  • 103,465
  • 117
  • 349
  • 581
  • Its moderately complicated, you'd have to do some research, but as far as I know that would be the surest way. Is that Matt Serra in your profile picture? – George Mauer Mar 25 '09 at 14:53
  • I found a solution. It is GSP –  Mar 25 '09 at 16:29
1

Try checking the Available property, it should throw a SocketException when the connection has been closed.

Source

Edit, here is how you would use it:

while(socket.Connected)
{
  try
  {
    while (socket.Available == 0)
      System.Threading.Thread.Sleep(100); // Zzzz
  }
  catch (SocketException)
  {
    // connection closed
    // do something
  }

  /* Do some processing */
}

You could also try using the Poll method.

From Source:

Alternatively, you can also utilize the Poll() Socket method with the SelectRead SelectMode parameter. This method will return a true value if data is available or if the connection has been closed by the remote host. You will then need to differentiate between which of these situations has occurred (by reading the socket buffer, and seeing if it returns a zero value).

GEOCHET
  • 20,623
  • 15
  • 71
  • 98
Samuel
  • 35,821
  • 11
  • 83
  • 84
  • Not going to work b/c sometimes socket is connected and no data is available, which in my case is fine... I want to specifically determine that socket is disconnected –  Mar 25 '09 at 14:45
  • Then its value is 0. I don't see the problem. Read the MSDN for the Available property. "If no data is queued in the network buffer, Available returns 0." "If the remote host shuts down or closes the connection, Available can throw a SocketException." – Samuel Mar 25 '09 at 14:47
  • "can" doesn't mean it will throw an exception... no reliable. –  Mar 25 '09 at 15:01
0

Maybe the SendTimeout and/or ReadTimeout properties of the Socket could help?

Svish
  • 138,188
  • 158
  • 423
  • 589
0

I refer you to my answer to your C++ version of this question...

Community
  • 1
  • 1
Len Holgate
  • 20,256
  • 4
  • 40
  • 89
-1

Have you tried to set a shorter connection timeout ?

Erick
  • 5,641
  • 10
  • 39
  • 59
  • While you might think setting a shorter timeout would help, it doesn't fix the underlying problem. Connected gets its value from the last IO operation, which will be true after the last read/write. – Samuel Mar 25 '09 at 14:44