Адрес уже используется с акселерометром boost asio

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

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

На стороне сервера я использую boost:: asio:: ip:: tcp:: acceptor. Я инициализирую его с помощью опции "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();

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

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

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

Ответ 1

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


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

Ответ 2

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

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

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

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