Как удалить соединение сокетов CLOSE_WAIT
Я написал небольшую программу, которая взаимодействует с сервером на определенном порту. Программа работает нормально, но:
Как только программа завершится неожиданно, и с тех пор, как это соединение сокета отображается в состоянии CLOSE_WAIT
. Если я пытаюсь запустить программу, она зависает, и мне нужно заставить ее закрыть, что еще больше увеличивает сокет CLOSE_WAIT
.
Есть ли способ сбросить эти соединения?
Ответы
Ответ 1
CLOSE_WAIT
означает, что ваша программа все еще запущена и не закрыла сокет (и ядро ждет его для этого). Добавьте -p
в netstat
, чтобы получить pid, а затем убейте его сильнее (при необходимости SIGKILL
). Это должно избавиться от ваших сокетов CLOSE_WAIT
. Вы также можете использовать ps
для поиска pid.
SO_REUSEADDR
для серверов и TIME_WAIT
сокетов, поэтому здесь не применяется.
Ответ 2
Как описано Crist Clark.
CLOSE_WAIT означает, что локальный конец соединения получил FIN с другого конца, но ОС ждет программу на локальный конец, чтобы фактически закрыть его соединение.
Проблема заключается в том, что ваша программа, запущенная на локальной машине, не закрывая сокет. Это не проблема настройки TCP. Соединение может (и вполне корректно) останутся в CLOSE_WAIT навсегда, пока программа открывает соединение.
Как только локальная программа закроет сокет, ОС может отправить FIN удаленный конец, который переводит вас на LAST_ACK, пока вы ждете ACK FIN. Как только это будет получено, соединение будет завершено и удаляется из таблицы соединений (если ваш конец находится в CLOSE_WAIT, вы не попадайте в состояние TIME_WAIT).
Ответ 3
У меня тоже такая же проблема с очень последним сервером Tomcat (7.0.40). Он не реагирует один раз на пару дней.
Чтобы увидеть открытые соединения, вы можете использовать:
sudo netstat -tonp | grep jsvc | grep --regexp="127.0.0.1:443" --regexp="127.0.0.1:80" | grep CLOSE_WAIT
Как указано в этом сообщении, вы можете использовать /proc/sys/net/ipv4/tcp_keepalive_time
для просмотра значений. Значение, по-видимому, находится в секундах и по умолчанию равно 7200 (т.е. 2 часа).
Чтобы изменить их, вам нужно отредактировать /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
Даже если слишком много соединений CLOSE_WAIT означает, что в вашем коде что-то не так, и это принято не очень хорошо.
Вы можете проверить: https://github.com/rghose/kill-close-wait-connections
Что это означает, что script отправляет ACK, который ожидал соединение.
Это то, что сработало для меня.