上一篇剖析了TCP三次握手过程,这次看下TCP四次挥手过程,相关内核代码和TCP三次握手有重复地方,所以会粗略截图。
先看下tcp四次挥手抓包情况:
从抓包可以看出:
172...9首先向172...10发送FIN+ACK包(以下简称9和10)
1、9给10回一个FIN+ACK报文
2、10给9回一个ACK报文
3、10给9又回一个FIN+ACK报文
4、9给10回一个ACK报文
9首先调用close,通过系统调用
接着调用__close_fd,获取访问锁,释放文件描述符,释放访问锁,然后调用flip_close
__put_ununsed_fd功能主要是根据待回收的fd确定下一个待分配的fd
接下来看下fput的调用
接下来看下sock_close的定义
其中sock->ops->release最终调用的是net/ipv4/af_inet.cd的 inet_release
调用tcp_send_fin之后,紧接着就进入了TCP四次挥手的第一次挥手阶段:
以上是第一次挥手过程,即9向10发送fin包。
接下来是第二次挥手:
接着等待另一方回应,从上一篇三次握手可以知道,处理TCP不同状态码的函数为net/ipv4/tcp_input.c中的tcp_rcv_state_process,现在主要是等待对方对fin的ack,让套接字进入fin_wait2状态
这时,10收到fin报文,同样是tcp_rcv_state_process处理,根据状态(现在是连接建立ESTABLISHED)调用tcp_data_queue进入close_wait状态
该函数将套接字状态切换为close_wait,即10状态为close_wait,然后等待新数据发送ack
第三次挥手:
10也调用close,状态由close_wait变为last_ack
第四次挥手:
9收到fin报文后,回复ack,并进入time_wait 10收到ack后,进入closed状态,回收资源
至此,TCP四次挥手完成。
总结一下: