FIN_WAIT2について



About Fin_wait2



ウォームアップして、TCPが古い画像を介して接続を閉じたときの状況を思い出してみましょう。

TCPクローズ



TCPクローズ

通常の状態の移行パスによれば、FIN_WAIT2がFINパケットを受信すると、TIME_WAIT状態に移行します。 FINパッケージを受け取っていない場合、接続状態はどのように移行するのでしょうか。テストすることをお勧めします。



#!/usr/bin/env python import socket import time s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('127.0.0.1', 1234)) s.listen(1) c, _ = s.accept() time.sleep(1000) c.close()

上記のように使用します Python 実装された単純なサーバーデモコード。サーバーがFINパケットを送信するのを遅らせるために、閉じる前に大きな遅延を設定したことに注意してください。これに対応して、単純なクライアントデモコードを実装します。言うまでもなく、接続後に直接閉じられます。

#!/usr/bin/env python import socket import time s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', 1234)) s.close()

テストするときは、サーバーを起動してポート1234でリッスンし、クライアントを起動してポート1234に接続します。プロセス全体が期待を満たしているかどうかを確認するために、tcpdumpを使用して通信プロセスを監視できます。

tcpdump -t -nn-i任意のポート1234



tcpdump -t -nn-i任意のポート1234

図に示すように、3ウェイハンドシェイクの後、クライアントは接続を閉じ、サーバーは確認後にFINパケットを送信しなかったため、プロセス全体が私たちの期待に沿っており、どのくらいの期間かを判断するためでした。 FIN_WAIT2が存在し、次のコードが記述されました。

#!/usr/bin/env python import socket import time s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', 1234)) s.shutdown(socket.SHUT_WR) time.sleep(1000) s.close()

監視により、この場合、FIN_WAIT2が約1分間存在することがわかりました。

FIN_WAIT2

FIN_WAIT2が存在する期間

実際、この時間は「net.ipv4.tcp_fin_timeout」によって制御されますが、FIN_WAIT2が存在する時間は、tcp_fin_timeoutの設定と正確に等しくないことがテストで判明し、一定の偏差があります。さらに、tcp_fin_timeoutの後、FIN_WAIT2はTIME_WAITに移行されず、直接閉じられることに注意してください。

tcp_fin_timeoutの概要については、カーネルの説明を参照してください。

孤立した(アプリケーションによって参照されなくなった)接続が、ローカルエンドで中止される前にFIN_WAIT_2状態のままになる時間の長さ。孤立していない接続に対しては完全に有効な「受信専用」状態ですが、FIN_WAIT_2状態の孤立した接続は、リモートが接続の終了を閉じるまで永久に待機する可能性があります。
Cf. tcp_max_orphans
デフォルト:60秒

孤立の概念は導入部で言及されています。つまり、ソケットがアプリケーションによって参照されなくなると、孤立になり、tcp_fin_timeoutは、孤立したFIN_WAIT2が存続できる時間を制限します。

注:孤児が多すぎると、次のようになります。 「ソケットメモリ不足」エラー

一部の人々は尋ねるかもしれません:FIN_WAIT2が孤立していない場合はどうなりますか?

|_+_|

このバージョンのクライアントコードでは、接続を直接閉じるのではなく、シャットダウンして閉じます。このとき、クライアントもFINパケットを送信しますが、接続は解放されないため、この例のFIN_WAIT2と前の例のFIN_WAIT2は異なり、孤立しません。テストの結果、この時点ではtcp_fin_timeoutが無効であり、この場合のFIN_WAIT2は、クライアントが接続を閉じるか終了するまで常に存在することがわかりました。

実際、他のTCP状態と比較すると、通常、FIN_WAIT2はそれほど問題を引き起こしません。サーバーのTCPステータスを数えると、それらのほとんどが非常に少ないことがわかります。そうでない場合は、アプリケーションレベルで問題があるはずです。 tcp_fin_timeoutについては、小さすぎる設定はお勧めしません。前述のように、通常の状況では、FINパケット損失などが実際に発生すると仮定すると、TCP接続がFIN_WAIT2状態に長時間留まらないためです。 FIN_WAIT2状態に妥当なライフサイクルを与える必要があります。結局のところ、失われたFINパケットは再送信される可能性があります。この時点で、TIME_WAITが2MSLに存在するのと同じ理由です。 TIME_WAITはデフォルトで60秒間存在するため、tcp_fin_timeoutのデフォルト設定である60も妥当な選択です。