サーバー側の「TIME_WAIT」は実際にどのように機能しますか?


11

これについてはSEに関する質問がかなりあることは知っていますが、ここまで来る前に重要な質問をたくさん読んだと思います。

「サーバー側TIME_WAIT」とは、サーバー側でclose()が開始されたサーバー側ソケットペアの状態を意味します。

私はしばしば私には矛盾しているように見えるこれらの声明を見ます:

  1. サーバー側TIME_WAITは無害です
  2. クライアントがclose()を開始するようにネットワークアプリを設計する必要があります。したがって、クライアントに TIME_WAIT

私がこの矛盾を見つける理由はTIME_WAIT、クライアント上で問題が発生する可能性があるためです-クライアントは利用可能なポートを使い果たす可能性があるため、本質的には、上記のTIME_WAIT問題は、クライアント側に問題がある可能性がある負荷をそれは問題ではないサーバー側。

クライアント側TIME_WAITはもちろん、限られた数のユースケースでのみ問題になります。ほとんどのクライアントサーバーソリューションには、1台のサーバーと多数のクライアントが関係します。クライアントは通常、問題になるほど十分な量の接続を処理しません。SO_LINGERタイムアウトが0の場合や、tcp_tw sysctlを調整するのとは対照的に)TIME_WAITあまりにも多くの接続を作成しすぎないようにして、クライアント側と戦います。しかし、たとえば次のようなアプリケーションのクラスでは、常に実行可能であるとは限りません。

  • 監視システム
  • 負荷発生器
  • 代理人

反対に、サーバー側TIME_WAITがどのように役立つかさえもわかりません。理由TIME_WAITはそこにもありTCPます。それは、もはや属していないストリームに古いフラグメントを注入することを防ぐためです。クライアント側TIME_WAITではip:port、この古い接続が持つことができたのと同じペアで接続を作成することを単に不可能にすることで達成されます(使用されたペアはによってロックアウトされますTIME_WAIT)。しかし、サーバー側の場合、ローカルアドレスには受け入れポートがあり、常に同じであり、サーバーは(私の知る限り、経験的証明しかありません)接続を拒否できないため、これを防ぐことはできません着信ピアは、ソケットテーブルにすでに存在する同じアドレスペアを作成します。

サーバー側のTIME-WAITが無視されることを示すプログラムを作成しました。さらに、テストは127.0.0.1で行われたため、カーネルには、サーバー側かクライアント側かを示す特別なビットが必要です(そうでなければ、タプルは同じになるため)。

ソース:http : //pastebin.com/5PWjkjEf、Fedora 22でテスト、デフォルトのネット設定。

$ gcc -o rtest rtest.c -lpthread
$ ./rtest 44400 s # will do server-side close
Will initiate server close
... iterates ~20 times successfully
^C
$ ss -a|grep 44400
tcp    TIME-WAIT  0      0            127.0.0.1:44400         127.0.0.1:44401   
$ ./rtest 44500 c # will do client-side close
Will initiate client close
... runs once and then
connecting...
connect: Cannot assign requested address

したがって、サーバー側TIME_WAITでは、まったく同じポートペアでの接続をすぐに正常に再確立でき、クライアント側TIME-WAITでは、2回目の反復でconnect()正しく失敗しました

要約すると、問題は2つあります。

  • サーバー側はTIME_WAIT実際には何もしませんRFCか?
  • サーバーTIME_WAITが役に立たないため、クライアントがclose()を開始することが推奨されているのはなぜですか?

クライアントが1つしかない場合を除き、ポートが不足することはありません。クライアント/サーバーIPの組み合わせごとに65535個のポートがあります。1.2.3.4:1111からの接続は4.3.2.1:1111とは異なります。の接続ごとに数バイトのメモリが必要TIME_WAITです。
Marki555

回答:


1

ではTCPの用語ここでは、サーバー側がLISTEN状態でソケットを持っているホストを意味します。

RFC1122では、TIME-WAIT状態のソケットがいくつかの条件で新しい接続を受け入れることができます

        When a connection is closed actively, it MUST linger in
        TIME-WAIT state for a time 2xMSL (Maximum Segment Lifetime).
        However, it MAY accept a new SYN from the remote TCP to
        reopen the connection directly from TIME-WAIT state, if it:

条件の詳細については、RFC1122を参照してください。また、ソケット(LISTEN状態のソケット)に一致するパッシブOPENがなければならないことを期待しています。

アクティブOPEN(クライアント側接続呼び出し)にはこのような例外はなく、RFC793に従って、ソケットがTIME-WAITにあるときにエラーを発生させる必要があります。

クライアント(TCPの用語でアクティブなOPEN、つまり接続を実行するホスト)で開始されたクローズに関する推奨事項は、一般的なケースでは、リソースが豊富なホストでTIME-WAITソケットを広げることとほぼ同じですソケット。一般的なケースでは、クライアントはサーバー上のTIME-WAITソケットを再利用するSYNを送信しません。このような推奨事項を適用するかどうかは、ユースケースに依存することに同意します。


0

これはおそらく、TIME-WAITが実際に行うことの最も明確な例であり、より重要なのはなぜそれが重要なのかです。また、TIME-WAITを「削減」するために、Linuxマシンでの「専門家」のヒントのいくつかを避ける理由についても説明します。


それでもクライアント- >サーバー接続が開始され、サーバーがそのペアがTIME_WAITにロックアウトされたときに何が起こるかを説明していません
パヴェルVeselov

stackoverflow.com/questions/1490196/…をご覧ください-答えはあなたが探しているものです。
Khushil

0

tcpセッションは、タプル(sourceIP、sourcePort、destIP、destPort)によって識別されます。したがって、TIME_WAITはすべてのTCP接続で機能します。

クローズ側に関して、いくつかのシナリオでは、クライアント側からクローズすると、サーバー上のTIME_WAITソケットが減少し、メモリがわずかに減少します。(一時的なポートの枯渇により)ソケットスペースが使い果たされる可能性がある場合(たとえば、同じサーバーへの接続が多い貪欲なクライアント)、この問題はいずれの側でも解決する必要があります。


説明してください; サーバー側のTWが何かを行うかどうかを尋ねると、TW期間中に同じ接続を再利用できるかどうか疑問に思います。タプルで定義された接続がサーバーのtcpテーブルで行われるため、答えはノーです。クライアントが同じ接続をすぐに開こうとすると、RSTを受信し、事実上tcp接続を拒否します。ところで、Khushilの記事は非常に説明的です。
バソ

ごめんなさい、あなたの答えは実際に質問に答えているので、間違って読んだのでコメントを撤回しました。ただし、サーバー側からの保護がないことを証明するコードがあるため、これも間違っているようですTIME_WAIT(この情報で質問を更新しました)。@Khushilのリファレンスは、サーバー側のTIME_WAITケースを十分に詳しくカバーしていません。
パヴェルヴェセロフ

-2

信頼できないプロトコルでは、ピアデバイスから最後のメッセージを受信したことを決して確信できないため、ピアが電話を突然切ったと想定するのは危険です。TCPプロトコルの大きな欠点は、同時に開くことができるのは65000程度のポートだけであることです。ただし、これを克服する方法は、サーバーファームに移行することです。サーバーファームは、ポート番号を迅速にリサイクルするよりも、負荷に応じて拡張性が高くなります。クライアント側では、基本的なワークステーションの場合、ポートが不足する可能性はほとんどありません。


大変申し訳ありませんが、これは私の質問に答えません。
パヴェルヴェセロフ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.