4 ウェイ ハンドシェイクでは、次のようになります。
FIN ------->
<------- ACK
<---x--- FIN (what if this packet is lost?)
ACK ------->
3 番目のパケットが失われた場合はどうなるでしょうか。再送信されますか? 3 番目のパケットが送信されるまでに、プログラムはおそらくソケットを破壊しているため、それ以上何も送信できないことに注意してください。
答え1
簡単に答えると、パケットが到着することは保証されていません。さまざまな状況により、パケットが転送中にドロップされたり失われたりする可能性があります。TCP には、データが確実に到着するように再試行ルールが含まれています。
シナリオは半閉じ接続です。一方が接続を閉じ、もう一方が接続を閉じるまでデータを読み取ることしかできません。
FIN ------>
<------ ACK
FIN パケットを送信する側は、接続が閉じられると、FIN_WAIT1、FIN_WAIT2、および TIME_WAIT 状態を循環します。FIN パケットを受信する側は CLOSE_WAIT に入ります。接続を閉じると、ACK を受信するかタイムアウトするまで、再試行ルールに従って FIN パケットを再試行します。2 番目の FIN が送信されるまで、接続は半閉じ状態になります。
<------ FIN
ACK ------>
接続は 3 つのパケットで閉じることができます。これは、私が目にするプロトコル ダンプではよくあることです。場合によっては、最初の FIN への応答が RST (リセット) になり、最後の ACK が RST に置き換えられます。
FIN ------>
<------ FIN,ACK
ACK ------>
場合によっては、ACK の代わりに RST (リセット) が送信され、最後の ACK が RST に置き換えられます。
FIN ------>
<------ RST
RST ------>
ネットワーク遅延により、両端でアクティブな接続が閉じられる可能性があります。この場合、ACK パケットはどちらの順序でも配信される可能性があります。
<------ FIN
FIN ------>
<------ ACK
ACK ------>
答え2
からRFC793 の翻訳:
半開きの接続とその他の異常
確立された接続は、TCP の 1 つが、もう一方の TCP に知られることなく接続を閉じたり中止したりした場合、または接続の両端がクラッシュによってメモリが失われて同期が取れなくなった場合に、「半オープン」状態になります。このような接続は、どちらかの方向にデータを送信しようとすると自動的にリセットされます。ただし、半オープン接続は異常であると予想され、回復手順は多少複雑になります。