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

问题描述:

我需要快速测试大约100个Web服务器的连接列表。快速意味着大约5秒钟。如果服务器无法访问约2-3秒,应该跳过。如果没有互联网连接 - 测试应该很快失败 - 2-3秒。它应该在XP(SP2)以上运行。多个名称的并发和可中断DNS名称解析似乎是不可能的

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

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

  • gethostbyname()getaddrinfo()(尝试都)
  • 创建一个套接字
  • connect()
  • 发送HTTP请求
  • 读HTTP性反应(只是半千字节)

这是没有好处:

  • 在缓慢的服务器的connect(的情况下)与没有超时阻断。
  • 如果没有互联网连接 - gethostbyname()和getaddrinfo()阻塞很长一段时间:17+秒。

异步测试程序:

  • 的异步消息
  • WSAAsyncGetHostByName()创建窗口 - 接受连接,随时可以发送 - 当分辨率为完整
  • WSAAsyncSelect()接收消息和准备阅读消息
  • SetTimeout()接收超时消息并弹出
  • 运行的窗口

消息循环这其中也白搭,因为WSAAsyncGetHostByName()的目的不是要提供几个名字的平行决议”(MSDN)。即使从多个线程调用,它也可以进行顺序解析。这使得线程按顺序运行,从而破坏了它们的目的。

因此,我的问题:要么阻止无法中断的调用,要么阻止不能被并置的异步调用。

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

有什么比这更好的?

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

这样就避免了必须使用WSAAsyncGetHostByName这是瓶颈,而只需要测试HTTP通信。

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

+0

是的,这将有助于我相信。顺便说一句,Windows系统本身不做兑现吗? –

+1

它会在您运行“DNS客户端”服务时执行。 –