A机器想要断开连接,则要等自身发送完数据后,传递FIN信号给B机器。B应答ACK,告诉A可以断开,但是要等待B处理完数据,再主动给A发送FIN信号。这时,A出于半关闭状态(FIN_WAIT_2),无法发送新的数据。B做好连接关闭前的准备工作后,发送FIN给A机器,B也进入半关闭状态(CLOSE WAIT)。A发送针对B机器FIN的ACK后,进入TIME-WAIT状态,经过2MSL(Maximum Segment Lifetime)后,没有收到B传来的报文,则约定B已经收到A最后发送的ACK指令,此时TCP连接正式释放。
四次挥手断开连接用通俗的说法可以形象化地这样描述。 男生:我们分手吧。 女生:好的,我的东西收拾完,发信息给你。( 此时男生不能再拥抱女生了。) ( 1 个小时后) 女生:我收拾好了,分手吧。 (此时 , 女生也不能再拥抱男生了。) 男生:好的。 (此时 , 双方约定经过 2 个月的过渡期,双方才可以分别找新的对象。)
在RFC793 中规定 MSL为2分钟。但是在当今网络中,2分钟的等待时间会造成资源的极大浪费,通常会使用更小的值,通过变更/etc/sysctl.conf文件来修改该省略值(秒)
net.ipv4.tcp_fin_timeout=30修改完后,执行
/sbin/sysctl -p让参数生效
可以通过
netstat - n I awk '/<tcp/ {++S[$NF]} END ( for (a 工n S) print a, S[a ]}’查看各连接状态的计数情况。 如果TIME_WAIT状态连接过多,则可以通过优化服务器参数得到解决。如果不是对方连接的异常,一般不会出现连接无法关闭的情况。
如果CLOSE_WAIT过多,则可能是程序自身的问题,比如在对方关闭连接后,程序没有检测到,或者忘记自己关闭连接。