53

TCP ソケットを開き、ネットワーク上の別の場所にある別のソケットに接続します。その後、データを正常に送受信できます。毎秒ソケットに何かを送信するタイマーがあります。

次に、接続を強制的に切断する (この場合はイーサネット ケーブルを引き抜く) ことで、無作法に接続を中断します。私のソケットは、毎秒データを正常に書き込んでいるとまだ報告しています。これが約 1 時間 30 分続き、最終的に書き込みエラーが発生します。

ソケットが最終的にもう一方の端を受け入れるこのタイムアウトを指定するものは何ですか? OS (Ubuntu 11.04) によるものですか、TCP/IP 仕様によるものですか、それともソケット構成オプションによるものですか?

4

2 に答える 2

79

ネットワーク ケーブルを引っ張っても、TCP 接続 (1) は切断されませんが、通信は中断されます。ケーブルを再び接続すると、IP 接続が確立されると、すべてのバックデータが移動します。これが、セルラー ネットワークでも TCP の信頼性を高めている理由です。

TCP がデータを送信するとき、応答として ACK が期待されます。一定時間内に何も来ない場合、データを再送信して再び待機します。通常、送信間の待機時間は指数関数的に増加します。

一定回数の再送信または ACK なしの合計時間の後、TCP は接続が「切断された」と見なします。OS とその構成によって回数または時間は異なりますが、通常は数分程度でタイムアウトします。

Linux のtcp.7 man ページから:

   tcp_retries2 (integer; default: 15; since Linux 2.2)
          The maximum number of times a TCP packet is retransmitted in
          established state before giving up.  The default value is 15, which
          corresponds to a duration of approximately between 13 to 30 minutes,
          depending on the retransmission timeout.  The RFC 1122 specified
          minimum limit of 100 seconds is typically deemed too short.

これは、接続が失われたかどうかを検出するのにかかる時間を変更するために調整する必要がある値です。

(1) これには例外があります。オペレーティング システムは、ケーブルが取り外されたことに気付くと、すべての接続が「切断」されていると見なす必要があることを上位層に通知できます。

于 2012-10-26T12:59:40.843 に答える
1

アプリケーションコードへのソケットエラーの迅速な伝播が必要な場合は、次のソケットオプションを試してみてください。

TCP_USER_TIMEOUT (Linux 2.6.37 以降) このオプションは引数としてunsigned intを取ります。値が 0 より大きい場合、 TCP が対応する接続​​を強制的に閉じてETIMEDOUTをアプリケーションに返す前に、送信されたデータが未確認のままになる最大時間をミリ秒単位で指定します。オプション値を 0 に指定すると、TCP はシステムのデフォルトを使用します。

linux/man/tcp(7) の完全な説明を参照してください。このオプションは、 tcp_retries2編集よりも柔軟性が高く (ソケットの作成直後にオンザフライで設定できます)、クライアントのソケットがサーバーの 1 つの状態を認識せず、いわゆるハーフ状態になる可能性がある状況に正確に適用されます。閉じた状態。

于 2019-12-10T13:45:07.827 に答える