初始时客户端和服务端都处于ESTABLISHED状态,要断开连接时:
1 客户端先发送一个FIN包,告诉服务端他要断开连接。
2 服务端收到FIN包后,给客户端发送一个确认包ACK,告诉应用程序他要关闭连接了。
3 当应用程序准备好断开后,服务端给客户端发送FIN包。
4 客户端收到服务端发来的FIN包后,给服务端发送ACK确认包。服务端收到之后就关闭连接。
四次握手断开连接状态分析:
1 当服务端收到客户端发来的FIN包后,给客户端发送一个ACK确认包,然后通知应用程序准备关闭,因为应用程序可能还有些数据需要发送给客户端,所以这时服务端是CLOSE_WAIT状态,而不是CLOSED状态。
2 客户端发送FIN包要求断开连接后就进入了FIN-WAIT-1状态,当收到服务端发送的ACK包后就进入到FIN-WAIT-2状态,而在实际情况下FIN-WAIT-1比较难见,因为客户端发送FIN包后服务端会立刻发送ACK包。
3 客户端进入FIN-WAIT-2状态时,表示是半连接,即一方要求关闭连接后,另一方回复说我还有点数据要传输,稍后再关闭,这就是服务端发送ACK之后不立即进入CLOSED状态,而是通知应用程序准备关闭。
4 服务端应用程序准备好之后,内核发送fin给客户端,等待客户端的ack包,服务端进入last_ack状态,这时候客户端收到fin后,发送ack报文给服务端,客户端进入time-wait状态,time-wait等待2msl后进入closed状态,服务端收到客户端发送的ack包之后进入closed状态。
具体过程如下图所示:
Linux内核协议栈提供的影响断开连接的设置项:
1 /proc/sys/net/ipv4/tcp_max_tw_buckets (18000)
该参数设置系统的time_wait的数量,如果超过默认值则会被立即清除。
2 /proc/sys/net/ipv4/tcp_tw_reuse (0 关闭 1 打开)
该参数设置TIME_WAIT重用,可以让处于TIME_WAIT的连接用于新的tcp连接
3 /proc/sys/net/ipv4/tcp_tw_recycle ( 0 关闭 1 打开)
该参数设置tcp连接中TIME_WAIT的快速回收。
4 /proc/sys/net/ipv4/tcp_fin_timeout (60)
设置TIME_WAIT2进入CLOSED的等待时间。