How to check if TcpClient Connection is closed?

As far as I know/remember there is no way to test if a socket is connected other than reading or writing to it.

I haven't used the TcpClient at all but the Socket class will return 0 from a call to Read if the remote end has been shutdown gracefully. If the remote end doesn't shutdown gracefully [I think] you get a timeout exception, can't remember the type sorry.

Using code like 'if(socket.Connected) { socket.Write(...) } creates a race condition. You're better off just calling socket.Write and handling the exceptions and/or disconnections.


I wouldn't recommend you to try write just for testing the socket. And don't relay on .NET's Connected property either.

If you want to know if the remote end point is still active, you can use TcpConnectionInformation:

TcpClient client = new TcpClient(host, port);

IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
TcpConnectionInformation[] tcpConnections = ipProperties.GetActiveTcpConnections().Where(x => x.LocalEndPoint.Equals(client.Client.LocalEndPoint) && x.RemoteEndPoint.Equals(client.Client.RemoteEndPoint)).ToArray();

if (tcpConnections != null && tcpConnections.Length > 0)
{
    TcpState stateOfConnection = tcpConnections.First().State;
    if (stateOfConnection == TcpState.Established)
    {
        // Connection is OK
    }
    else 
    {
        // No active tcp Connection to hostName:port
    }

}
client.Close();

See Also:
TcpConnectionInformation on MSDN
IPGlobalProperties on MSDN
Description of TcpState states
Netstat on Wikipedia


And here it is as an extension method on TcpClient.

public static TcpState GetState(this TcpClient tcpClient)
{
  var foo = IPGlobalProperties.GetIPGlobalProperties()
    .GetActiveTcpConnections()
    .SingleOrDefault(x => x.LocalEndPoint.Equals(tcpClient.Client.LocalEndPoint));
  return foo != null ? foo.State : TcpState.Unknown;
}

The solution of Peter Wone and uriel is very nice. But you also need to check on the Remote Endpoint, since you can have multiple open connections to your Local Endpoint.

    public static TcpState GetState(this TcpClient tcpClient)
    {
        var foo = IPGlobalProperties.GetIPGlobalProperties()
          .GetActiveTcpConnections()
          .SingleOrDefault(x => x.LocalEndPoint.Equals(tcpClient.Client.LocalEndPoint)
                             && x.RemoteEndPoint.Equals(tcpClient.Client.RemoteEndPoint)
          );

        return foo != null ? foo.State : TcpState.Unknown;
    }