2

我编写使用套接字的可移植 Windows/Linux 应用程序。我使用gethostbyname函数来执行 DNS 查找。但是,我看不到如何设置gethostbyname超时并保护我的应用程序在名称查找期间不被挂起。当然也可以跑gethostbyname在另一个线程上,这就是我所做的。但是,它仅适用于琐碎的应用程序。我的应用程序并行使用 1000-3000 个连接。在这种情况下,问题是:如何处理超时线程?我没有看到好的解决方案。我们可以“忘记”它们,但是,我们面临着程序线程数在不良网络上会增长到无穷大的风险。我们可以终止它们,但这个想法看起来很糟糕。根据我的经验,在数千个线程终止后,Windows 可能会崩溃,我不知道 Linux 在这种情况下会如何表现。此外,线程创建需要很多资源;仅仅为了运行而创建 3000 个线程并不是一个好主意gethostbyname功能并退出。因此,对于真正复杂的应用程序,单独的线程看起来不是一个好主意。当然,另一种选择是编写自己的 DNS 客户端,但是,它也不好看。Windows 和 Linux 上是否有任何“官方”方式(或更好的可移植方式)来获取具有自定义超时的主机地址?

4

2 回答 2

2

首先:不要使用gethostbyname(),它已经过时了。改为使用getaddrinfo()

您想要的是异步名称解析。这是一个常见的要求,但不幸的是没有“标准”方式,如何做到这一点。这是我为您找到最佳解决方案的提示:

  1. 不要实现 DNS 客户端。名称解析不仅仅是 DNS。想想 mDNS、主机文件等等。使用这样的系统函数getaddrinfo()可以为您抽象出不同的名称解析机制。

  2. 一些系统提供解析函数的异步版本,例如 glibc 提供getaddrinfo_a().

  3. 有异步解析库,围绕同步系统解析器函数。一开始我想到了libasyncns 。

  4. Boost.Asio 支持将解析器与线程池一起使用。见这里

于 2014-06-25T14:44:10.487 回答
1

最便携的解决方案确实是使用单独的线程进行名称解析。这也记录在MSDN中。

存在执行异步名称查找的不可移植解决方案。

Linux glibc 2.2.3+:getaddrinfo_a

Windows:WSAAsyncGetHostByName仅限 IPv4 :(

那里有异步 DNS 库:例如TADNS看起来很简单。

于 2014-06-25T08:54:07.630 回答