Тайм-аут поиска имени хоста сокета: как это реализовать?

Я пишу портативное приложение для Windows / Linux, которое использует сокеты. я использую gethostbyname функция для поиска DNS.
Однако я не вижу, как установить gethostbyname тайм-аут и защитите мое приложение от зависания при поиске имени.
Конечно, можно запустить gethostbyname на другой ветке, и это то, что я делаю. Тем не менее, это решение только для тривиальных приложений.
Мое приложение использует 1000-3000 подключений параллельно. В такой ситуации возникает вопрос: что делать с временными потоками? Я не вижу хорошего решения. Мы можем «забыть» их, однако, мы рискуем, что количество потоков нашей программы будет расти до бесконечности в плохих сетях. Мы можем прекратить их, но идея выглядит ужасно. По моему опыту, Windows может аварийно завершить работу после завершения тысяч потоков, и я не знаю, как Linux будет вести себя в таких условиях.
Кроме того, создание потоков требует много ресурсов; не стоит создавать 3000 потоков только для запуска gethostbyname Функция и выход.
Таким образом, отдельный поток не выглядит хорошей идеей для действительно сложного приложения. Другая альтернатива — это, конечно, написать собственный DNS-клиент, но он также выглядит не очень хорошо.
Есть ли какой-нибудь «официальный» способ для Windows и Linux (или более удобный способ переноса) получить адрес хоста с заданным временем ожидания?

2

Решение

Прежде всего: не используйте gethostbyname()устарела. использование getaddrinfo() вместо.

То, что вы хотите, это асинхронное разрешение имен. Это общее требование, но, к сожалению, нет «стандартного» способа, как это сделать. Вот мои подсказки, чтобы найти лучшее решение для вас:

  1. Не используйте DNS-клиент. Разрешение имен — это больше, чем просто DNS. Подумайте о mDNS, файлах хостов и так далее. Используйте системную функцию, например getaddrinfo() который абстрагирует различные механизмы разрешения имен для вас.

  2. Некоторые системы предлагают асинхронные версии функций разрешения, такие как glibc getaddrinfo_a(),

  3. Существуют библиотеки асинхронного разрешения, которые обертывают функции распознавателя синхронной системы. Вначале libasyncns приходит мне в голову.

  4. Boost.Asio поддерживает использование резолвера с пулом потоков. Увидеть Вот.

2

Другие решения

Действительно, наиболее переносимым решением является использование отдельного потока для разрешения имен. Это также задокументировано в MSDN.

Существуют непереносимые решения, которые выполняют асинхронную проверку имен.

Linux glibc 2.2.3+: getaddrinfo_a

Окна: WSAAsyncGetHostByName Только IPv4 🙁

Существуют асинхронные библиотеки DNS: TADNS например выглядит достаточно просто.

1

По вопросам рекламы [email protected]