私はC#でクライアントを1つだけ受け入れることができるサーバーを開発しています。このクライアントが切断されたときに別の接続要求を受け入れることができるようにする必要があります。.NETでクライアントの切断を検出するためのベストプラクティスはありますか。
私は接続要求を継続的に聞き取り、Socket.BeginAccept
でクライアントを受け入れるか拒否する最初のソケットを使用しています。クライアントが受け入れられると、Socket.EndAccept
によって返される新しいソケットは、クライアントとサーバー間の通信に使用されます。次に、サーバーはクライアントからのコマンドをSocket.Begin/EndReceive
で待機し、応答を送信します。サーバーはTelnetのようなプロトコルを使用します。つまり、各コマンドと各応答行は、\r\n
で終わらなければなりません。
クライアントが切断されているかどうかを検出するために、空のメッセージ( "\r\n
")をクライアントに500msごとに送信するタイマーをインストールしました。クライアントが切断されると、Socketによって例外がスローされます。この例外は、現在のセッションを閉じて新しい接続を受け入れるサーバーによって捕捉されます。このソリューションは堅牢ですが、ネットワーク上の不要なトラフィックを意味し、実際の応答を得る前にダミーメッセージをフィルタリングする必要があるクライアントによって正しく処理されなければなりません。
空のバッファー(Socket.Send(new byte[1], 0, 0)
)を送信しようとしましたが、方向サーバー - >クライアントでは機能しないようです。
もう1つの解決策は、Socket.EndReceive
が0バイトを返す場合を処理することです。 「アイドル」時間中に発生する断線の場合には問題ありません。しかし、メッセージ転送中にクライアントが切断された場合、サーバは必ずしもそれを見ず、無期限に待機します。
私はすでにこの問題に関するいくつかのスレッドと質問を見てきましたが、私は決して良い解決策を見たことがありません。
私の質問は:どのような切断の検出に最適な方法は何ですか?ネット。
OK、私のソケットにKeepAliveを有効にするコードを追加しました。しかし、私は今何を期待していますか?クライアントが接続を切断したときに何も起こりません...私は例外をどこかで受け取ることを期待していました...定期的に何かを読んだり書いたりするべきですか? – cedrou
Begin/EndReceiveを使用していましたが?その場合、BeginReceiveはコールバックを実行する必要があります。結果を取得するためにEndReceiveを呼び出すときには、例外が発生するか、ストリームの最後が0バイト読み出されます。 –
OK、今例外が発生しました...ありがとう – cedrou