多个名称的并发和可中断DNS名称解析似乎是不可能的

时间:2014-02-12 17:05:37

标签: c++ winapi winsock2

我需要快速测试大约100个Web服务器的列表以进行连接。快速意味着大约5秒钟。如果服务器在大约2-3秒内无法访问,则应跳过该服务器。如果没有互联网连接 - 测试应该很快失败 - 2-3秒。它应该在XP(SP2)及更高版本上运行。

我决定在一个单独的线程中为每个服务器运行一个测试过程。

同步测试程序执行以下操作:

  • gethostbyname()getaddrinfo()(同时尝试过)
  • 创建一个套接字
  • connect()
  • 发送HTTP请求
  • 读取HTTP响应(只有半个千字节)

这不好:

  • 如果服务器速度较慢,则connect()会在没有超时的情况下阻塞。
  • 如果没有互联网连接 - gethostbyname()和getaddrinfo()会长时间阻止:17秒以上。

异步测试程序:

  • 为异步消息创建窗口
  • WSAAsyncGetHostByName() - 在解决方案完成时收到消息
  • WSAAsyncSelect() - 接收连接,准备发送和准备阅读的消息
  • SetTimeout()收到超时消息并弹出
  • 为窗口运行消息循环

这个也不好,因为WSAAsyncGetHostByName()不是为了提供多个名称的并行解析”(MSDN)。因此,即使从多个线程调用,它也会执行顺序解析。这使得线程顺序运行,无法实现其目的。

因此我的问题是:阻止无法中断的调用或无法进行并行化的异步调用。

在我看来,唯一的选择是在单独的线程中执行阻塞调用,如果线程没有足够快地完成 - 用TerminateThread()谋杀它。

还有什么比这更好的了吗?!

1 个答案:

答案 0 :(得分:1)

我不确定这适合你的模型,但也许你可以解析一次主机名的IP地址,作为一种冷启动的东西,然后缓存它们。

这样,您就不必使用{+ 1}}作为瓶颈,而只需要测试HTTP通信。

现在,假设您有理由怀疑某个主机自您上次解决后更改了其IP地址(例如,目标无法访问,或连接被拒绝),您只需再次为该主机运行查询。