Я пишу портативное приложение для Windows / Linux, которое использует сокеты. я использую gethostbyname
функция для поиска DNS.
Однако я не вижу, как установить gethostbyname
тайм-аут и защитите мое приложение от зависания при поиске имени.
Конечно, можно запустить gethostbyname
на другой ветке, и это то, что я делаю. Тем не менее, это решение только для тривиальных приложений.
Мое приложение использует 1000-3000 подключений параллельно. В такой ситуации возникает вопрос: что делать с временными потоками? Я не вижу хорошего решения. Мы можем «забыть» их, однако, мы рискуем, что количество потоков нашей программы будет расти до бесконечности в плохих сетях. Мы можем прекратить их, но идея выглядит ужасно. По моему опыту, Windows может аварийно завершить работу после завершения тысяч потоков, и я не знаю, как Linux будет вести себя в таких условиях.
Кроме того, создание потоков требует много ресурсов; не стоит создавать 3000 потоков только для запуска gethostbyname
Функция и выход.
Таким образом, отдельный поток не выглядит хорошей идеей для действительно сложного приложения. Другая альтернатива — это, конечно, написать собственный DNS-клиент, но он также выглядит не очень хорошо.
Есть ли какой-нибудь «официальный» способ для Windows и Linux (или более удобный способ переноса) получить адрес хоста с заданным временем ожидания?
Прежде всего: не используйте gethostbyname()
устарела. использование getaddrinfo()
вместо.
То, что вы хотите, это асинхронное разрешение имен. Это общее требование, но, к сожалению, нет «стандартного» способа, как это сделать. Вот мои подсказки, чтобы найти лучшее решение для вас:
Не используйте DNS-клиент. Разрешение имен — это больше, чем просто DNS. Подумайте о mDNS, файлах хостов и так далее. Используйте системную функцию, например getaddrinfo()
который абстрагирует различные механизмы разрешения имен для вас.
Некоторые системы предлагают асинхронные версии функций разрешения, такие как glibc getaddrinfo_a()
,
Существуют библиотеки асинхронного разрешения, которые обертывают функции распознавателя синхронной системы. Вначале libasyncns приходит мне в голову.
Boost.Asio поддерживает использование резолвера с пулом потоков. Увидеть Вот.
Действительно, наиболее переносимым решением является использование отдельного потока для разрешения имен. Это также задокументировано в MSDN.
Существуют непереносимые решения, которые выполняют асинхронную проверку имен.
Linux glibc 2.2.3+: getaddrinfo_a
Окна: WSAAsyncGetHostByName Только IPv4 🙁
Существуют асинхронные библиотеки DNS: TADNS например выглядит достаточно просто.