在很久之前,看到一些面试文章写TCP四次挥手,我还蛮懵逼的,为什么是四次挥手而连接又是三次握手。那时候也没深入去理解下,刚好最近有时间深入学习下,以小白的视角一步步讲解这个知识点。
TCP四次挥手过程状态
- FIN: finish关闭连接
- FIN-WAIT-1:客户端等待服务端收到断开请求状态,这时候客户端过后不会发起请求
- FIN-WAIT-2:客户端等待服务端确认是否完全传输完数据
- CLOSE-WAIT:服务端发送确认收到客户端断开连接后的状态
- TIME-WAIT:客户端等待服务端收到最后请求时的状态,防止请求丢包或者其他网络问题
- LAST-ACK:服务端等待客户端确认收到可以断开连接状态
- CLOSED:断开连接
TCP四次挥手过程
首先,客户端完成请求后,向服务端发起断开连接请求,报文的首部为FIN=1,序列号seq=u, 这时候客户端进入到FIN-WAIT-1的状态,并且这时候客户端不会再发起请求了。
然后,服务端收到客户端发来的断开连接请求,检查了请求的数据后发送报文首部为ACK=1 (一般确认请求报文首部都有ACK)、seq=w、ack=u+1 (这个字段是为了告诉客户端,服务端收到并且确认断开连接请求数据没有错误,所以这个值是报文和序列号值的和),这个时候服务端处于CLOSE-WAIT状态,
服务端处于CLOSE-WAIT状态时,为了防止可能数据没有发完整,或者中途数据丢失的情况,会去确认是否请求的数据发送完毕。
刚好这时候,客户端收到服务端发送确认收到断开连接请求,这时候客户端处于FIN-WAIT-2状态,客户端就等待服务端确认内容发送完毕后告诉它一声。
服务端确认没有数据发送了,这时候就发送确认没有数据的请求FIN = 1、ACK = 1、seq=w、ack=u+1给客户端,这时候服务端处于LAST-ACK状态,客户端收到请求后就发送确认收到服务端没有数据的请求的请求ACK=1、seq=u+1 、ack=w+1,这时候服务端就直接CLOSED断开连接了,然后客户端就等待2MSL(最大报文生存时间),防止因为一些网络原因服务端丢失或者没有接收到客户端发送确认的请求后再断开连接。
TCP连接建立后,客户端突然出现故障后怎么办?
TCP保活计时器:客户端如果出现故障,服务器每收到一次客户端的请求后都会重新复位,保活计时器,时间是2小时 如果2小时没有收到客户端的数据,服务器就会发送一个探测报文段,以后每隔75分钟发送一次,若一连发送10个探测报文仍无反应,服务器就会认为客户端出了故障,就会关闭连接。
总结
简单说就是: 客户端断开连接 -> 服务端收到断开连接,发送收到请求 -> 客户端催促服务端还落下东西吗? -> 服务端没东西发了,发送请求-> 客户端收到确认可以断开请求,并回复收到!->服务端收到回复,直接断开,让客户端等待一下再下线。
为什么TCP断开连接会有四次,而连接才三次呢? 我理解其实TCP连接是为了双方都可以确认接收信息,所以就三次。而四次挥手是为了保证服务端没有东西再传输才多了一次确认。