当 TCP 连接在连接的一端关闭时 - 另一端会收到FIN
并以 响应ACK
。连接的这一端随后进入 状态CLOSE_WAIT
。一旦close()
在这一端调用 ,TCP 就会发送一个FIN
数据包并进入LAST_ACK
状态。但是,它永远不会进入该TIME_WAIT
状态。
现在,假设主机 A 调用close()
套接字并向FIN
主机 B 发送数据包。主机 A 进入FIN_WAIT_1
状态。主机 B 接收数据FIN
包,发送一个ACK
,然后进入CLOSE_WAIT
状态。但是,ACK 在上游路由器的某个地方被丢弃。
与此同时,主机 B 发出呼叫close()
(回想一下,主机 B 处于 状态CLOSE_WAIT
)FIN
并向主机 A 发送数据包。主机 B 现在进入 状态LAST_ACK
。主机 A 收到FIN
数据包并回复ACK
。然后它进入CLOSING
状态。
在另一端,主机 B 仍处于此LAST_ACK
状态。然后它收到ACK
来自主机 A 的 并进入此CLOSED
状态。回想一下,ACK
从主机 B 到主机 A 的 已被丢弃,并且主机 A 尚未重新发送其FIN
数据包。主机 A 在超时时重新发送其FIN
数据包 - 但主机 B 已关闭连接。
主机 A 现在是否卡在该CLOSING
状态?连接断开还能继续吗?接下来会发生什么?
答案1
我的 TCP 有点生疏,但我相信它的工作原理如下:
当主机 B 调用close()
并发送它的时FIN
, 上的序列号FIN
将向主机 A 显示它错过了来自主机 B 的数据包。因此主机 A 不会确认主机 B 的数据包FIN
,它将继续确认从主机 B 成功接收的最后一个 TCP 段。这将提示主机 B 重新传输丢失的ACK
。
因此主机 A 不会达到该状态,因为它不会认为真正接收到了CLOSING
无序数据,直到它接收到先于它的丢失的数据。FIN
ACK