3

ソケット クライアント プログラムから、リモート接続がダウンしていることを確認するにはどうすればよいですか (たとえば、サーバーがダウンしています)。recv を実行してサーバーがダウンしている場合、タイムアウトを設定しないとサーバーがブロックされます。ただし、私の場合、信頼できるタイムアウト値を設定して回避することはできません。そうしないと、サーバーが稼働していてもrecvがタイムアウトしますが、設定したタイムアウト値よりも応答に時間がかかります。

4

2 に答える 2

3

残念ながら、ZeroMQ はこれを次の層に渡すだけです。したがって、ZeroMQ の上に実装するプロトコルは、これを処理する必要があります。

ハートビートをお勧めします。基本的に、接続がアイドル状態の場合は、一方にメッセージを送信するだけです。反対側は、そのようなメッセージがないことを障害状態として扱い、接続を閉じることができます。

上位レベルのプロトコルを変更して、より堅牢にすることができます。たとえば、コマンドを送信し、そのステータスを照会し、反対側がコマンドを忘れることを許可できます。そうすれば、接続が失われた場合でも、再接続して未処理のコマンドを照会できます。持っていないものは、通過しなかったことがわかっているため、再送信できます。コマンドの結果で応答を取得したら、応答を忘れることができるようになったことを相手に伝えることができます。

これにより、長時間実行されるコマンドが進行中の間、接続をアクティブに保つことができます。「大丈夫ですか?」とよく聞かれます。相手は「はい」と答える。コマンドの処理中に反対側の応答が 1 秒程度遅れるロング ポーリングを使用できます。これにより、次のクエリを待つことなく、すぐに結果を返すことができます。

詳細は正確な要件によって異なりますが、これをプロトコルに正しく設計する必要があります。

于 2013-11-13T12:18:07.467 に答える
0

tcpFINパッケージを送信せずにリモート ホストがダウンした場合、それを検出する機会はありません。そのポートで接続が確立された後、そのポートをファイアウォールで保護することにより、その動作をテストできます。プログラムは永久に「ハング」します。

ただし、Linux カーネルは、TCP キープアライブと呼ばれるメカニズムをサポートしています。これは、特定のタイムアウト後に tcp 接続を閉じることを目的としています。アプリケーションのタイムアウトを指定できない場合は、それを使用する信頼できる機会がありません。最後のチャンスは、アプリケーション プロトコルの機能を使用することかもしれません (名前を付けることができますか?)。そのプロトコルが接続処理の機能をサポートしていない場合は、それに加えて独自に何かを発明することができます。

于 2013-11-13T12:02:56.333 に答える