套接字主机名查找超时:如何实现呢?

时间:2014-06-25 08:12:38

标签: c++ c sockets timeout gethostbyname

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

2 个答案:

答案 0 :(得分:2)

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

您想要的是异步名称解析。这是一个常见的要求,但遗憾的是没有"标准"方式,怎么做。这是我为您找到最佳解决方案的提示:

  1. 不要实施DNS客户端。名称解析不仅仅是DNS。想想mDNS,托管文件等等。使用像getaddrinfo()这样的系统函数为您提取不同的名称解析机制。

  2. 有些系统提供分辨率功能的异步版本,例如glibc提供getaddrinfo_a()

  3. 有异步解析库,它包含同步系统解析器函数。我首先想到libasyncns

  4. Boost.Asio支持将解析程序与线程池一起使用。请参阅here

答案 1 :(得分:1)

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

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

Linux glibc 2.2.3+:getaddrinfo_a

Windows:WSAAsyncGetHostByName仅限IPv4 :(

有异步DNS库:TADNS例如看起来很容易。