如何删除CLOSE_WAIT套接字连接

时间:2021-03-29 23:56:09

I have written a small program that interacts with a server on a specific port. The program works fine, but:

我编写了一个与特定端口上的服务器交互的小程序。这个程序运行得很好,但是:

Once the program terminated unexpectedly, and ever since that socket connection is shown in CLOSE_WAIT state. If I try to run a program it hangs and I have to force it close, which accumulates even more CLOSE_WAIT socket connections.

一旦程序意外终止,并且从此套接字连接显示在CLOSE_WAIT状态。如果我尝试运行一个程序,它就挂起了,我必须将它关闭,这就会积累更多的CLOSE_WAIT套接字连接。

Is there a way to flush these connections?

有办法清除这些联系吗?

4 个解决方案

#1


53  

CLOSE_WAIT means your program is still running, and hasn't closed the socket (and the kernel is waiting for it to do so). Add -p to netstat to get the pid, and then kill it more forcefully (with SIGKILL if needed). That should get rid of your CLOSE_WAIT sockets. You can also use ps to find the pid.

CLOSE_WAIT表示程序仍然在运行,并且没有关闭套接字(内核正在等待它这样做)。在netstat中添加-p,以获得pid,然后更有力地杀死它(如果需要,使用SIGKILL)。这应该可以去掉CLOSE_WAIT套接字。您还可以使用ps查找pid。

SO_REUSEADDR is for servers and TIME_WAIT sockets, so doesn't apply here.

SO_REUSEADDR是用于服务器和TIME_WAIT套接字的,所以这里不适用。

#2


27  

As described by Crist Clark.

正如克里斯特·克拉克所描述的。

CLOSE_WAIT means that the local end of the connection has received a FIN from the other end, but the OS is waiting for the program at the local end to actually close its connection.

CLOSE_WAIT意味着连接的本地端从另一端接收了一个FIN,但是操作系统在本地端等待程序来关闭它的连接。

The problem is your program running on the local machine is not closing the socket. It is not a TCP tuning issue. A connection can (and quite correctly) stay in CLOSE_WAIT forever while the program holds the connection open.

问题是在本地机器上运行的程序没有关闭套接字。这不是TCP调优问题。当程序保持连接打开时,连接可以(非常正确地)永远保持在CLOSE_WAIT中。

Once the local program closes the socket, the OS can send the FIN to the remote end which transitions you to LAST_ACK while you wait for the ACK of the FIN. Once that is received, the connection is finished and drops from the connection table (if your end is in CLOSE_WAIT you do not end up in the TIME_WAIT state).

一旦本地程序关闭套接字,操作系统可以发送远程终端转换你的鳍LAST_ACK当你等待ACK的鳍。一旦收到,连接完成后,滴从连接表(如果你的结束是在CLOSE_WAIT你不最终TIME_WAIT状态)。

#3


5  

I'm also having the same issue with a very latest Tomcat server (7.0.40). It goes non-responsive once for a couple of days.

我对最新的Tomcat服务器(7.0.40)也有同样的问题。它会有几天没有反应。

To see open connections, you may use:

要查看打开的连接,您可以使用:

sudo netstat -tonp | grep jsvc | grep --regexp="127.0.0.1:443" --regexp="127.0.0.1:80" | grep CLOSE_WAIT

As mentioned in this post, you may use /proc/sys/net/ipv4/tcp_keepalive_time to view the values. The value seems to be in seconds and defaults to 7200 (i.e. 2 hours).

如本文所述,您可以使用/proc/sys/net/ipv4/tcp_keepalive_time来查看这些值。值似乎是秒,默认值是7200(即2小时)。

To change them, you need to edit /etc/sysctl.conf.

要更改它们,需要编辑/etc/sysctl.conf。

Open/create `/etc/sysctl.conf`
Add `net.ipv4.tcp_keepalive_time = 120` and save the file
Invoke `sysctl -p /etc/sysctl.conf`
Verify using `cat /proc/sys/net/ipv4/tcp_keepalive_time`

#4


4  

Even though too much of CLOSE_WAIT connections means there is something wrong with your code in the first and this is accepted not good practice.

尽管太多的CLOSE_WAIT连接意味着您的代码在第一次出现了问题,但这并不是一个好的实践。

You might want to check out: https://github.com/rghose/kill-close-wait-connections

您可能需要检查:https://github.com/rghose/kill-wait -connections

What this script does is send out the ACK which the connection was waiting for.

这个脚本所做的就是发送连接正在等待的ACK。

This is what worked for me.

这对我起了作用。

#1


53  

CLOSE_WAIT means your program is still running, and hasn't closed the socket (and the kernel is waiting for it to do so). Add -p to netstat to get the pid, and then kill it more forcefully (with SIGKILL if needed). That should get rid of your CLOSE_WAIT sockets. You can also use ps to find the pid.

CLOSE_WAIT表示程序仍然在运行,并且没有关闭套接字(内核正在等待它这样做)。在netstat中添加-p,以获得pid,然后更有力地杀死它(如果需要,使用SIGKILL)。这应该可以去掉CLOSE_WAIT套接字。您还可以使用ps查找pid。

SO_REUSEADDR is for servers and TIME_WAIT sockets, so doesn't apply here.

SO_REUSEADDR是用于服务器和TIME_WAIT套接字的,所以这里不适用。

#2


27  

As described by Crist Clark.

正如克里斯特·克拉克所描述的。

CLOSE_WAIT means that the local end of the connection has received a FIN from the other end, but the OS is waiting for the program at the local end to actually close its connection.

CLOSE_WAIT意味着连接的本地端从另一端接收了一个FIN,但是操作系统在本地端等待程序来关闭它的连接。

The problem is your program running on the local machine is not closing the socket. It is not a TCP tuning issue. A connection can (and quite correctly) stay in CLOSE_WAIT forever while the program holds the connection open.

问题是在本地机器上运行的程序没有关闭套接字。这不是TCP调优问题。当程序保持连接打开时,连接可以(非常正确地)永远保持在CLOSE_WAIT中。

Once the local program closes the socket, the OS can send the FIN to the remote end which transitions you to LAST_ACK while you wait for the ACK of the FIN. Once that is received, the connection is finished and drops from the connection table (if your end is in CLOSE_WAIT you do not end up in the TIME_WAIT state).

一旦本地程序关闭套接字,操作系统可以发送远程终端转换你的鳍LAST_ACK当你等待ACK的鳍。一旦收到,连接完成后,滴从连接表(如果你的结束是在CLOSE_WAIT你不最终TIME_WAIT状态)。

#3


5  

I'm also having the same issue with a very latest Tomcat server (7.0.40). It goes non-responsive once for a couple of days.

我对最新的Tomcat服务器(7.0.40)也有同样的问题。它会有几天没有反应。

To see open connections, you may use:

要查看打开的连接,您可以使用:

sudo netstat -tonp | grep jsvc | grep --regexp="127.0.0.1:443" --regexp="127.0.0.1:80" | grep CLOSE_WAIT

As mentioned in this post, you may use /proc/sys/net/ipv4/tcp_keepalive_time to view the values. The value seems to be in seconds and defaults to 7200 (i.e. 2 hours).

如本文所述,您可以使用/proc/sys/net/ipv4/tcp_keepalive_time来查看这些值。值似乎是秒,默认值是7200(即2小时)。

To change them, you need to edit /etc/sysctl.conf.

要更改它们,需要编辑/etc/sysctl.conf。

Open/create `/etc/sysctl.conf`
Add `net.ipv4.tcp_keepalive_time = 120` and save the file
Invoke `sysctl -p /etc/sysctl.conf`
Verify using `cat /proc/sys/net/ipv4/tcp_keepalive_time`

#4


4  

Even though too much of CLOSE_WAIT connections means there is something wrong with your code in the first and this is accepted not good practice.

尽管太多的CLOSE_WAIT连接意味着您的代码在第一次出现了问题,但这并不是一个好的实践。

You might want to check out: https://github.com/rghose/kill-close-wait-connections

您可能需要检查:https://github.com/rghose/kill-wait -connections

What this script does is send out the ACK which the connection was waiting for.

这个脚本所做的就是发送连接正在等待的ACK。

This is what worked for me.

这对我起了作用。