如何检查TcpClient连接是否已关闭?

Sup*_*ell 29 c# sockets networkstream tcpclient

我正在玩TcpClient,我试图弄清楚如何在连接断开时使Connected属性为false.

我试过了

NetworkStream ns = client.GetStream();
ns.Write(new byte[1], 0, 0);
Run Code Online (Sandbox Code Playgroud)

但是如果TcpClient断开连接,它仍然不会显示给我.你会如何使用TcpClient进行此操作?

uri*_*iel 42

我不建议您尝试编写仅用于测试套接字.并且不要在.NET的Connected属性上进行中继.

如果您想知道远程端点是否仍处于活动状态,可以使用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();
Run Code Online (Sandbox Code Playgroud)

另请参见:
TcpConnectionInformation MSDN上
IPGlobalProperties MSDN上
的说明TcpState规定
的Netstat上维基百科


这里它是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;
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很棒的答案.您可以改进它的唯一方法是将测试作为Socket的扩展方法呈现,该方法返回套接字状态. (3认同)
  • 更改行, .SingleOrDefault(x => x.LocalEndPoint.Equals(tcpClient.Client.LocalEndPoint) && x.RemoteEndPoint.Equals(tcpClient.Client.RemoteEndPoint)); (2认同)

Kep*_*boy 7

据我所知/记得没有办法测试套接字是否连接而不是读取或写入.

我根本没有使用TcpClient,但是如果远程端已经正常关闭,Socket类将从调用Read返回0.如果远程端没有正常关闭[我认为]你得到超时异常,不记得抱歉的类型.

使用像' if(socket.Connected) { socket.Write(...) }创建竞争条件的代码.你最好只是调用socket.Write并处理异常和/或断开连接.


fra*_*ers 5

Peter Wone 和 uriel 的解决方案非常好。但是您还需要检查远程端点,因为您可以有多个到本地端点的打开连接。

    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;
    }
Run Code Online (Sandbox Code Playgroud)