多个名称的并发和可中断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地址(例如,目标无法访问或连接被拒绝),则可以再次为该主机运行查询。
是的,这将有助于我相信。顺便说一句,Windows系统本身不做兑现吗? –
它会在您运行“DNS客户端”服务时执行。 –