本文目录:
四次挥手
客户端发送完 HTTP 的数据,也正确地获取到服务端的响应。完成了 HTTPS 的请求工作后,接下来要关闭 TCP 连接。关闭 TCP 连接一共分成四步,也可以成为四次挥手。对应包如下:
No. | Time | Source | Destionation | Protocol | Length | Info |
---|---|---|---|---|---|---|
688 | 7.607349 | 172.17.32.211 | 172.17.32.19 | TCP | 66 | 35973 → 8888 [FIN, ACK] Seq=1657 Ack=3213 Win=96512 Len=0 TSval=15986483 TSecr=59355534 |
689 | 7.607363 | 172.17.32.19 | 172.17.32.211 | TCP | 66 | 8888 → 35973 [ACK] Seq=3213 Ack=1658 Win=65024 Len=0 TSval=59355763 TSecr=15986483 |
690 | 7.620494 | 172.17.32.19 | 172.17.32.211 | TCP | 66 | 8888 → 35973 [FIN, ACK] Seq=3213 Ack=1658 Win=65024 Len=0 TSval=59355764 TSecr=15986483 |
697 | 7.661600 | 172.17.32.211 | 172.17.32.19 | TCP | 66 | 35973 → 8888 [ACK] Seq=1658 Ack=3214 Win=96512 Len=0 TSval=15986494 TSecr=59355764 |
可以看到,这四个包都只有 66 个字节。因为不带数据,是纯粹的 TCP 首部。
Round 1
客户端 A 发出 FIN + ACK 包,通知服务端数据传输结束,可以关闭连接了。同样这是一个 ACK 确认包,指出希望的下一个包的序号为 3213。
这个阶段后,客户端进入 FIN_WAIT_1
状态,不再发送数据给服务端,但是如果服务端还在传数据过来,客户端的 ACK 确认报文还会有。
服务端进入 CLOSE_WAIT
状态。这个状态再发出 ACK 确认包后解除。
Round 2
接收端 B 收到第一次挥手的包后,会先给一个 ACK 确认包,为第二次挥手。
这里有个疑问,既然收到了 A 的结束信息,为什么不马上结束呢?因为 A 完成数据传输,但是 B 可能还有数据没有传完,所以比三次握手会多一个步骤。
收到客户端的 FIN 包后,已经知道客户端结束数据传输了,所以服务端后面数据传输结束,就可以直接通知客户端可以结束了。
客户端收到 ACK 确认包后,进入 FIN_WAIT_2
状态。
Round 3
如果服务端数据还没有传完,会继续传给客户端。
等服务端的数据完全传完后,会再发一个 FIN + ACK 包,通知客户端数据传完了。
这个阶段后,服务端进入 LAST_ACK
状态,即等待客户端最后一个 ACK 报文。
Round 4
发送端 A 收到 B 发出的 FIN + ACK 后,进入 TIME_WAIT
状态。服务端收到 FIN 后进入 CLOSED
状态关闭连接。
经过 2MSL 时间,没有问题后会关闭连接。也进入 CLOSED
状态。
为什么有个 TIME_WAIT
?
原因是有可能服务端一直没有收到 FIN + ACK,有可能触发超时重传,又发了一个 FIN 给客户端,客户端要重新发送最后一个包。
小结
TCP 四次挥手的时序图如下: