0、引言
生产环境中,运行一段时间后,发现经常出现残留着大量的TCP链接,如下图所示,这些残留的TCP链接占用着系统的资源,一旦数量过大的话,会导致系统资源耗尽,甚至崩溃,急需排查解决。
2、TCP/IP的连接和断开过程
2.1 三次握手建立连接
- 第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_SEND状态,等待服务器B确认。
- 第二次握手:服务器B收到SYN包,必须发生一个ACK包,来确认客户A的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器B进入SYN_RECV状态。
- 第三次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,客户端A和服务器B进入ESTABLISHED状态,完成三次握手(注意,主动打开方的最后一个ACK包中可能会携带了它要发送给服务端的数据)。
总结: 三次握手,其实就是主动打开方,发送SYN,表示要建立连接,然后被动打开方对此进行确认,表示可以,然后主动方收到确认之后,对确认进行确认;
2.2 四次挥手断开连接
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭,TCP的双方都要向对方发送一次 FIN 包,并且要对方对次进行确认。根据两次FIN包的发送和确认可以将四次挥手分为两个阶段:
第一阶段: 主要是主动闭方方发生FIN,被动方对它进行确认;
- 第一次挥手:主动关闭方,客户端发送完数据之后,向服务器发送一个FIN(M)数据包,进入 FIN_WAIT1 状态;被动关闭方服务器收到FIN(M)后,进入
CLOSE_WAIT
状态; - 第二次挥手:服务端发生FIN(M)的确认包ACK(M+1),关闭服务器读通道,进入 LAST_ACK 状态;客户端收到ACK(M+1)后,关闭客户端写通道,进入 FIN_WATI2状态;此时客户端仍能通过读通道读取服务器的数据ÿ