12

クライアントがサーバーへの TCP ソケットを開くクライアント サーバーの状況があり、それらの間でデータが送信されずに長い時間が経過することがあります。サーバーがクライアントにデータを送信しようとして成功したように見えますが、クライアントはそれを受信せず、数分後にクライアントが切断されたように見えるという問題が発生しました。

時々何らかのキープアライブ パケットを送信する必要がありますか?

編集:注意してください、これは同じコンピューター上のピアとの関係です。コンピューターは、このコンピューターに使用されるポートの範囲を転送する NAT の背後にあります。サーバーに接続するクライアントは、DNS 経由で接続を開きます。つまり、mydomain.net とポートを使用して接続します。

4

4 に答える 4

9

Windows では、データが送信されないソケットは、多くのアプリケーションでトラブルの大きな原因となるため、正しく処理する必要があります。

問題は、SO_KEEPALIVE の期間がシステム全体 (そうでない場合、デフォルトは役に立たない 2 時間) または後の winsock API で設定できることです。

したがって、多くのアプリケーションは、ACK が受信されなかった後 (レイヤーと ack タイムアウトによってすべての再送信が行われた後) に、ネットワーク層に切断を宣言させるためだけに、ときどきデータのバイトを送信します (ピアによって無視されます)。

あなたの質問への回答: いいえ、ソケットは自動的に切断されません。

ただし、上記の問題には注意が必要です。さらに複雑なのは、この動作のテストが非常に難しいことです。たとえば、すべてを正しく設定し、切断を適切に検出することを期待している場合、物理層を切断してテストすることはできません。これは、NIC がキャリア損失を感知し、ソケット レイヤーがそれに依存するすべてのアプリケーション ソケットを閉じるように信号を送るためです。それをテストする良い方法は、2 台のコンピューターを 3 つのレッグと 2 つのスイッチの間に接続し、中間のレッグを切断して、キャリアの損失を防ぎながらマシンを物理的に切断することです。

于 2012-07-30T00:42:50.013 に答える
0

TCP にはタイムアウトが組み込まれていますが、それを調整することができます。Socket クラスSendTimeoutを参照しReciveTimeoutてください。NAT ルーターには、ポート転送テーブルから削除する前に、TCP 接続の有効期限がある場合もあります。ルーターでそのタイムアウト時間内にトラフィックが通過しない場合、すべての着信トラフィックがブロックされます (転送情報がメモリから消去されるため、トラフィックの送信先のコンピューターがわからないため)。送信元ポートが異なるため、サーバーはそれを同じ接続として認識しない場合があります。

于 2012-07-29T19:54:52.367 に答える
0

キープアライブ オプション ( Linux では SO_KEEPALIVE ) を使用して非アクティブによる切断を防ぐ方が安全ですが、余分なパケットが生成される場合があります。

このサンプル コードは、Linux で実行します。

int val = 1;
....
// After creating the socket
if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&val, sizeof(val)))                   
    fprintf(stderr, "setsockopt failure : %d", errno);

よろしく。

于 2012-07-30T00:45:21.937 に答える
-1

TCP ソケットは自動的に閉じません。ただし、TCP接続は可能です。ただし、これが同じコンピューター内のピア間で発生している場合、両方のピアが存在し、ソケットが開いている限り、接続が切断されることはありません。

于 2012-07-30T00:33:14.687 に答える