因为TCP连接是双向的,所以在关闭连接的时候两个方向各自都需要关闭。先发起关闭连接的一方我们称为主动方,与之对应的被动关闭连接的一方我们称为被动方

TCP连接主动关闭端的状态转换:
1、应用层调用close函数发起关闭连接请求;
2、主动方发送FIN给对端,关闭写通道,自己进入FIN_WAIT1状态;
3、主动方等待对端的确认ACK到来,接收到ACK后进入FIN_WAIT2状态,如果在超时时间内没有收到确认ACK则直接进入CLOSED状态;
4、如果在FIN_WAIT1状态等待对端ACK时收到了对端的FIN则进入CLOSING状态(双方都发出了关闭连接请求);
5、在FIN_WAIT2接收到了对端FIN后进入TIME_WAIT状态,如果在超时时间内没有收到这个FIN则直接进入CLOSED状态;
6、在TIME_WAIT状态等待2个MSL(2个报文最长存活时间)后进入CLOSED状态。

TCP连接被动方的状态转换: 1、收到对端FIN后,关闭读通道进入CLOSE_WAIT状态; 2、在CLOSE_WAIT状态等待应用层调用close函数关闭连接; 3、如果在超时时间内调用了close,则进入LAST_ACK状态;否则直接进入CLOSED状态; 4、在LAST_ACK状态发送FIN到对端并等待对端的确认ACK; 5、如果在超时时间内收到了确认ACK则进入CLOSED,否则直接进入CLOSED状态。

注意: 主动端如出现大量的FIN_WAIT1时需要注意网络是否畅通,出现大量的FIN_WAIT2时需要检查程序为何迟迟收不到对端的FIN(可能时主动方或被动方的Bug),出现大量的TIME_WAIT需要注意系统的并发量/socket句柄/内存/端口资源等。
被动方出现大量的CLOSE_WAIT时需要检查为何自己迟迟不愿调用close关闭连接(可能是socket打开用完后没有关闭)。