大家好,我是前端西瓜哥。今天给大家说说 TCP 的四次挥手。
建立 TCP 连接一段时间后,如果要断开 TCP 连接,就会进行 TCP 四次挥手过程完成断开操作。
TCP 四次的过程有点像 TCP 建立连接的三次握手。
下图为 TCP 头部的结构,我们的 TCP 四次挥手主要用到其中的标黄的部分。
和三次握手的发起者必须是客户端不同,断开 TCP 连接的发起方可以是任何一方。为了方便讲解,下面我们以客户端作为发起者进行描述。
TCP 四次挥手过程
我们先看示意图。
第一次挥手,客户端向服务端发送 TCP 请求,将 TCP 头部中的。
- FIN 设置为 1。
- seq 设置为一个随机数 x。
FIN 是一个标志位,表示结束(finish)的意思,1 等同于 true。
seq 是个序列号,一个装数据的地方,我们这里给他设置为一个随机数,用于给服务端做确认,好对应上这个 TCP 请求。
第二次挥手,服务端发送 TCP,并将 TCP 头部中的。
- ACK 设置为 1(acknowledge,表示 “收到” 的意思)。
- ack 确认号设置为 x+1(x 来自第一次挥手)。
当客户端收到这个 TCP 请求时,表示从客户端到服务端的通道已经关闭,你不能再向服务端发正常的数据请求了。
此时服务端到客户端还是可以发送数据的。如果服务端有一些之前的 TCP 请求没来得及响应,在第二次挥手和第三次挥手期间还是可以去返回的。
第三次挥手,服务端向客户端发送 TCP 请求:
- FIN 设置为 1。
- seq 设置为一个随机数 y。
类似第一次挥手,只是这次发送方为服务端。
第四次挥手,客户端向服务端发送 TCP 请求:
- ACK 设置为 1。
- ack 确认号设置为 y+1。
服务端接收到这个请求后,服务端就能成功变成关闭(CLOSE)状态。客户端则会等一段时间再进入关闭状态,因为第四次挥手不一定能成功发给服务端,所以要等一下,看看服务端会不会因为没收到第四次挥手,而重发第三次挥手。
结尾
和 TCP 三次握手不同。TCP 关闭连接的挥手足足有四次。这是因为第二次挥手和第三次挥手之间可能有一些服务端需要发送的处理比较慢的数据要返回,所以没有将这两次挥手合并。