使用wininet的异步请求

Posted

技术标签:

【中文标题】使用wininet的异步请求【英文标题】:Asynchronous request using wininet 【发布时间】:2009-12-29 22:00:52 【问题描述】:

我已经使用 wininet 发送了一些同步 HTTP 请求。现在,我想更进一步,想异步请求一些内容。

目标是获得类似“反向代理”的东西。我发送了一个延迟响应的 HTTP 请求 - 只要有人想联系我。我的线程应该继续,就好像同时没有任何东西一样,并且一旦响应到达,就应该在这个线程中调用回调。请注意,我不想要处理回复的第二个线程(如果有必要,它应该只提供一些中断主线程以在那里调用回调的机制)!

更新: 也许,描述我想要的最好的方式是像 javascript 中的行为,你只有一个线程,但可以发送 AJAX 请求,然后导致在这个 main 中调用回调线程。

因为我想了解它是如何工作的,所以我不想要图书馆解决方案。有人知道一些很好的教程来解释我如何实现我想要的行为吗?

【问题讨论】:

如果你不想有第二个线程,你显然需要一些同步机制来检索调用请求的线程中的通知 - 没有神奇的方法来调用线程上的回调那是忙于其他事情。 那么,InternetSetStatusCallback 开始了一个新线程?你会提出什么样的同步机制? "WaitForSingleObject" 等似乎不合适,因为我不知道什么时候必须等待。我需要更多一些“推送”同步机制来中断主线程来调用我的回调 【参考方案1】:

我的话题应该继续下去 在此期间什么都不是,而且 应在此调用回调 尽快回复 到了。

您在这里要求的基本上是COME FROM(而不是GO TO)。这是一个神话般的指令,实际上并不存在。调用代码的唯一方法是在发出线程中进行轮询,或者让一个单独的线程执行同步 IO,然后执行回调(在该线程中,或在另一个生成的线程中)结果.

当我在 C++ 中使用套接字工作时,我设置了一个专用线程来迭代所有打开的套接字,轮询可以在没有阻塞的情况下可用的数据,获取数据并将其填充到缓冲区中,将缓冲区发送到在给定情况下回调(EOL、EOF 等)。

【讨论】:

【参考方案2】:

除非您的主线程正在侦听消息队列之类的东西,否则实际上没有办法劫持它并启动它执行当前正在执行的代码之外的代码。

看看 boost::asio 是如何工作的,它基本上可以让你异步执行连接、读取、写入等操作……例如,你使用主(或任何)线程启动异步读取,然后 asio 使用重叠IO 要求操作系统通知它 IO 完成。当异步读取完成时,您的回调将由其中一个工作线程执行。

您需要做的就是确保使用您的主线程或工作线程调用 io_service::run() 来处理 IO 完成队列。您调用 run 的任何线程都将是执行回调的线程。

如果您遵守规则,Asio 有一些保证可以使这种多线程方法相当健壮。

看看documentation for asio,即使你不打算使用它,如果这是你想自己解决的问题,很多模式和想法都很有趣。

如果你不想看,请记住,在 Windows 上进行异步 IO 的方法称为“Overlapped IO”。

【讨论】:

以上是关于使用wininet的异步请求的主要内容,如果未能解决你的问题,请参考以下文章

FTP 异步操作上的 ERROR_IO_PENDING [Wininet C++]

异步请求(获取json数据)

Spring DeferredResult 异步请求

tornado异步web请求

异步请求 AJAX

wininet api 将文件发送到 http web 服务