Адрес уже используется с Boost Asio Acceptor - PullRequest
10 голосов
/ 16 ноября 2010

Я написал сервер, который прослушивает входящие TCP-соединения и подключающихся к нему клиентов.Когда я выключаю сервер и перезапускаю его на том же порту, я иногда получаю сообщение об ошибке EADDRINUSE при вызове bind (...) (код ошибки: 98 в Linux).Это происходит, даже если я устанавливаю опцию повторного использования сокета.

Ошибка не возникает постоянно, но, похоже, это происходит чаще, когда клиенты подключаются к серверу и отправляют данные во время его выключения.вниз.Я предполагаю, что проблема в том, что все еще ожидающие соединения, пока сервер выключен (связанная тема: https://stackoverflow.com/questions/41602/how-to-forcibly-close-a-socket-in-time-wait).

На стороне сервера я использую boost :: asio :: ip :: tcp ::акцептор. Я инициализирую его с помощью опции "reuse_address" (см. http://beta.boost.org/doc/libs/1_38_0/doc/html/boost_asio/reference/basic_socket_acceptor.html). Вот фрагмент кода:

using boost::asio::ip::tcp;
acceptor acceptor::acceptor(io_service);
endpoint ep(ip::tcp::v4(), port);
acceptor.open(ep.protocol());
acceptor.set_option(acceptor::reuse_address(true));
acceptor.bind(ep);
acceptor.listen();

Акцептор закрыт:

acceptor.close();

Iтакже пытался использовать acceptor.cancel () до этого, но это имело тот же эффект. Когда эта ошибка произошла, я не могу перезапустить сервер на тот же порт в течение некоторого времени. Перезапуск сети помогает, но не является постоянным решением.

Чего мне не хватает?

Любая помощь будет принята с благодарностью! :)

Ответы [ 2 ]

1 голос
/ 10 мая 2011

Когда вы решаете эти проблемы «насильно», кажется, вы вызываете проблемы на своей голове, не так ли?

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

Я бы не позволил включить это "решение" в сборки релизов в моей команде.

Помните, когдавероятность ошибки очень мала, тестирование крайне сложно!

1 голос
/ 17 ноября 2010

Первоначально это был комментарий к вопросу.


Ваш сервер обрабатывает дочерние процессы?Кроме того, вы уверены, что сокет находится в состоянии TIME_WAIT?Возможно, вы захотите получить вывод netstat -ap, когда это произойдет

...