我有一些奇怪的超时InternetOpenUrl请求。端点在那里,URL正确。这发生在activex控件内部的同步循环中,并且大约在第6次执行时,它会在没有命中服务器的情况下超时。
HINTERNET hINet = InternetOpen(TEXT("InetURL/1.0"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );
/*hangs*/ HINTERNET hFile = InternetOpenUrl( hINet, url.c_str(), headers, headersLen, dwFlags, dwContext);
GetLastError只返回12002操作超时。以下是完整代码段:http://gist.github.com/559317
有趣的是,如果我将InternetOpen标志更改为INTERNET_OPEN_TYPE_DIRECT,并且fiddler未运行,则会出现故障(在几次成功请求之后),如果我运行fiddler,请求都会成功。
到目前为止,这已经在Win7 / IE8和Vista64 / IE8,XP / IE6上复制了答案 0 :(得分:1)
您几乎肯定会在WinINET中达到“每个主机的连接数”限制。
根据RFC2616中每个主机的连接数,您只能向并行运行的单个主机发出一定数量的请求。达到上限后,WinINET将挂起待处理的请求,直到现有连接可用。如果在达到超时之前没有可用的连接,则请求超时。
WinINET基于每个端点实现此限制,因此当您使用代理(如Fiddler,ISA,SQUID等)运行时,您可以同时激活最多“n”个连接,同时如果没有代理,那么每个主机名最多可以有“n”个连接。
如果您的ActiveX控件在响应完成后没有正确释放连接,那么您可能会遇到此问题。通常情况下,运行Fiddler不应该为您“修复”,但您可以使用NetMon来检查发生了什么。
答案 1 :(得分:1)
好的,所以我原本以为EricLaw是正确的并且评论道:“我的特殊问题是我在每个控制ajax调用之后都有javascript ajax调用。这会创建一个竞争条件,并且当我制作时最终没有返回4个javascript ajax调用控制中的ajax调用。(是的,我在原问题中错误地记录了我的环境)“
此评论不正确。
问题实际上是讨论的问题here:
“您的ActiveX控件有一个共同的缺点,即单线程单元 (STA)ActiveX& COM对象必须避免:STA COM对象无法执行 阻止STA线程上的操作,除非COM对象也泵 Windows消息。因此,如果您的控件需要执行同步 阻塞操作时,需要实现Windows消息泵 等待阻止操作完成。“
这解决了这个问题(并开启了一整套新的蠕虫)。如果你碰到这个,欢迎在这里发表评论,我会更好地解释。
答案 2 :(得分:0)
根据ivymike的评论,我查看了InternetOpenUrl标志,看到了一个我忽略的标志; INTERNET_FLAG_PRAGMA_NOCACHE
更新:此标志无法解决问题。我正在考虑从WinINet(InternetOpenUrl)移植到WinHTTP以解决缓存行为。
(将WinINet移植到WinHTTP)http://msdn.microsoft.com/en-us/library/aa384068(VS.85).aspx