LAST_ACK が CLOSE_WAIT に入らないのはなぜですか?

LAST_ACK が CLOSE_WAIT に入らないのはなぜですか?

TCP 接続が接続の一方の端で閉じられると、もう一方の端は を受信しFIN、 で応答しますACK。次に、接続のこの端は 状態になりますCLOSE_WAIT。 がclose()この端で呼び出されると、TCP はFINパケットを送信し、LAST_ACK状態になります。ただし、 状態になることはありませんTIME_WAIT

TCP状態遷移図

ここで、ホスト A がclose()ソケットを呼び出し、FINホスト B にパケットを送信するとしますFIN_WAIT_1。ホスト A は状態に入ります。ホスト B はFINパケットを受信し、を送信してACKからCLOSE_WAIT状態に入ります。ただし、ACK は上流ルーターのどこかでドロップされます。

一方、ホスト B はclose()(ホスト B が 状態にあることを思い出してくださいCLOSE_WAIT) を呼び出し、FINホスト A にパケットを送信しますLAST_ACK。これでホスト B は 状態に入ります。ホスト A はパケットを受信しFIN、 で応答しますACK。その後、CLOSING状態に入ります。

一方、ホスト B はまだ状態にありますLAST_ACK。その後、ACKホスト A からの を受信し、状態に入ります。ホスト B からホスト A への がドロップされ、ホスト A はパケットを再送信していないCLOSEDことを思い出してください。ホスト A はタイムアウト時にパケットを再送信しますが、ホスト B は接続を閉じています。ACKFINFIN

ホスト A は今このCLOSING状態で停止していますか? 接続の切断は続行できますか? 次に何が起きますか?

答え1

私の TCP は少し錆びていますが、次のように動作すると思います:

ホスト B が を呼び出してclose()を送信するとFIN、その のシーケンス番号から、FINホスト A はホスト B からのパケットをFIN受信できなかったことがわかります。そのため、ホスト A はホスト B の を ACK せず、ホスト B から正常に受信した最後の TCP セグメントを ACK し続けます。これにより、ホスト B は不足している を再送信するように促されますACK

したがって、ホスト A は、その前の欠落したデータを受信するまでCLOSING、順序が間違っているデータFINを実際に受信したとは見なさないため、その状態に到達できません。ACK

関連情報