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 通訊協定。 例如,除非用戶端特別啟用 SSL2,否則 WinHTTP 5.1 版不支援 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 MB) ,並視需要調整大小。 在實務上, 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、具有 SP3 的 Windows 2000 Server [僅限傳統型應用程式]
目標平台 Windows
標頭 winHTTP.h
程式庫 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