1
序列号
FIN
x+1
0
应答号
FIN-WAIT 1
第四次挥手的ACK数据包丢失会发生什么?服务端会重新发送FIN报文,直到达到最大重传次数,如果还未收到第四次挥手的ACK应答报文,服务端会断开连接
y+1
ACK
FIN-WAIT 2
问题:服务器的ACK报文和FIN报文为什么分开发送?服务端收到客户端的FIN报文时,先回复一个ACK应答报文;但应用层可能还有数据正在发送,等所有数据发送完毕后,应用层会调用close(),此时内核才会向客户端发送FIN报文。这里的WAIT就是要等待服务端把数据发完
服务器(被动关闭)
x
CLOSED
(客户端)发送FIN/ACK数据包“我的数据发完了,请求关闭发送通道”
ESTABLISHED
(客户端)发送FIN/ACK数据包“收到FIN,确认关闭”
第三次挥手的FIN数据包丢失会发生什么?服务端会重新发送FIN报文,直到达到最大重传次数,如果还未收到第四次挥手的ACK应答报文,服务端会断开连接
(服务器)再回复一个FIN数据包“我的数据也发完了,请求关闭”
TIME-WAIT
y
客户端(主动关闭)
第一次挥手的FIN数据包丢失会发生什么?客户端会触发超时重传机制,重传FIN报文,重发次数由tcp_orphan_retries参数控制。如果超过重传次数限制,就不会再发送FIN报文,而是等待一段时间还未收到响应报文,直接进入CLOSED状态
关闭连接时,客户端向服务端发送FIN时,仅仅表示客户端不再发送数据了,但还能接收数据。此时的客户端:可以接收数据,但不发数据了
(服务器)回复一个ACK数据包“收到你的FIN,同意关闭”
LAST-ACK
第二次挥手的ACK数据包丢失会发生什么?记住:ACK报文是不会重传的,如果第二次挥手的ACK数据包丢失,客户端会触发超时重传机制,重传FIN报文,直到收到ACK数据包,或达到最大重传次数
主动关闭方为什么会有个TIME-WAIT状态?客户端在发出第四个 ACK 后并没有直接变成 CLOSED,而是进入 TIME_WAIT 停留 2MSL(最长报文寿命,通常 60 秒)。目的是:如果第四个 ACK 丢了,服务端在 LAST_ACK 状态下会超时重发第三个 FIN,客户端必须还活着(在 TIME_WAIT 里)才能重新发送 ACK,帮服务端正常关闭。否则服务端会永远卡在 LAST_ACK 状态。
当客户端收到第二次挥手的ACK数据包后,客户端的状态会转换为Fin-WAIT2状态,此状态是在等待服务器发送第三次挥手的FIN数据包。tcp_fin_timeout控制了这个状态下连接的持续时长,默认为60秒。
CLOSE-WAIT