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


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

Функция WinHttpQueryDataAvailable возвращает объем данных в байтах, доступных для чтения с помощью WinHttpReadData.

Синтаксис

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

Параметры

[in] hRequest

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

[out] lpdwNumberOfBytesAvailable

Указатель на длинную целочисленную переменную без знака, которая получает количество доступных байтов. Если 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_TIMEOUT
Истекло время ожидания запроса.
ERROR_NOT_ENOUGH_MEMORY
Недостаточно памяти для выполнения запрошенной операции. (Код ошибки Windows)

Комментарии

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

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

  • WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
  • WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
  • WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE
Примечание Дополнительные сведения о Windows XP и Windows 2000 см. в разделе Требования к времени выполнения.
 

Примеры

В следующем примере показано, как использовать безопасную семантику транзакций для скачивания ресурса с HTTPS-сервера. Пример кода инициализирует API WinHTTP, выбирает целевой HTTPS-сервер, а затем открывает и отправляет запрос на этот безопасный ресурс.
WinHttpQueryDataAvailable используется с дескриптором запроса, чтобы определить объем данных, доступных для скачивания, а затем WinHttpReadData используется для чтения данных. Этот процесс повторяется до тех пор, пока не будет извлечен и отображен весь документ.

Важно!

Если требуется как можно быстрее (то есть вы обрабатываете и анализируете данные по мере их получения), следует вызвать WinHttpQueryDataAvailable и WinHttpReadData. Если вы пытаетесь скачать весь ответ как можно быстрее, вызовите WinHttpReadData напрямую, так как WinHttpReadData пытается заполнить буфер перед завершением.

Кроме того, приведенный ниже пример кода выделяется для каждой итерации цикла. Для рабочего кода, где важна производительность, можно начать с буфера соответствующего размера (возможно, 1 мегабайт) и изменить его размер при необходимости. На практике WinHttpQueryDataAvailable возвращает не более 8 килобайт.


    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 Профессиональная с пакетом обновления 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

WinHttpReadData

WinHttpSendRequest