Reputation: 1891
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.
Is there a way to flush these connections?
Upvotes: 120
Views: 459646
Reputation: 631
Even though too many CLOSE_WAIT connections mean that there is something wrong with your code in the first place, there is an option, although it is not accepted as good practice.
You might want to check out: https://github.com/rghose/kill-close-wait-connections
What this script does is send out the ACK which the connection was waiting for.
This is what worked for me.
Upvotes: 10
Reputation: 1824
You can forcibly close sockets with ss
command. The ss
command is a utility that allows you to dump socket statistics and displays information sockets, including network connections. It is similar to the netstat
command, but is generally faster and more efficient.
To forcibly close sockets in the CLOSE_WAIT state using the ss
command, you can use the --tcp
option to specify that you want to view TCP sockets, and the state CLOSE-WAIT
option to specify that you only want to view sockets that are in the CLOSE_WAIT state. For example:
$ ss --tcp state CLOSE-WAIT
This will display a list of all TCP sockets that are in the CLOSE_WAIT state.
To forcibly close these sockets, you can use the --kill
option. This will send a signal to the socket, causing it to be closed. For example:
$ ss --tcp state CLOSE-WAIT --kill
You can also use the --tcp
option to filter the sockets that you want to close based on various criteria. For example, you can use the dport
option to specify a specific port number, or the dst
option to specify a specific destination IP address. For example:
$ ss --tcp state CLOSE-WAIT '( dport = 22 or dst 1.1.1.1 )' --kill
This will forcibly close all TCP sockets in the CLOSE_WAIT state that are connected to port 22 or have a destination IP address of 1.1.1.1.
It is important to note that using the ss
command to forcibly close sockets can have unintended consequences, as it may disrupt ongoing network connections. It is generally a good idea to use this command with caution, and only when it is necessary to do so.
Upvotes: 75
Reputation: 442
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.
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).
Upvotes: 2
Reputation: 5898
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.
Upvotes: 4
Reputation: 487
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 not end up in the TIME_WAIT state).
Upvotes: 47
Reputation: 1642
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.
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).
To change them, you need to edit /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`
Upvotes: 8
Reputation: 51137
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.
SO_REUSEADDR
is for servers and TIME_WAIT
sockets, so doesn't apply here.
Upvotes: 103