Four socket wave (the CLOSE_WAIT and a TIME_WAIT state and process description)

Description of the problem:

Recently websocket service program after binding certain fixed port fails, use statnet -noa view found that a large number of state and port TIME_WAIT state CLOSE_WAIT system residues. Leading to the situation at bind listening port, socket failure.

CLOSE_WAIT

2 to explain the principles of

We know that in socket programming, TCP connection and disconnection of the following three handshakes and four waving process. Here four times and waved emphatically say. When the server / client program automatically call closesocket port, take the initiative to disconnect the party will send a signal to the passive side FIN, FIN signal is received after the passive side, entered the CLOSE_WAIT state. If all goes well, the passive side needs to send FIN packet again later, and then moved to LAST_ACK state; the active side after FIN packet is received, an ACK signal to reply, and the state becomes a TIME_WAIT state and waits twice MSL period, the state variable CLOSED state; OFF when the passive side receives the ACK signal, state to the CLOSED state.

Four wave interaction diagram and call the function

Above theory, it was described in detail in many articles, personal feeling https://www.cnblogs.com/kevingrace/p/9988354.html good article describes. The reason, TCP end to be designed so complicated, in fact and circumstances of daily phone calls is the same; before to hang up, first ask whether the other side there are other things, the absence of other things, the ability to make Barbara hang up action.

Implementation code in the attachment,

wireshark taken exchange procedure below

Disconnect normal interaction

However, we recv () == 0 case, the code comments after closesocket, the port side of the passive disconnected state will CLOSE_WAIT nominal state, which led to the program can not be released. Can say that this is an abnormal state, such as encounter this situation, we must take to get rid of this bug. The following figure shows the interaction in this case

被动方在收到FIN后,没有调用closesocket的情况下,双方的交互

这种情况下,我们可以清楚看到被动方的端口变为CLOSE_WAIT状态,而且此状态在进程退出之前会一直存在,不能释放。主动方在经过2MSL后,在上图中,是被动在回复FIN的ACK后,120秒后,向被动方发送了RST复位的信号,最后变为CLOSED的状态。

出现CLOSE_WAIT的端口

 

 

3 解决问题:

从上图可以看出,TIME_WAIT的状态是正常状态。如果,发现程序中过多,最简单的方法可以通过设置回收TIME_WAIT端口周期来实现。WINDOWS可以通过设置HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters, 添加名为TcpTimedWaitDelay的DWORD键,设置为30或更短,以缩短TIME_WAIT的等待时间,需要重启电脑。能很明显的看到TcpTimedWaitDelay值影响TIME_WAIT端口数量变多或变少,大家可以自行进行测试。

CLOSE_WAIT状态的端口,一定是程序出问题,也就是说被动断开方,没有在合适的时刻去调用closesocket函数,导致被动断开方一直处于此种状态,而不能释放端口资源。本人大量的CLOSE_WAIT端口的问题,PID是百度云盘导致的。

发布了40 篇原创文章 · 获赞 17 · 访问量 12万+

Guess you like

Origin blog.csdn.net/rendawei636/article/details/104543001