【问题标题】:WinHTTP Multiple Asynchronous RequestsWinHTTP 多个异步请求
【发布时间】:2012-05-26 12:32:59
【问题描述】:

我需要从网站的大约 6000 个页面中提取数据。在做了一些研究之后,我决定试一试 WinHTTP。我能够让这个工作,但是我正在同步做事情,所以需要一段时间才能完成。我现在正在尝试异步使用 WinHTTP,但遇到了障碍。我搜索了许多教程和示例,但我只能找到 MSDN 文档,这对于我正在做的事情来说似乎过于复杂。如前所述,我找不到很多资源,所以我继续尝试:

std::string theSource = "";
char * httpBuffer;
DWORD dwSize = 1;
DWORD dwRecv = 1;

HINTERNET hOpen = 
           WinHttpOpen
           (
               L"Example Agent", 
               WINHTTP_ACCESS_TYPE_NO_PROXY, 
               NULL, 
               NULL, 
               WINHTTP_FLAG_ASYNC
           );

WINHTTP_STATUS_CALLBACK theCallback = 
           WinHttpSetStatusCallback
           (
               hOpen, 
               (WINHTTP_STATUS_CALLBACK) HttpCallback,
               WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS,
               NULL
           );

HINTERNET hConnect = 
           WinHttpConnect
           (
               hOpen, 
               L"example.org",
               INTERNET_DEFAULT_HTTPS_PORT, 
               0
           );

HINTERNET hRequest = NULL;

BOOL allComplete = false;

int theRequest = 1;


while (!allComplete)
{
    if (theRequest == 1)
    {
        hRequest = WinHttpOpenRequest
                   (
                       hConnect,
                       L"GET", 
                       L"example.html",
                       0,
                       WINHTTP_NO_REFERER, 
                       WINHTTP_DEFAULT_ACCEPT_TYPES, 
                       WINHTTP_FLAG_SECURE
                   );


        WinHttpSendRequest
        (
            hRequest, 
            WINHTTP_NO_ADDITIONAL_HEADERS, 
            0, 
            WINHTTP_NO_REQUEST_DATA, 
            0, 
            0, 
            0
        );
    }

    else if (theRequest == 2)
    {
        WinHttpReceiveResponse(hRequest, NULL);
    }

    else if (theRequest == 3)
    {
        WinHttpQueryHeaders
        (
            hRequest, 
            WINHTTP_QUERY_RAW_HEADERS_CRLF, 
            WINHTTP_HEADER_NAME_BY_INDEX, 
            NULL, 
            &dwSize, 
            WINHTTP_NO_HEADER_INDEX
        );

        WCHAR * headerBuffer = new WCHAR[dwSize/sizeof(WCHAR)];

        WinHttpQueryHeaders
        (
            hRequest, 
            WINHTTP_QUERY_RAW_HEADERS_CRLF, 
            WINHTTP_HEADER_NAME_BY_INDEX, 
            headerBuffer, 
            &dwSize, 
            WINHTTP_NO_HEADER_INDEX
        );

        delete [] headerBuffer;

        dwSize = 1;

        while (dwSize > 0)
        {
            if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
            {
                break;
            }

            httpBuffer = new char[dwSize + 1];

            ZeroMemory(httpBuffer, dwSize + 1);

            if (!WinHttpReadData(hRequest, httpBuffer, dwSize, &dwRecv))
            {
                std::cout << "WinHttpReadData() - Error Code: " << GetLastError() << "\n";
            }

        else
        {
            theSource = theSource + httpBuffer;
        }

        delete [] httpBuffer;

        // Parse the source for the data I'm looking for.

        break;

    }
}

下面是我的回调函数:

void CALLBACK HttpCallback(HINTERNET hInternet, DWORD * dwContext, DWORD dwInternetStatus, void * lpvStatusInfo, DWORD dwStatusInfoLength)
{
    switch (dwInternetStatus)
    {
        default:
            std::cout << dwInternetStatus << "\n";
            break;

        case WINHTTP_CALLBACK_STATUS_HANDLE_CREATED:
            std::cout << "Handle created.\n";
            theRequest = 1;
            break;

        case WINHTTP_CALLBACK_STATUS_REQUEST_SENT:
            std::cout << "Request sent.\n";
            theRequest = 2;
            break;

        case WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED:
            std::cout << "Response received.\n";
            theRequest = 3;
            break;

    }
}

注意:我只提供了我的代码的这一部分,因为它是与我的问题/问题有关的部分。如果缺少变量声明,我深表歉意。

上面的代码对我有用,实际上确实得到了我正在寻找的所需信息,但仅适用于单个页面。到了这一步之后,我意识到当使用这种方法发出多个请求时,我不知道该怎么做。同样,除了 MSDN 文章之外,搜索并没有出现太多,据我所知,这些文章并不是一次发出多个请求的示例。此外,我用来打开/发送/等的 while 循环。基于 theRequest 值的请求似乎是一种糟糕的方式。对于改进我的代码的任何其他建议,我也将不胜感激。

总的来说,我的问题总结如下:我需要异步使用 WinHTTP 发出大约 6000 个 GET 请求。我不完全确定如何执行此操作,因为我是 WinHTTP 的新手,所以我正在寻找处理多个异步请求的最基本(或可能有效)的方法。

【问题讨论】:

标签: c winapi asynchronous winhttp


【解决方案1】:

您将重复您在while (!allComplete) { ... } 中所做的事情,并以这种方式发出更多请求。您可以重复使用hConnect,但您需要为每个资源请求执行WinHttpOpenRequest

【讨论】:

  • 您能否详细说明或提供一些示例代码?如果可能的话,后者对我最有帮助。我没有看到如何将其他请求合并到我的循环中并仍然适当地监视它们。我将无法依赖请求的值来查询标头或读取数据,因为每个请求都将根据当前代码在任何给定时间通过回调函数修改该值。
  • theRequest 在这种情况下不能是全局的,它将特定于特定的hRequest。因此,您将需要一种具有theRequest + hRequest 值的结构集合。
猜你喜欢
  • 2015-05-03
  • 2015-01-17
  • 2018-04-10
  • 1970-01-01
  • 2012-02-14
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 2019-01-05
相关资源
最近更新 更多