Разъем застрял в CLOSE_WAIT - PullRequest
       4

Разъем застрял в CLOSE_WAIT

0 голосов
/ 08 декабря 2011

У меня застряли сокеты в close_wait, когда два моих демона общаются друг с другом. Прочитав различные вопросы и записи в блоге на эту тему, я убедился, что закрываю сокет с обеих сторон (отправитель и получатель).

Модель выглядит следующим образом:

Отправитель: установить соединение, отправить данные, дождаться подтверждения, закрыть соединение

Получатель: получить соединение, прочитать данные, отправить подтверждение, закрыть соединение

Может кто-нибудь сказать мне, что я делаю не так? Примечание: я использую close (), чтобы закрыть соединения прямо сейчас. Я тоже пытался использовать shutdown, и это ничего не изменило. Любые советы будут с благодарностью.

EDIT: Вскоре после закрытия сокета, получающий демон разветвляется. Я попытался передать дескриптор файла в функцию, которая разветвляется, и явно закрыть его снова в дочернем процессе, но это не решило мою проблему. Есть ли другой способ, которым разветвление может повлиять на этот процесс? Обратите внимание, что демон-отправитель не разветвляется.

Ответы [ 4 ]

1 голос
/ 09 декабря 2011

Посмотрев в Wireshark, я увидел, что последний FIN_ACK сказал:

"[TCP ACKed потерял сегмент] [TCP предыдущий сегмент потерян] ..."

Оказывается, моя проблема была вызвана тем, что оба демона работали на одной и той же коробке (что мы добавили для тестирования). После повторной попытки использования нескольких ящиков эта проблема больше не возникает.

0 голосов
/ 18 сентября 2017

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

  1. Используйте FD_CLOSEXEC для сокетов.
  2. Используйте setsockopt и установите tcp_keepalive для сокетов.

Код для реализации обоих вышеуказанных решений может немного отличаться на * NIX и Microsoft. Разница только в семантических различиях.

Я бы порекомендовал реализовать обе вышеуказанные меры.

Однако, если вы не можете изменить код, вы можете использовать libkeepalive

0 голосов
/ 08 декабря 2011

По моему (короткому) опыту, вполне возможно, что вы закрываете неправильный fd или даже не достигаете оператора "close" вообще.Я наткнулся на более позднюю версию, и первая подсказка заключалась в том, что мое приложение стало зомби, а не закрылось (в частности, простым printf прямо перед тем, как оператор close заставил все это пойти в ад).проверьте диспетчер задач / рабочие места / системный монитор / <имя какого-либо процесса, относящееся к вашей ОС>.

0 голосов
/ 08 декабря 2011

когда у вас есть приложение, которое открыло сокет и после некоторой отправки получает, оно принимает FIN от своего партнера, после чего оно переходит в состояние CLOSE_WAIT.Он может оставаться в этом состоянии навсегда до тех пор, пока вы явно не вызовете close ().Надеюсь, вы действительно передаете правильный FD в close ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...