ACE_SOCK_Dgram::open() и errno

Я попытался открыть уже открытый порт UDP, и ACE_SOCK_Dgram::open() не удалось. Как и ожидалось, strace показывает, что bind() завершился ошибкой и для errno установлено значение EADDRINUSE.

Чтобы увидеть, какая ошибка произошла, я использовал ACE_OS::last_error(), но она не обновляется.

Я хотел бы дать информативную ошибку пользователю, что порт уже используется, вместо какой-то общей ошибки.

Бонусный вопрос - когда можно использовать ACE_OS:: last_error ()?

Tnx

3 ответа

Решение

Я нашел проблему. Я использовал ACE_OS::last_error() для макроса (да, макросы плохие), который расширился до нескольких ссылок. Одна из строк выполнила системный вызов, и поэтому значение errno изменилось

Это помогло бы, если бы вы предоставили более подробную информацию. На какой платформе вы запускали приложение? Какую версию библиотеки ACE вы используете? Был ли это порт UDP в диапазоне 1-1024? Используете ли вы широковещательный сокет UDP?

Давайте предположим, что, поскольку вы проверяете "errno", а не GetLastError(), вы работаете в среде UNIX, такой как Linux. Глядя на OS_S_errno.inl, вы можете найти комментарии, которые описывают разницу в поведении между различными ОС.

Вы не спрашиваете, почему вы получаете EADDRINUSE для UDP-сокета в первую очередь. Вы используете опцию SO_REUSEADDR? Если вы это сделаете, вы должны знать, что только последний процесс, связанный с сокетом, будет уведомлен, и поведение может отличаться в зависимости от ОС.

Возможно ли, чтобы после bind() был выполнен другой системный вызов? В этом случае ошибка, возвращаемая bind(), может быть сброшена последующим системным вызовом. Как вы можете видеть из реализации last_error(), он просто устанавливает "errno =::GetLastError()" в окнах и возвращает errno прямо в UNIX.

Вы пробовали просто проверить errno себя после звонка открыть? Мне кажется, что если errno == EADDRINUSE Вы можете справиться с этим так, как вам нравится, без помощи ACE.

Другие вопросы по тегам