Linux 如何删除 CLOSE_WAIT 套接字连接
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15912370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I remove a CLOSE_WAIT socket connection
提问by Dilletante
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 moreCLOSE_WAIT
socket connections.
一旦程序意外终止,并且此后套接字连接显示为CLOSE_WAIT
状态。如果我尝试运行一个程序,它会挂起,我必须强制关闭它,这会积累更多的CLOSE_WAIT
套接字连接。
Is there a way to flush these connections?
有没有办法刷新这些连接?
采纳答案by derobert
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
意味着您的程序仍在运行,并且尚未关闭套接字(并且内核正在等待它这样做)。添加-p
到netstat
获取pid,然后更强力地杀死它(SIGKILL
如果需要的话)。那应该摆脱你的CLOSE_WAIT
套接字。您还可以使用ps
来查找 pid。
SO_REUSEADDR
is for servers and TIME_WAIT
sockets, so doesn't apply here.
SO_REUSEADDR
用于服务器和TIME_WAIT
套接字,因此不适用于此处。
回答by Amil Waduwawara
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`
回答by user2618402
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.
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.
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 notend up in the TIME_WAIT state).
CLOSE_WAIT 表示连接的本端已经收到了另一端的 FIN,但是 OS 正在等待本端的程序实际关闭它的连接。
问题是您在本地机器上运行的程序没有关闭套接字。这不是 TCP 调整问题。当程序保持连接打开时,连接可以(并且非常正确)永远保持在 CLOSE_WAIT 状态。
一旦本地程序关闭套接字,操作系统可以将 FIN 发送到远程端,在您等待 FIN 的 ACK 时,远程端将您转换为 LAST_ACK。收到后,连接完成并从连接表中删除(如果您的一端处于 CLOSE_WAIT状态,则您最终不会处于 TIME_WAIT 状态)。
回答by mirage
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-close-wait-connections
What this script does is send out the ACK which the connection was waiting for.
该脚本的作用是发送连接正在等待的 ACK。
This is what worked for me.
这对我有用。
回答by Binita Bharati
It should be mentioned that the Socket
instance in both client and the server end needs to explicitly invoke close()
. If only one of the ends invokes close()
then too, the socket will remain in CLOSE_WAIT state.
需要说明的是Socket
,客户端和服务端的实例都需要显式调用close()
. 如果只有一端也调用close()
,则套接字将保持在 CLOSE_WAIT 状态。
回答by Ian
It is also worth noting that if your program spawns a new process, that process may inherit all your opened handles. Even after your own program closs, those inherited handles can still be alive via the orphaned child process. And they don't necessarily show up quite the same in netstat. But all the same, the socket will hang around in CLOSE_WAIT while this child process is alive.
还值得注意的是,如果您的程序产生一个新进程,该进程可能会继承您打开的所有句柄。即使在您自己的程序关闭之后,那些继承的句柄仍然可以通过孤立的子进程存活。而且它们在 netstat 中的显示不一定完全相同。但同样的,当这个子进程还活着时,套接字将在 CLOSE_WAIT 中徘徊。
I had a case where I was running ADB. ADB itself spawns a server process if its not already running. This inherited all my handles initially, but did not show up as owning any of them when I was investigating (the same was true for both macOS and Windows - not sure about Linux).
我有一个案例,我正在运行 ADB。如果 ADB 尚未运行,它本身会生成一个服务器进程。这最初继承了我的所有句柄,但在我调查时并没有显示为拥有它们中的任何一个(macOS 和 Windows 都是如此 - 不确定 Linux)。
回答by Mustapha Hadid
You can forcibly close sockets with ss
command; the ss
command is a tool used to dump socket statistics and displays information in similar fashion (although simpler and faster) to netstat.
可以通过ss
命令强行关闭套接字;该ss
命令是一个工具,用于转储套接字统计信息并以与 netstat 类似的方式(虽然更简单和更快)显示信息。
To kill any socket in CLOSE_WAIT state, run this (as root)
要终止处于 CLOSE_WAIT 状态的任何套接字,请运行它(以 root 身份)
$ ss --tcp state CLOSE-WAIT --kill