共用方式為


winHttpReadData 函式 (winHTTP.h)

WinHttpReadData 函式會從 WinHttpOpenRequest 函式所開啟的句柄讀取數據。

另請參閱 WinHttpReadDataEx

語法

WINHTTPAPI BOOL WinHttpReadData(
  [in]  HINTERNET hRequest,
  [out] LPVOID    lpBuffer,
  [in]  DWORD     dwNumberOfBytesToRead,
  [out] LPDWORD   lpdwNumberOfBytesRead
);

參數

[in] hRequest

從先前呼叫 WinHttpOpenRequest 傳回的有效 HINTERNET 句柄。 WinHttpReceiveResponseWinHttpQueryDataAvailable 必須已為此句柄呼叫,而且必須在 呼叫 WinHttpReadData 之前完成。 雖然在 WinHttpReceiveResponse 完成之後立即呼叫 WinHttpReadData 可避免緩衝區複製的費用,但這樣做需要應用程式使用固定長度緩衝區進行讀取。

[out] lpBuffer

接收讀取數據之緩衝區的指標。 請確定此緩衝區保持有效狀態,直到 WinHttpReadData 完成為止。

[in] dwNumberOfBytesToRead

包含要讀取之位元組數目的不帶正負號長整數值。

[out] lpdwNumberOfBytesRead

接收讀取位元組數目的不帶正負號長整數變數指標。 WinHttpReadData 會在執行任何工作或錯誤檢查之前,將此值設定為零。 以異步方式使用 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_RESPONSE_DRAIN_OVERFLOW
當傳入回應超過內部 WinHTTP 大小限制時傳回。
ERROR_WINHTTP_TIMEOUT
要求已逾時。
ERROR_NOT_ENOUGH_MEMORY
記憶體不足,無法完成要求的作業。 (Windows 錯誤碼)

備註

從 Windows Vista 和 Windows Server 2008 開始,WinHttp 可讓應用程式對傳送至伺服器的數據執行區塊傳輸編碼。 當 winHttp 回應上出現 Transfer-Encoding 標頭時, WinHttpReadData 會先去除區塊化資訊,再將數據提供給應用程式。

即使 WinHTTP 用於異步模式 (亦即,在 WinHttpOpen) 中設定WINHTTP_FLAG_ASYNC時,此函式可以同步或異步運作。 如果此函式傳回 FALSE,此函式會失敗,而且您可以呼叫 GetLastError 以取得擴充的錯誤資訊。 如果此函式傳回 TRUE,請使用WINHTTP_CALLBACK_STATUS_READ_COMPLETE完成來判斷此函式是否成功,以及參數的值。 WINHTTP_CALLBACK_STATUS_REQUEST_ERROR完成表示作業以異步方式完成,但失敗。

警告 當 WinHTTP 用於異步模式時,請一律將 lpdwNumberOfBytesRead 參數設定為 NULL ,並擷取回呼函式中讀取的位元組;否則,可能會發生記憶體錯誤。
 
當讀取緩衝區非常小時, WinHttpReadData 可能會同步完成。 如果WINHTTP_CALLBACK_STATUS_READ_COMPLETE完成觸發另一個 WinHttpReadData 呼叫,則這種情況可能會導致堆疊溢位。 一般而言,最好使用大小類似的讀取緩衝區,或大於 WinHTTP 所使用的內部讀取緩衝區,也就是 8 KB。

如果您同步使用 WinHttpReadData ,且傳回值為 TRUE ,且讀取的位元組數目為零,則傳輸已完成,且句柄上沒有其他位元組可讀取。 這類似於在本機檔案中到達檔尾。 如果您以異步方式使用 函式,則會呼叫 WINHTTP_CALLBACK_STATUS_READ_COMPLETE 回呼,且找到響應結尾時 ,dwStatusInformationLength 參數會設定為零。

WinHttpReadData 會嘗試填滿 lpBuffer 指向的緩衝區,直到響應中沒有可用的數據為止。 如果沒有足夠的數據未從伺服器抵達,則不會填入緩衝區。

對於 WinHttpOpenRequest 函式所建立並由 WinHttpSendRequest 所建立的 HINTERNET 句柄,必須先在句柄上呼叫 WinHttpReceiveResponse,才能使用 WinHttpReadData

使用 WinHttpReadData 擷取的單一位元組位元元不會轉換成多位元組字元。

當讀取緩衝區非常小時, WinHttpReadData 可能會同步完成,如果 WINHTTP_CALLBACK_STATUS_READ_COMPLETE 完成,則會觸發對 WinHttpReadData 的另一個呼叫,可能會產生堆疊溢位。 最好使用大小為 8 KB 或更大的讀取緩衝區。

如果沒有足夠的數據從伺服器抵達, WinHttpReadData 不會完全填滿 lpBuffer 指向的緩衝區。 緩衝區必須夠大,才能在第一次讀取時保存 HTTP 標頭,而且讀取 HTML 編碼目錄專案時,它必須夠大,才能保存至少一個完整的專案。

如果使用 WinHttpSetStatusCallback 安裝狀態回呼函式,則在 WinHttpSetStatusCallbackdwNotificationFlags 參數中設定的下列通知指出檢查可用數據的進度:

  • WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
  • WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
  • WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
  • WINHTTP_CALLBACK_STATUS_READ_COMPLETE
注意 針對 Windows XP 和 Windows 2000,請參閱 WinHttp 起始頁的 運行時間需求 一節。
 

範例

下列範例示範如何使用安全交易語意,從安全超文本傳輸通訊協定 (HTTPS) 伺服器下載資源。 範例程式代碼會初始化 WinHTTP 應用程式開發介面 (API) 、選取目標 HTTPS 伺服器,然後開啟並傳送此安全資源的要求。
WinHttpQueryDataAvailable 會與要求句柄搭配使用,以判斷有多少數據可供下載,然後使用 WinHttpReadData 來讀取該數據。 此程式會重複執行,直到擷取並顯示整份文件為止。

    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);

    // Keep checking for data until there is nothing left.
    if (bResults)
    {
        do 
        {
            // Check for available data.
            dwSize = 0;
            if (!WinHttpQueryDataAvailable( hRequest, &dwSize)) 
            {
                printf( "Error %u in WinHttpQueryDataAvailable.\n",
                        GetLastError());
                break;
            }
            
            // No more available data.
            if (!dwSize)
                break;

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

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

            // This condition should never be reached since WinHttpQueryDataAvailable
            // reported that there are bits to read.
            if (!dwDownloaded)
                break;
                
        } while (dwSize > 0);
    }
    else
    {
        // Report any errors.
        printf( "Error %d has occurred.\n", GetLastError() );
    }

    // Close any 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

WinHttpQueryDataAvailable

WinHttpSendRequest

WinHttpWriteData