本文已参与「新人创作礼」活动,一起开启掘金创作之路。
以下描述不讨论序号和确认号,因为序号和确认号的规则比较简单。并且不讨论 ACK,因为 ACK 在连接建立之后都为 1。
- A 发送连接释放报文,FIN=1,A发送窗口撤销。
- B 收到之后发出确认,B接收窗口撤销,进入 CLOSE-WAIT 状态,此时 TCP 属于半关闭状态,B 能向 A 发送数据但是 A 不能向 B 发送数据。
- 当 B 不再需要连接时,发送连接释放报文,FIN=1。
- A 收到后发出确认,进入 TIME-WAIT 状态,等待 2 MSL(2个最大报文存活时间)后释放连接。
- B 收到 A 的确认后释放连接。
四次挥手的原因(CLOSE-WAIT 状态)
这个状态是为了让服务器端发送还未传送完毕的数据,传送完毕之后,服务器会发送 FIN 连接释放报文。
TIME_WAIT
客户端接收到服务器端的 FIN 报文后进入TIME_WAIT状态,此时并不是直接进入 CLOSED 状态,等待2MSL时间(2个最大报文存活时间)。这么做有两个理由:
- 确保最后一个确认报文能够到达。如果因为某些原因 B 没收到 A 发送来的确认报文,那么就会重新发送FIN连接释放报文,A 在2MSL时间内再次收到FIN,会回重新发送确认。
- 等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文。
- MSL(Maximum Segment Lifetime),指报文在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。
CLOSE_WAIT状态是为了让服务器端发送还未传送完毕的数据。
TIME_WAIT状态就是用来重发可能丢失的ACK报文。
如果第二次挥手时服务器的ACK没有送达客户端,会怎样?
客户端没有收到ACK确认,会重新发送FIN请求。