Поделиться через


Функция WinHttpReadData (winhttp.h)

Функция WinHttpReadData считывает данные из дескриптора, открытого функцией WinHttpOpenRequest .

См. также статью WinHttpReadDataEx.

Синтаксис

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

Параметры

[in] hRequest

Допустимый дескриптор HINTERNET, возвращенный при предыдущем вызове WinHttpOpenRequest. WinHttpReceiveResponse или WinHttpQueryDataAvailable должны быть вызваны для этого дескриптора и должны быть завершены до вызова WinHttpReadData . Хотя вызов WinHttpReadData сразу после завершения winHttpReceiveResponse позволяет избежать расходов на копирование буфера, для этого приложение должно использовать буфер фиксированной длины для чтения.

[out] lpBuffer

Указатель на буфер, который получает считываемые данные. Убедитесь, что этот буфер остается действительным до завершения работы WinHttpReadData .

[in] dwNumberOfBytesToRead

Длинное целочисленное значение без знака, содержащее количество считываемых байтов.

[out] lpdwNumberOfBytesRead

Указатель на непознавленную длинную целочисленную переменную, получающую число прочитанных байтов. WinHttpReadData устанавливает это значение в нулевое значение перед выполнением какой-либо работы или проверки ошибок. При асинхронном использовании WinHTTP всегда присвойте этому параметру значение NULL и получите сведения в функции обратного вызова; Это может привести к сбою памяти.

Возвращаемое значение

Возвращает значение TRUE в случае успешного выполнения или FALSE в противном случае. Чтобы получить дополнительные сведения об ошибке, вызовите Метод GetLastError. В следующей таблице указаны коды ошибок, которые возвращаются.

Код ошибки Описание
ERROR_WINHTTP_CONNECTION_ERROR
Подключение к серверу было сброшено или прервано, или обнаружен несовместимый протокол SSL. Например, 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 позволяет приложениям выполнять кодирование фрагментов передачи данных, отправляемых на сервер. Когда заголовок Transfer-Encoding присутствует в ответе WinHttp, WinHttpReadData удаляет сведения о фрагментации, прежде чем предоставлять данные приложению.

Даже если WinHTTP используется в асинхронном режиме (то есть, когда WINHTTP_FLAG_ASYNC задано в WinHttpOpen), эта функция может работать как синхронно, так и асинхронно. Если эта функция возвращает значение 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 КБ.

Если вы используете WinHttpReadData синхронно и возвращается значение TRUE , а число прочитанных байтов равно нулю, передача завершена и больше нет байтов для чтения на дескрипторе. Это аналогично достижению конца файла в локальном файле. Если функция используется асинхронно, обратный вызов WINHTTP_CALLBACK_STATUS_READ_COMPLETE вызывается с параметром dwStatusInformationLength , равным нулю при обнаружении конца ответа.

WinHttpReadData пытается заполнить буфер, на который указывает lpBuffer , пока не будет больше доступных данных из ответа. Если с сервера не поступило достаточно данных, буфер не заполняется.

Для дескрипторов HINTERNET, созданных функцией WinHttpOpenRequest и отправленных WinHttpSendRequest, перед использованием WinHttpReadData необходимо выполнить вызов WinHttpReceiveResponse.

Однобайтовые символы, полученные с помощью WinHttpReadData , не преобразуются в многобайтовые символы.

Если буфер чтения очень мал, WinHttpReadData может выполняться синхронно, и если WINHTTP_CALLBACK_STATUS_READ_COMPLETE завершения активирует другой вызов WinHttpReadData, может возникнуть переполнение стека. Рекомендуется использовать буфер чтения размером 8 Килобайт или больше.

Если с сервера не поступило достаточно данных, WinHttpReadData не полностью заполняет буфер, на который указывает lpBuffer. Буфер должен быть достаточно большим по крайней мере для хранения заголовков HTTP при первом чтении, а при чтении записей каталога в кодировке HTML он должен быть достаточно большим, чтобы вместить по крайней мере одну полную запись.

Если функция обратного вызова состояния была установлена с помощью WinHttpSetStatusCallback, то следующие уведомления, заданные в параметре dwNotificationFlagswinHttpSetStatusCallback , указывают на ход проверки доступных данных:

  • 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. В примере кода инициализируется программный интерфейс приложения (API) WinHTTP, выбирается целевой 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 Профессиональная с пакетом обновления 3 (SP3) [только классические приложения]
Минимальная версия сервера Windows Server 2003, Windows 2000 Server с пакетом обновления 3 (SP3) [только классические приложения]
Целевая платформа Windows
Header winhttp.h
Библиотека Winhttp.lib
DLL Winhttp.dll
Распространяемые компоненты WinHTTP 5.0 и Internet Обозреватель 5.01 или более поздней версии в Windows XP и Windows 2000.

См. также раздел

Сведения о службах HTTP Microsoft Windows (WinHTTP)

Версии WinHTTP

WinHttpCloseHandle

WinHttpConnect

WinHttpOpen

WinHttpOpenRequest

WinHttpQueryDataAvailable

WinHttpSendRequest

WinHttpWriteData