WinHttpQueryDataAvailable 函数 (winhttp.h)

WinHttpQueryDataAvailable 函数返回可使用 WinHttpReadData 读取的数据量(以字节为单位)。

语法

WINHTTPAPI BOOL WinHttpQueryDataAvailable(
  [in]  HINTERNET hRequest,
  [out] LPDWORD   lpdwNumberOfBytesAvailable
);

参数

[in] hRequest

WinHttpOpenRequest 返回的有效 HINTERNET 句柄。 WinHttpReceiveResponse 必须已为此句柄调用,并在调用 WinHttpQueryDataAvailable 之前完成。

[out] lpdwNumberOfBytesAvailable

指向接收可用字节数的无符号长整数变量的指针。 在异步模式下使用 WinHTTP 时,始终将此参数设置为 NULL ,并在回调函数中检索数据;不这样做可能会导致内存故障。

返回值

如果函数成功,则返回 TRUE ,否则返回 FALSE 。 若要获取扩展的错误数据,请调用 GetLastError。 返回的错误代码如下。

错误代码 说明
ERROR_WINHTTP_CONNECTION_ERROR
与服务器的连接已重置或终止,或者遇到不兼容的 SSL 协议。 例如,WinHTTP 版本 5.1 不支持 SSL2,除非客户端专门启用 SSL2。
ERROR_WINHTTP_INCORRECT_HANDLE_STATE
请求的操作无法完成,因为提供的句柄未处于正确状态。
ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
此操作提供的句柄类型不正确。
ERROR_WINHTTP_INTERNAL_ERROR
发生了内部错误。
ERROR_WINHTTP_OPERATION_CANCELLED
操作被取消,通常是因为操作之前关闭了操作请求的句柄。
ERROR_WINHTTP_TIMEOUT
请求已超时。
ERROR_NOT_ENOUGH_MEMORY
内存不足,无法完成请求的操作。 (Windows 错误代码)

注解

即使在异步模式下使用 WinHTTP, (即在 WinHttpOpen) 中设置了WINHTTP_FLAG_ASYNC,此函数也可以同步或异步运行。 如果返回 FALSE,则失败,你可以调用 GetLastError 以获取扩展的错误信息。 如果返回 TRUE,请使用WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE完成来确定此函数是否成功以及参数的值。 WINHTTP_CALLBACK_STATUS_REQUEST_ERROR完成指示操作异步完成,但失败。

警告 在异步模式下使用 WinHTTP 时,始终将 lpdwNumberOfBytesAvailable 参数设置为 NULL ,并检索回调函数中可用的字节;否则,可能会发生内存故障。
 
此函数返回可通过后续调用 WinHttpReadData 立即读取的数据字节数。 如果没有可用的数据,并且文件末尾尚未到达,则会发生以下两种情况之一。 如果会话是同步的,则请求将等待数据可用。 如果会话是异步的,则函数返回 TRUE,当数据变得可用时,使用 WINHTTP_STATUS_CALLBACK_DATA_AVAILABLE 调用回调函数,并通过调用 WinHttpReadData 指示可立即读取的字节数。

在读取 对 WinHttpQueryDataAvailable 的调用指示的所有可用数据之前,不会重新计算剩余的数据量。

使用 WinHttpReadData 的返回值确定何时已完全读取响应。

重要 请勿使用 WinHttpQueryDataAvailable 的返回值来确定是否已到达响应的末尾,因为并非所有服务器都正确终止响应,而错误终止的响应会导致 WinHttpQueryDataAvailable 预测更多数据。
 
对于由 WinHttpOpenRequest 函数创建并由 WinHttpSendRequest 发送的 HINTERNET 句柄,必须在该句柄上调用 WinHttpReceiveResponse,然后才能使用 WinHttpQueryDataAvailable

如果状态回调函数已随 WinHttpSetStatusCallback 一起安装,则在 WinHttpSetStatusCallbackdwNotificationFlags 参数中设置的以下通知指示检查可用数据的进度:

  • WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
  • WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
  • WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE
注意 有关 Windows XP 和 Windows 2000 的详细信息,请参阅 运行时要求
 

示例

以下示例演示如何使用安全事务语义从 HTTPS 服务器下载资源。 示例代码初始化 WinHTTP API,选择目标 HTTPS 服务器,然后打开并发送对此安全资源的请求。
WinHttpQueryDataAvailable 与请求句柄一起使用,以确定可供下载的数据量,然后使用 WinHttpReadData 读取该数据。 此过程将重复,直到检索并显示整个文档。

重要

如果希望尽快 (某些数据,即在收到数据) 处理和分析数据,则应调用 WinHttpQueryDataAvailableWinHttpReadData。 如果尝试尽快下载整个响应,请直接调用 WinHttpReadData ,因为 WinHttpReadData 会在完成之前尝试填充缓冲区。

此外,下面的代码示例在每次循环迭代时分配。 对于性能非常重要的生产代码,可以改为从适当大小的缓冲区开始, (大约 1 兆字节) ,并在必要时调整大小。 实际上, WinHttpQueryDataAvailable 返回不超过 8 KB。


    DWORD dwSize = 0;
    DWORD dwDownloaded = 0;
    LPSTR pszOutBuffer;
    BOOL  bResults = FALSE;
    HINTERNET  hSession = NULL, 
               hConnect = NULL,
               hRequest = NULL;

    // Use WinHttpOpen to obtain a session handle.
    hSession = WinHttpOpen( L"WinHTTP Example/1.0",  
                            WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                            WINHTTP_NO_PROXY_NAME, 
                            WINHTTP_NO_PROXY_BYPASS, 0);

    // Specify an HTTP server.
    if (hSession)
        hConnect = WinHttpConnect( hSession, L"www.microsoft.com",
                                   INTERNET_DEFAULT_HTTPS_PORT, 0);

    // Create an HTTP request handle.
    if (hConnect)
        hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL,
                                       NULL, WINHTTP_NO_REFERER, 
                                       WINHTTP_DEFAULT_ACCEPT_TYPES, 
                                       WINHTTP_FLAG_SECURE);

    // Send a request.
    if (hRequest)
        bResults = WinHttpSendRequest( hRequest,
                                       WINHTTP_NO_ADDITIONAL_HEADERS,
                                       0, WINHTTP_NO_REQUEST_DATA, 0, 
                                       0, 0);

 
    // End the request.
    if (bResults)
        bResults = WinHttpReceiveResponse( hRequest, NULL);

    // Continue to verify data until there is nothing left.
    if (bResults)
        do 
        {

            // Verify available data.
            dwSize = 0;
            if (!WinHttpQueryDataAvailable( hRequest, &dwSize))
                printf( "Error %u in WinHttpQueryDataAvailable.\n",
                        GetLastError());

            // Allocate space for the buffer.
            pszOutBuffer = new char[dwSize+1];
            if (!pszOutBuffer)
            {
                printf("Out of memory\n");
                dwSize=0;
            }
            else
            {
                // Read the Data.
                ZeroMemory(pszOutBuffer, dwSize+1);

                if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, 
                                      dwSize, &dwDownloaded))
                    printf( "Error %u in WinHttpReadData.\n", GetLastError());
                else
                    printf( "%s\n", pszOutBuffer);
            
                // Free the memory allocated to the buffer.
                delete [] pszOutBuffer;
            }

        } while (dwSize > 0);


    // Report any errors.
    if (!bResults)
        printf( "Error %d has occurred.\n", GetLastError());

    // Close open handles.
    if (hRequest) WinHttpCloseHandle(hRequest);
    if (hConnect) WinHttpCloseHandle(hConnect);
    if (hSession) WinHttpCloseHandle(hSession);

要求

   
最低受支持的客户端 Windows XP、Windows 2000 Professional SP3 [仅限桌面应用]
最低受支持的服务器 Windows Server 2003、Windows 2000 Server SP3 [仅限桌面应用]
目标平台 Windows
标头 winhttp.h
Library Winhttp.lib
DLL Winhttp.dll
可再发行组件 Windows XP 和 Windows 2000 上的 WinHTTP 5.0 和 Internet Explorer 5.01 或更高版本。

另请参阅

关于 Microsoft Windows HTTP Services (WinHTTP)

WinHTTP 版本

WinHttpCloseHandle

WinHttpConnect

WinHttpOpen

WinHttpOpenRequest

WinHttpReadData

WinHttpSendRequest