TCPは信頼性のあるコネクション指向型のプロトコルです。TCPはデータ転送が行われる前に、コネクションを確立し、データ転送後はコネクションをクローズします。
例えば、netstatコマンドでTCPセッションが今どのような状態(state) であるかわかります。
netstatの出力例 Active Internet connections Proto Recv-Q Send-Q Local Address Foreign Address (state) tcp4 0 0 192.168.3.5.53254 server-143-204-8.https SYN_SENT tcp4 0 517 192.168.3.5.53253 server-143-204-8.https ESTABLISHED tcp4 0 596 192.168.3.5.53252 nrt20s20-in-f2.1.https ESTABLISHED tcp4 0 0 192.168.3.5.53189 23.96.112.38.https FIN_WAIT_1 tcp4 0 517 192.168.3.5.53250 182.22.24.124.https ESTABLISHED tcp4 31 0 192.168.3.5.52276 162.125.80.17.https CLOSE_WAIT tcp4 0 0 192.168.3.5.53195 23.96.112.38.https TIME_WAIT
TCP接続でトラブルシューティングする場合、TCPの状態の理解が必要な場面があります。
全体の流れは以下の通りです。一つずつ見ていきます。
![](https://hirotanoblog.com/wp-content/uploads/2020/07/8C3A4332-A40E-4ECF-A721-BE7A4B757ADD.png)
SYN-SENT状態
サーバはTCP待ち受け状態(LISTEN)であるとします。クライアントは、アプリケーション(ソケット)からの接続要求に対して、TCPはサーバにSYNを送信し、SYN-Sent状態に移行します。
![](https://hirotanoblog.com/wp-content/uploads/2020/07/ACBCFE98-6F39-450D-BFCD-8C3AD8BFA9EB.png)
SYN-RECV状態
サーバはクライアントのSYNを受信したので、SYN+ACKをクライアントに送り返し、SYN-RECV状態に移行します。このようなクライアント、サーバの状態をハーフオープンと呼ばれることもあります。
![](https://hirotanoblog.com/wp-content/uploads/2020/07/D7865AD1-FC15-4C13-A647-76F9E28D1988.png)
Established状態
クライアントは、サーバからSYN + ACKを受信し、ACKをサーバへ送り返すと、Established状態になります。サーバはクライアントからのACKを受信するとEstablished状態になります。これで、データを双方向に送受信する準備ができました。
![](https://hirotanoblog.com/wp-content/uploads/2020/07/15CE0083-A10A-441A-8CB5-EC528186B60C.png)
データ送受信
クライアント、サーバ間でデータが送受信されます。
![](https://hirotanoblog.com/wp-content/uploads/2020/07/7620970F-93C0-4D0A-B787-70E8A18B4CA0.png)
FIN-WAIT1状態
クライアント側で送信するデータがなくなった場合、サーバへFINを送信し、FIN-WAIT1状態になります。
![](https://hirotanoblog.com/wp-content/uploads/2020/07/732865C0-C5CF-4780-9DE7-0CB8EE6E0158.png)
CLOSE-WAIT状態
クライアントからのFINを受信し、クライアントにACKを送信した後、CLOSE-WAIT状態に推移します。このようなクライアント、サーバの状態をハーフクローズと呼ばれることもあります。
![](https://hirotanoblog.com/wp-content/uploads/2020/07/22C3AAD7-B39A-4C5E-964A-855D036D5F41.png)
FIN-WAIT2状態
サーバから送信されたACKを受信すると、クライアントはFIN-WAIT-2状態に遷移します。
![](https://hirotanoblog.com/wp-content/uploads/2020/07/DFB7D9D0-0DF3-4E45-8F1A-72557EC9AB30.png)
LAST-ACK状態
サーバはFINを送信し、LAST-ACKに移行します。それは、それに対するACKを受信するまでこの状態になり、ACKを受信するとCLOSED状態に遷移します。
![](https://hirotanoblog.com/wp-content/uploads/2020/07/F42453BE-4DF9-44D7-8527-1C53B92C0E36.png)
TIME-WAIT状態
クライアントは、サーバからFINを受信し、応答としてACKを送信すると、TIME-WAIT状態になります。RFC793では、Maximum Segment Lifetime (MSL:最大セグメント生存時間)を2分とし、TIME-WAITの待機時間はMSLの2倍としています。TIME-WAITの待機時間経過後、CLOSED状態になります。
参考までにWindows2016では、以下のサイトの通り、既定で4分のようで、RFCに準拠しているようです。
![](https://hirotanoblog.com/wp-content/uploads/cocoon-resources/blog-card-cache/62becbf9e66edbd7a674a2191e28faef.png)
![](https://hirotanoblog.com/wp-content/uploads/2020/07/8C3A4332-A40E-4ECF-A721-BE7A4B757ADD-1.png)
コメント