当客户端和服务器通过三次握手建立了TCP连接以后,当数据传送完毕,肯定是要断开TCP连接的。那对于TCP的断开连接,就有了四次挥手(TCP Four-way Wavehand)。
四次挥手(TCP Four-way Wavehand)
由于TCP连接是全双工的,因此每个方向的连接必须单独地进行关闭,于是TCP连接的断开需要进行“四次挥手”(两端分别进行FIN+ACK和ACK两次挥手)。
TCP连接断开的过程:
- 客户端发起请求,向服务端发送一个FIN报文段(其中Seq = x, Ack = l),用来关闭从客户端到服务端的传输。客户端的状态变为FIN_WAIT_1状态。此时客户端仍然可以接收数据。如果这之前发出的数据中存在没有ACK的,客户端仍然会重发这些数据。
- 服务端收到客户端的FIN包,然后向客户端发回一个ACK报文段(Ack = x + 1, Seq = l)作为确认,此后服务端进入CLOSE_WAIT状态。
- 同时,服务端向客户端发送一个FIN报文段(Seq = l, Ack = x + 1),用来关闭从服务端到客户端的传输,此后服务端的状态变为LAST_ACK。
- 客户端收到服务端发送的FIN报文段后,进入TIME_WAIT状态,然后向服务端发回一个ACK包(Ack = l + 1, Seq = x + 1)作为确认。服务端收到后,Server进入CLOSED状态。最终四次挥手结束,连接断开(CLOSE)。
注意:TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSED状态,原因:
- TIME_WAIT确保有足够的时间让对端收到了ACK(如果被动关闭的那方没有收到ACK,就会触发被动端重发FIN,一来一去正好2个MSL)
- 有足够的时间让这个连接不会跟后面的连接混在一起(部分路由器会缓存数据包导致连接重用)
以下为动画演示四次挥手的交互过程:
四次握手时的状态变化
为什么要四次挥手
TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工模式,这就意味着:
- 当主机1向主机2发出FIN报文段时,只是表示主机1已经没有数据要发送了,即主机1告诉主机2,它的数据已经全部发送完毕了;
- 但是,这个时候主机1还是可以接受来自主机2的数据;当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2仍然还是可以发送数据到主机1的;
- 当主机2也发送了FIN报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。
Wireshake抓包学习TCP 四次挥手
可以增加tcp && tcp.flags.fin == 1
过滤条件,可以让我们找到两条FIN报文段。去掉过滤条件,并找到这两条FIN报文段对应的ACK报文段。
一个完整的四次挥手过程如下所示:
分析
#6939
Client -> Server
[FIN, ACK]
Sequence number 196
Acknowledgement number: 1689
#6941
Server -> Client
[ACK]
Sequence number 1689
Acknowledgement number: 197
#6942
Server -> Client
[FIN, ACK]
Sequence number 1689
Acknowledgement number: 197
#6951
Client -> Server
[ACK]
Sequence number 197
Acknowledgement number: 1690
Reference
FEATURED TAGS
algorithm
algorithmproblem
architecturalpattern
architecture
aws
blockchain
c#
cachesystem
codis
compile
concurrentcontrol
database
dataformat
datastructure
debug
design
designpattern
distributedsystem
django
docker
domain
engineering
freebsd
git
golang
grafana
hackintosh
hadoop
hardware
hexo
http
hugo
ios
iot
java
javaee
javascript
kafka
kubernetes
linux
linuxcommand
linuxio
lock
macos
markdown
microservices
mysql
nas
network
networkprogramming
nginx
node.js
npm
oop
openwrt
operatingsystem
padavan
performance
programming
prometheus
protobuf
python
redis
router
security
shell
software testing
spring
sql
systemdesign
truenas
ubuntu
vmware
vpn
windows
wmware
wordpress
xml
zookeeper