почему я получаю EADDRINUSE не от bind (), а от listen ()? - PullRequest
2 голосов
/ 15 июля 2011

В приложении C ++ для Linux я вызываю socket (), bind () и listen (), чтобы создать сокет сервера. Обычно, если приложение запускается дважды (с одним и тем же портом сервера), во втором процессе bind () завершится с ошибкой EADDRINUSE. Однако теперь у меня есть случай, когда bind (), по-видимому, успешно завершился, но последующий вызов listen () вызвал ошибку EADDRINUSE ...

Это, вероятно, редкое состояние гонки, но мне все равно было бы интересно, в каких случаях может произойти, если второй bind () завершится успешно, а второй listen () - нет. Кто-нибудь знает больше о таком случае?

Это на 32-битном RHEL 5.3.

Ответы [ 2 ]

3 голосов
/ 16 июля 2011

Не уверен насчет Linux, но в Windows, если при вызове bind() указан подстановочный IP-адрес (INADDR_ANY и т. Д.), Базовая привязка может быть отложена до вызова listen() или connect(), так как ОС имеет больше шансов решить, какой сетевой интерфейс лучше использовать. bind() не сообщит об ошибке в этой ситуации.

1 голос
/ 15 июля 2011

setsockopt(.... SOL_SOCKET, SO_REUSEADDR, ...) должен решить вашу проблему.

См. setsockopt (2) и сокет (7)

(относительно того, почему второй bind на самом деле успешен, понятия не имею ... на самом деле это тоже должно потерпеть неудачу)

...