在上一篇的文章中,我们知道了TCP通道的建立需要3次握手,在这一篇的文章中就准备好好聊聊关于TCP通道销毁的过程,即所谓的 四次挥手,开搞!
详解TCP的四次挥手过程
首先先上一个四次挥手的过程图,能让我们有一个整体上的认知
通信双方都可以主动断开连接,这里以 客户端 主动断开为例讲解,主要分为以下几步
- 第一步,此时客户端与服务端都处于 ESTABLISHED 状态,客户端向服务端发送一个TCP首部 FIN 字段为1的报文,即FIN报文,客户端状态变为 FIN_WAIT_1
- 第二步,服务端收到客户端发送的FIN报文后,此为第一次挥手,服务端知道了客户端准备关闭连接,此时会先发送一个 ACK应答报文,告知客户端我已知晓要关闭连接的事情,但此时并不会马上断开连接,因为服务端可能还有 未处理完 的请求,所以会继续保持连接的状态,此时服务端状态变为 CLOSED_WAIT
- 第三步,客户端收到服务端发送的 ACK应答报文 后,此为第二次挥手,状态变为 FIN_WAIT_2
- 第四步,等服务端把所有未处理完的请求处理完毕后,就会发送 FIN报文 给客户端,告知客户端当前连接已经可以关闭了,服务端状态变为 LAST_ACK
- 第五步,客户端收到服务端发送的 FIN报文 后,此为第三次挥手,会给服务端发送 ACK应答报文,状态变为 TIME_WAIT
- 第六步,客户端等待 2MSL,如果期间没有再收到服务端的 FIN报文 后,就会关闭连接,处于 CLOSED 状态
- 第七步,服务端收到 ACK应答报文 后,此为第四次挥手,就会关闭连接,处于 CLOSED 状态,至此整个过程结束
也许你会有疑问:为什么TCP握手需要3次,而挥手却需要四次呢?其实答案很简单,挥手的时候,因为在收到客户端FIN报文时,可以立即应答,但是可能还存在未处理的请求,连接还不能马上关闭,因此需要等到把所有请求处理完成后才能发送FIN报文,告知客户端已经可以关闭连接了,由于ACK和FIN是分开发的,所有挥手的过程会多一次
这里还有一个疑问,就是客户端发送ACK报文后,为什么需要等待2MSL才关闭连接?
首先解释下MSL(Maximum Segment Lifetime)的定义:一段TCP报文在传输过程中的最大生命周期。2MSL 即是服务器端发出FIN报文和客户端发出ACK确认报文所需的 总时间
由于服务端在 1MSL 时间内未收到客户端的 ACK报文 后,会重新发送 FIN报文,因此客户端延迟关闭的这2MSL的时间内,如果没有收到FIN包,就证明服务端已经正确接收到客户端发送的 ACK应答报文,因此就可以关闭连接,而如果在这2MSL时间内收到了服务端的 FIN报文,那么就代表发送的 ACK报文 丢失了,需要重新发送,通过这种延迟2MSL的方式可以完全保证双方都可以安全地关闭连接
结语
关于TCP三次握手和四次挥手的讲解就全部完毕了,这些知识虽然在日常开发中不会直接带来效益,但是会在需要解决疑难杂症时凸显威力,这样就可以跟别人拉开差距,成为一名真正优秀的前端工程师,所以,加油吧,骚年!