8

1つのクライアントのみを受け入れることができるC#でサーバーを開発していますが、別の接続要求を受け入れることができるようにするには、このクライアントがいつ切断されるかを知る必要があります。

クライアントとの接続要求を継続的にリッスンし、Socket.BeginAcceptクライアントを受け入れるか拒否する最初のソケットを使用しています。クライアントが受け入れられると、によって返される新しいソケットがSocket.EndAcceptクライアントとサーバー間の通信に使用されます。次に、サーバーはクライアントからのコマンドを待機し、Socket.Begin/EndReceive応答を送信します。サーバーはTelnetのようなプロトコルを使用します。つまり、各コマンドと応答の各行はで終わる必要があり\r\nます。

クライアントが切断されているかどうかを検出するために、500ミリ秒ごとに空のメッセージ( " \r\n")をクライアントに送信するタイマーをインストールしました。クライアントが切断されると、ソケットによって例外がスローされます。この例外は、現在のセッションを閉じて新しい接続を受け入れるサーバーによってキャッチされます。このソリューションは堅牢ですが、ネットワーク上の不要なトラフィックを意味し、実際の応答を取得する前にダミーメッセージをフィルタリングする必要があるクライアントによって正しく処理される必要があります。

空のバッファ()を送信しようとしましたSocket.Send(new byte[1], 0, 0)が、server->clientの方向で機能しないようです。

Socket.EndReceive別の解決策は、 0バイトを返す場合を処理することかもしれません。これは、「アイドル」時間中に発生する切断の場合に正常に機能します。ただし、メッセージ転送中にクライアントが切断された場合、サーバーは常にそれを認識しているわけではなく、無期限に待機します。

私はすでにこの問題に関するいくつかのスレッドと質問を見てきましたが、良い解決策を見たことがありません。

だから私の質問は:.Netで切断を検出するための最良の方法は何ですか?

4

4 に答える 4

5

他の唯一のオプションは、TCPの場合、TCPにキープアライブを頻繁に送信させることです。これは、現在実行していることなどのポーリングを継続しますが、TCPレイヤーで処理されるため、プロトコルは必要ありません。知る。

ただし、他のクライアントに何かを送信して応答を取得しないと、それがまだ接続されているかどうかを知る方法がないため、ポーリングを回避する方法はありません。

また、標準のNAPTなどのステートフルパケットインスペクションを介して通信する場合は、非アクティブのためにリモートサーバーがセッションをドロップしないようにするために、キープアライブが必要になる場合があります。

于 2009-09-02T12:29:50.470 に答える
3

以下の方法を使用して、クライアントがまだ接続されているかどうかを確認できます。これ

public static bool IsConnected(this TcpClient client)
{
    try
    {
        bool connected = !(client.Client.Poll(1, SelectMode.SelectRead) && client.Client.Available == 0);

        return connected;
    }
    catch
    {
        return false;
    }
}

この答えは、ソケットをテストするためのものです。これが、コードスニペットを取得する方法です。

于 2009-09-02T12:38:17.913 に答える
0

クライアントを管理できますか?もしそうなら、クライアントにサーバーに切断中であることを示す特別なパケットを送信させてから、ソケットを切断させることはできませんか?

クライアントが実際に切断された場合(Socket.Shutdown()またはSocket.Close()のいずれかを使用)、またはクライアントが長時間アイドル状態であるために排出する必要があるかどうかを検出しようとしていますか?

いずれの場合も、クライアントに定期的なメッセージをサーバーに送信してもらいます(これまでと同じように)。サーバーは最後のハートビートを追跡でき、クライアントが3つを超えるハートビートを見逃した場合は、クライアントを切断できます。はい、それは余分なデータを含みますが、それは物事の壮大な計画ではそれほど悪くはありません。クライアントが生きているかどうかを知ることができ、ハートビートの間隔が長すぎないように、十分な周期でハートビートを送信するように調整すると、非常に優れたシステムを実現できます。

于 2009-09-10T19:50:07.137 に答える
0

http://social.msdn.microsoft.com/forums/en-US/netfxnetcom/thread/d5b6ae25-eac8-4e3d-9782-53059de04628/を参照してください

于 2009-12-01T16:33:48.643 に答える