Как удалить соединение с сокетом ожидания CLOSE


Я написал небольшую программу, которая взаимодействует с сервером по определенному порту. Программа работает нормально, но:

Как только программа неожиданно завершилась, и с тех пор это соединение сокета показано в CLOSE_WAIT государство. Если я пытаюсь запустить программу, она зависает, и я должен заставить ее закрыть, что накапливается даже большеCLOSE_WAIT гнездо подключения.

есть ли способ очистить эти соединения?

4 62

4 ответа:

CLOSE_WAIT означает, что ваша программа все еще работает и не закрыла сокет (и ядро ждет этого). Добавить -p to netstat чтобы получить pid, а затем убить его более сильно (с SIGKILL Если требуется). Это должно избавиться от вашего CLOSE_WAIT розетки. Вы также можете использовать ps чтобы найти pid.

SO_REUSEADDR предназначен для серверов и TIME_WAIT сокеты, поэтому здесь не применяется.

Как рассказала Крист Кларк.

CLOSE_WAIT означает, что локальный конец соединения получил FIN с другого конца, но ОС ждет программу на локальный конец, чтобы фактически закрыть его соединение.

проблема в том, что программа работает на локальном компьютере не закрываем розетку. Это не проблема настройки TCP. Соединение может (и совершенно правильно) оставайтесь в CLOSE_WAIT навсегда, пока программа держит соединение открытым.

Как только локальная программа закрывает сокет, ОС может отправить FIN удаленный конец, который переходит к LAST_ACK, пока вы ждете АК из плавника. Как только это будет получено, соединение будет завершено и падает из таблицы соединений (если ваш конец находится в CLOSE_WAIT вас делай не в конечном итоге в состоянии TIME_WAIT).

хотя слишком много соединений CLOSE_WAIT означает, что что-то не так с вашим кодом в первом, и это принято не очень хорошая практика.

вы можете проверить:https://github.com/rghose/kill-close-wait-connections

то, что делает этот скрипт, - это отправить ACK, которого ожидало соединение.

Это то, что сработало для меня.

у меня также есть такая же проблема с очень последним сервером 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`