How to check if a socket is connected or disconnected in C #?

How can you check if a network socket (System.Net.Sockets.Socket) is connected if another host does not send you a packet when it disconnects (for example, because it is disconnected unfairly)?

+48
c # sockets connection
Apr 18 '10 at 9:35 a.m.
source share
9 answers

As Paul Turner answered, Socket.Connected cannot be used in this situation. You should check the connection each time to see if the connection is enabled. This is the code I used:

 bool SocketConnected(Socket s) { bool part1 = s.Poll(1000, SelectMode.SelectRead); bool part2 = (s.Available == 0); if (part1 && part2) return false; else return true; } 

It works as follows:

  • s.Poll returns true if
    • connection closed, reset, completed, or pending (which means there is no active connection)
    • active and readable data
  • s.Available returns the number of bytes available for reading
  • if both truths:
    • there is no data to read, so the connection is inactive
+74
Apr 18 '10 at 10:17
source share

As zendar wrote, it's good to use Socket.Poll and Socket.Available , but you need to consider that the socket may not have been initialized in the first place. This is the last (I think) piece of information, and it is provided by the Socket.Connected property. The revised version of the method will look something like this:

  static bool IsSocketConnected(Socket s) { return !((s.Poll(1000, SelectMode.SelectRead) && (s.Available == 0)) || !s.Connected); /* The long, but simpler-to-understand version: bool part1 = s.Poll(1000, SelectMode.SelectRead); bool part2 = (s.Available == 0); if ((part1 && part2 ) || !s.Connected) return false; else return true; */ } 
+20
Feb 17 '13 at 19:59
source share

The Socket.Connected property will tell you if the socket considers it a connection. It actually reflects the state of the last send / receive operation performed on the socket.

If the socket was closed by your own actions (deleting the socket, calling methods to disconnect), Socket.Connected will return false . If the socket has been disabled by other means, the property will return true until you try to send or receive information, after which a SocketException or ObjectDisposedException will be ObjectDisposedException .

You can check the property after an exception occurs, but it is not reliable before that.

+11
Apr 18 2018-10-18T00:
source share

The accepted answer does not work if you disconnect the network cable. Or the server is crashing. Or your router crashes. Or if you forget to pay your Internet bill. Set TCP save options for better reliability.

 public static class SocketExtensions { public static void SetSocketKeepAliveValues(this Socket instance, int KeepAliveTime, int KeepAliveInterval) { //KeepAliveTime: default value is 2hr //KeepAliveInterval: default value is 1s and Detect 5 times //the native structure //struct tcp_keepalive { //ULONG onoff; //ULONG keepalivetime; //ULONG keepaliveinterval; //}; int size = Marshal.SizeOf(new uint()); byte[] inOptionValues = new byte[size * 3]; // 4 * 3 = 12 bool OnOff = true; BitConverter.GetBytes((uint)(OnOff ? 1 : 0)).CopyTo(inOptionValues, 0); BitConverter.GetBytes((uint)KeepAliveTime).CopyTo(inOptionValues, size); BitConverter.GetBytes((uint)KeepAliveInterval).CopyTo(inOptionValues, size * 2); instance.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null); } } // ... Socket sock; sock.SetSocketKeepAliveValues(2000, 1000); 

The time value sets the timeout since the last data was sent. He then tries to send and receive a keep-alive packet. If it fails, it retries 10 times (the number is hard-coded with Vista AFAIK) in the interval specified before deciding to disconnect the connection.

Thus, the above values ​​will lead to the detection of 2 + 10 * 1 = 12 seconds. After that, any read operations / wrtie / poll will not be performed on the socket.

+4
Sep 23 '16 at 15:34
source share

I made an extension method based on this MSDN article. Here's how you can determine if a socket is still connected.

 public static bool IsConnected(this Socket client) { bool blockingState = client.Blocking; try { byte[] tmp = new byte[1]; client.Blocking = false; client.Send(tmp, 0, 0); return true; } catch (SocketException e) { // 10035 == WSAEWOULDBLOCK if (e.NativeErrorCode.Equals(10035)) { return true; } else { return false; } } finally { client.Blocking = blockingState; } } 
+2
Apr 20 '16 at 3:02
source share

The best way is to simply send a PING to the client every X seconds, and for the server to assume that it is down after it has not received for some time.

I ran into the same problem as when using sockets, and that was the only way to do this. The socket.connected property has never been correct.

In the end, I switched to using WCF because it was much more reliable than sockets.

+1
Apr 18 '10 at
source share

Following the advice of NibblyPig and zendar , I came up with the code below that works on every test I did. In the end, it took me both ping and polling. Ping will let me know if the cable is disconnected or the physical layer is otherwise broken (the router is disconnected, etc.). But sometimes after reconnecting I get RST, ping is ok, but tcp state is not.

 #region CHECKS THE SOCKET HEALTH if (_tcpClient.Client.Connected) { //Do a ping test to see if the server is reachable try { Ping pingTest = new Ping() PingReply reply = pingTest.Send(ServeripAddress); if (reply.Status != IPStatus.Success) ConnectionState = false; } catch (PingException) { ConnectionState = false; } //See if the tcp state is ok if (_tcpClient.Client.Poll(5000, SelectMode.SelectRead) && (_tcpClient.Client.Available == 0)) { ConnectionState = false; } } } else { ConnectionState = false; } #endregion 
+1
Aug 26 '16 at 18:45
source share
 public static class SocketExtensions { private const int BytesPerLong = 4; // 32 / 8 private const int BitsPerByte = 8; public static bool IsConnected(this Socket socket) { try { return !(socket.Poll(1000, SelectMode.SelectRead) && socket.Available == 0); } catch (SocketException) { return false; } } /// <summary> /// Sets the keep-alive interval for the socket. /// </summary> /// <param name="socket">The socket.</param> /// <param name="time">Time between two keep alive "pings".</param> /// <param name="interval">Time between two keep alive "pings" when first one fails.</param> /// <returns>If the keep alive infos were succefully modified.</returns> public static bool SetKeepAlive(this Socket socket, ulong time, ulong interval) { try { // Array to hold input values. var input = new[] { (time == 0 || interval == 0) ? 0UL : 1UL, // on or off time, interval }; // Pack input into byte struct. byte[] inValue = new byte[3 * BytesPerLong]; for (int i = 0; i < input.Length; i++) { inValue[i * BytesPerLong + 3] = (byte)(input[i] >> ((BytesPerLong - 1) * BitsPerByte) & 0xff); inValue[i * BytesPerLong + 2] = (byte)(input[i] >> ((BytesPerLong - 2) * BitsPerByte) & 0xff); inValue[i * BytesPerLong + 1] = (byte)(input[i] >> ((BytesPerLong - 3) * BitsPerByte) & 0xff); inValue[i * BytesPerLong + 0] = (byte)(input[i] >> ((BytesPerLong - 4) * BitsPerByte) & 0xff); } // Create bytestruct for result (bytes pending on server socket). byte[] outValue = BitConverter.GetBytes(0); // Write SIO_VALS to Socket IOControl. socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); socket.IOControl(IOControlCode.KeepAliveValues, inValue, outValue); } catch (SocketException) { return false; } return true; } } 
  • Copy the SocketExtensions class to your project
  • Call SetKeepAlive on your socket - socket.SetKeepAlive (1000, 2);
  • Add a timer to test the IsConnected function
0
Oct 18 '17 at 8:27
source share

Use the Socket.Connected Property.

-eleven
Apr 18 '10 at 9:38 on
source share



All Articles