在四次握手中,我们有以下内容:
FIN ------->
<------- ACK
<---x--- FIN (what if this packet is lost?)
ACK ------->
如果第三个数据包丢失了,会发生什么情况?它会被重新发送吗?请注意,在发送第三个数据包时,程序可能已经破坏了套接字,因此它无法再发送任何东西!
答案1
简而言之,没有数据包可以保证到达。许多情况都可能导致数据包在传输过程中丢失。TCP 包含重试规则以确保数据到达。
您的场景是半关闭连接。一方关闭连接,并且只能读取数据,直到另一方关闭连接为止。
FIN ------>
<------ ACK
发送FIN包的一方在关闭连接的过程中,会循环切换FIN_WAIT1、FIN_WAIT2、TIME_WAIT状态,接收FIN包的一方会进入CLOSE_WAIT状态,关闭连接时会根据重试规则重发FIN包,直到收到ACK或者超时,在第二次FIN发送之前,连接一直处于半关闭状态。
<------ FIN
ACK ------>
连接可以用 3 个数据包关闭。这些在我看到的协议转储中很常见。在某些情况下,对第一个 FIN 的响应将是 RST(重置),而最后的 ACK 将被替换为 RST。
FIN ------>
<------ FIN,ACK
ACK ------>
在某些情况下,会发送 RST(重置)来代替 ACK,并且最终的 ACK 也被 RST 替换。
FIN ------>
<------ RST
RST ------>
由于网络延迟,两端可能会关闭活动连接。在这种情况下,ACK 数据包可能以任意顺序传送。
<------ FIN
FIN ------>
<------ ACK
ACK ------>
答案2
从RFC 793:
半开连接和其他异常
如果 TCP 之一在另一端不知情的情况下关闭或中止了其一端的连接,或者由于崩溃导致内存丢失,连接的两端变得不同步,则已建立的连接被称为“半开”。如果尝试向任一方向发送数据,此类连接将自动重置。但是,半开连接预计是不常见的,并且恢复过程略有复杂。