c# TcpClientは接続状態が切断されているかどうかを判断します

まず問題を明確にします。TcpClient は scoket のカプセル化であり、TcpClient.Client は元のソケット オブジェクトです。

次に、 client.Client.Connected または client.Connected を使用して、まだ接続されているかどうかを判断することはできません。これは、このプロパティは、接続、アクティブな切断、または情報の送受信にのみ更新され、リアルタイム状態ではないためです。

Microsoft によれば、ノンブロッキング Send() を呼び出して 0 バイトのメッセージを送信することが可能であるとのことですが、送信が成功した場合は接続が継続していることを意味し、例外がスローされた場合は接続が切断されています。実験では動作しないことが判明しました リモートエンドは切断されて送信されました 0 バイトのメッセージはまだエラーを報告しません TcpClient のカプセル化に関連していると思われます 空のメッセージは動作しない可能性があります直接。そこで、1バイト送信するように変更し、接続切断後は正常にエラーが報告されるようになりました。

接続の検出方法は以下の通りで、接続中であればtrue、切断されていればfalseを返します。

 public bool IsSocketConnect(TcpClient client) //判断一个socket是否处于连接状态
    {
    
           
        if (client == null||client.Client == null)
        {
    
    
            return false;
        }
        //先看看状态
        if (client.Client.Connected == false || client.Client.RemoteEndPoint == null)
        {
    
    
            return false;
        }
        //尝试发送以非阻塞模式发送一个消息 注意这个非阻塞模式不会影响异步发送
        bool blockingState = client.Client.Blocking;
        try
        {
    
    
            byte[] tmp = new byte[1];
            client.Client.Blocking = false;
            client.Client.Send(tmp, 1, 0);
            return true;
        }
        catch (SocketException e)
        {
    
    
            // 产生 10035 == WSAEWOULDBLOCK 错误,说明被阻止了,但是还是连接的  这个错误是说发送缓冲区已满或者客户端的接收缓冲区已满
            if (e.NativeErrorCode.Equals(10035))
                return true;
            else
                return false;
        }
        finally
        {
    
    
            client.Client.Blocking = blockingState; //恢复状态
        }
    }

おすすめ

転載: blog.csdn.net/weixin_44568736/article/details/130990283