2009-02-25 8 views
1

SO_LINGERソケットオプションを使用して、待ち時間をゼロに意図的に '暗殺'する方法について読んでいました。この本の著者は、これを決して行うべきではないと主張しており、一般的には、時間待機状態を妨げるべきではないと一般的に述べている。その後すぐに、SO_REUSEADDRオプションを使用して時間待機状態をバイパスすることを推奨します。TIME-WAIT暗殺とSO_REUSEADDRの違い

私の質問は何ですか?どちらの場合も、時間切れ状態を早期に終了し、重複セグメントを受け取るリスクがあります。なぜ1つは良い、もう1つは悪いですか?

答えて

1

私はいくつかのより多くの読み取りを行なったし、これが(多分正しい)何が起こるかの私の理解です:

あなたはSO_REUSEADDRセット(またはアプリのクラッシュ)、次の配列を有するソケットに近い呼び出すときに発生します。

  1. TCP送信バッファ内の残りのデータとFINを送信します。
  2. closeが呼び出された場合、残りのデータが正常に配信された場合には、
  3. データが送信された場合、ピアは、データACK
  4. を送信したピアは、FINのACKを送信し、それがピアのFINがACKされ、ソケットリソースの割り当てが解除されている自身のFINパケット
  5. です送信します。
  6. ソケットがTIME-WAITに入っていません。

あなたがゼロに設定SO_LINGER時間でソケットを閉じます。

  1. TCPは
  2. TCPピア
  3. ソケットリソースにRSTパケットを送信し、送信バッファ内のデータを破棄割り当てが解除されます。
  4. ソケットだからゼロにリンガを設定すると、接続のクリーンシャットダウンを経由しないようにも悪いマナーだハックと悪いスタイルであるという事実を超えて

を-WAIT TIMEを入力しません。

+1

これは正しくありません。 'SO_REUSEADDR'は' TIME_WAIT'を防ぎません。すでに使用されているアドレス/ポートの組み合わせに新しいソケットを 'bind()'するだけです( 'listen()'を呼び出す前など)。コメントをするにはあまりにも多くの理由があります。 Stevens、Fenner and Rudoff著 "UNIX Network Programming、第3版"(ISBN 0-13-14115-1)の210〜213ページをお読みください。 – mgd

2

TIME_WAITは絶対に正常です。これは、ローカル側のTCP FINと、リモートロケーションからのTCP FIN ACKの後に発生します。 TIME_WAITでは、迷子パケットがローカルアドレスに到着するのを待っているだけです。しかし、パケットが紛失したり迷子になったりする場合は、TIME_WAITを実行してTTLまたは「存続可能時間」が期限切れになったことを確認してから、再度アドレスを使用してください。

SO_REUSEADDRを使用している場合、基本的には、私は迷子パケットがないと仮定します。現代的で信頼性の高いTCPネットワークがますます普及しています。それはまだ可能ですが、それはありそうもありません。

SO_LINGERをゼロに設定すると、異常終了を開始することがあります。これは、「接続を終了する」とも呼ばれます。ここでは、TIME_WAITを尊重するのではなく、迷子パケットの可能性を無視します。

FIN_WAIT_1が表示されている場合、リモートロケーションがFINに対する応答としてTCP FIN ACKを送信していないため、問題が発生する可能性があります。そのため、プロセスが強制終了されたか、TCP FIN ACKがネットワークパーティションまたは不正なルートによって失われました。

CLOSE_WAITが表示されているときに問題が発生した場合は、TCP FINが指定されているときにTCP FIN ACKを送信していないため、接続がリークしています。

+0

リンガーを使用することは、実際の違いは何ですか?私が言ったように、両方とも時間待機状態を解消する。私が考えることができる唯一のことは、送信バッファ内のデータは、ACKを待つことなく送信されるということです。 –

+0

@ng。 'SO_REUSEADDR'を使うことは、漂遊TCPパケットを無視することを意味しません。通常は、接続(またはTIME_WAITの古い接続)がまだ存在している間に、TCPリスンソケットをポートにバインドするために使用されます。これは、プロセスがリッスンしてから着信接続を処理するために子を生成した後、接続がまだ進行している間に親が終了したり、終了したりする場合です。親を再起動できるようにするには、完全に安全な 'SO_REUSEADDR'が必要です。 Stevens、Fenner and Rudoff著 "UNIX Network Programming、第3版"(ISBN 0-13-14115-1)の210〜213ページをお読みください。 – mgd

0

私はSO_REUSEADDRを使用して、他のプログラムがすでに接続されているローカルポートにbind()をワイルドカードしています。この特定の使用法は、同じaddr/portコンボで同時に2つのソケットがlisten()しようとしない限り、問題を引き起こすことはありません。

関連する問題