Compartilhar via


Função WinHttpReadData (winhttp.h)

A função WinHttpReadData lê dados de um identificador aberto pela função WinHttpOpenRequest .

Consulte também WinHttpReadDataEx.

Sintaxe

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

Parâmetros

[in] hRequest

Identificador HINTERNET válido retornado de uma chamada anterior para WinHttpOpenRequest. WinHttpReceiveResponse ou WinHttpQueryDataAvailable deve ter sido chamado para esse identificador e deve ter sido concluído antes de WinHttpReadData ser chamado. Embora chamar WinHttpReadData imediatamente após a conclusão de WinHttpReceiveResponse evite a despesa de uma cópia de buffer, isso exige que o aplicativo use um buffer de comprimento fixo para leitura.

[out] lpBuffer

Ponteiro para um buffer que recebe os dados lidos. Verifique se esse buffer permanece válido até que WinHttpReadData seja concluído.

[in] dwNumberOfBytesToRead

Valor inteiro longo sem sinal que contém o número de bytes a serem lidos.

[out] lpdwNumberOfBytesRead

Ponteiro para uma variável de inteiro longo sem sinal que recebe o número de bytes lidos. WinHttpReadData define esse valor como zero antes de fazer qualquer verificação de erro ou trabalho. Ao usar WinHTTP de forma assíncrona, sempre defina esse parâmetro como NULL e recupere as informações na função de retorno de chamada; não fazer isso pode causar uma falha de memória.

Retornar valor

Retornará TRUE se tiver êxito ou FALSE caso contrário. Para obter informações de erro estendidas, chame GetLastError. A tabela a seguir identifica os códigos de erro retornados.

Código do Erro Descrição
ERROR_WINHTTP_CONNECTION_ERROR
A conexão com o servidor foi redefinida ou encerrada ou um protocolo SSL incompatível foi encontrado. Por exemplo, o WinHTTP 5.1 não dá suporte a SSL2, a menos que o cliente o habilite especificamente.
ERROR_WINHTTP_INCORRECT_HANDLE_STATE
A operação solicitada não pode ser executada porque o identificador fornecido não está no estado correto.
ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
O tipo de identificador fornecido está incorreto para esta operação.
ERROR_WINHTTP_INTERNAL_ERROR
Ocorreu um erro interno.
ERROR_WINHTTP_OPERATION_CANCELLED
A operação foi cancelada, geralmente porque o identificador no qual a solicitação estava operando foi fechado antes da conclusão da operação.
ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW
Retornado quando uma resposta de entrada excede um limite de tamanho do WinHTTP interno.
ERROR_WINHTTP_TIMEOUT
O tempo limite da solicitação foi atingido.
ERROR_NOT_ENOUGH_MEMORY
Não havia memória suficiente disponível para concluir a operação solicitada. (Código de erro do Windows)

Comentários

A partir do Windows Vista e do Windows Server 2008, o WinHttp permite que os aplicativos executem a codificação de transferência em partes nos dados enviados ao servidor. Quando o cabeçalho Transfer-Encoding estiver presente na resposta WinHttp, WinHttpReadData removerá as informações de agrupamento antes de fornecer os dados ao aplicativo.

Mesmo quando WinHTTP é usado no modo assíncrono (ou seja, quando WINHTTP_FLAG_ASYNC foi definido em WinHttpOpen), essa função pode operar de forma síncrona ou assíncrona. Se essa função retornar FALSE, essa função falhará e você poderá chamar GetLastError para obter informações de erro estendidas. Se essa função retornar TRUE, use o WINHTTP_CALLBACK_STATUS_READ_COMPLETE conclusão para determinar se essa função foi bem-sucedida e o valor dos parâmetros. A conclusão do WINHTTP_CALLBACK_STATUS_REQUEST_ERROR indica que a operação foi concluída de forma assíncrona, mas falhou.

Aviso Quando WinHTTP é usado no modo assíncrono, sempre defina o parâmetro lpdwNumberOfBytesRead como NULL e recupere os bytes lidos na função de retorno de chamada; caso contrário, uma falha de memória pode ocorrer.
 
Quando o buffer de leitura é muito pequeno, WinHttpReadData pode ser concluído de forma síncrona. Se a conclusão do WINHTTP_CALLBACK_STATUS_READ_COMPLETE disparar outra chamada para WinHttpReadData, a situação poderá resultar em um estouro de pilha. Em geral, é melhor usar um buffer de leitura comparável em tamanho ou maior que o buffer de leitura interno usado pelo WinHTTP, que é de 8 KB.

Se você estiver usando WinHttpReadData de forma síncrona e o valor retornado for TRUE e o número de bytes lidos for zero, a transferência será concluída e não haverá mais bytes para ler no identificador. Isso é análogo a atingir o fim do arquivo em um arquivo local. Se você estiver usando a função de forma assíncrona, o retorno de chamada WINHTTP_CALLBACK_STATUS_READ_COMPLETE será chamado com o parâmetro dwStatusInformationLength definido como zero quando o final de uma resposta for encontrado.

WinHttpReadData tenta preencher o buffer apontado por lpBuffer até que não haja mais dados disponíveis na resposta. Se dados suficientes não tiverem chegado do servidor, o buffer não será preenchido.

Para identificadores HINTERNET criados pela função WinHttpOpenRequest e enviados por WinHttpSendRequest, uma chamada para WinHttpReceiveResponse deve ser feita no identificador antes que WinHttpReadData possa ser usada.

Os caracteres de byte único recuperados com WinHttpReadData não são convertidos em caracteres de vários bytes.

Quando o buffer de leitura é muito pequeno, WinHttpReadData pode ser concluído de forma síncrona e, se o WINHTTP_CALLBACK_STATUS_READ_COMPLETE conclusão disparar outra chamada para WinHttpReadData, um estouro de pilha poderá resultar. É melhor usar um buffer de leitura com 8 Kilobytes ou maior.

Se dados suficientes não tiverem chegado do servidor, WinHttpReadData não preencherá totalmente o buffer apontado por lpBuffer. O buffer deve ser grande o suficiente pelo menos para manter os cabeçalhos HTTP na primeira leitura e, ao ler entradas de diretório codificadas em HTML, ele deve ser grande o suficiente para conter pelo menos uma entrada completa.

Se uma função de retorno de chamada status tiver sido instalada usando WinHttpSetStatusCallback, as seguintes notificações que foram definidas no parâmetro dwNotificationFlags de WinHttpSetStatusCallback indicam o progresso na verificação de dados disponíveis:

  • WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
  • WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
  • WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
  • WINHTTP_CALLBACK_STATUS_READ_COMPLETE
Nota Para Windows XP e Windows 2000, consulte a seção Requisitos de tempo de execução da página inicial do WinHttp.
 

Exemplos

O exemplo a seguir mostra como usar a semântica de transação segura para baixar um recurso de um servidor HTTPS (Secure Hypertext Transfer Protocol). O código de exemplo inicializa a API (interface de programação de aplicativo) WinHTTP, seleciona um servidor HTTPS de destino e, em seguida, abre e envia uma solicitação para esse recurso seguro.
WinHttpQueryDataAvailable é usado com o identificador de solicitação para determinar quantos dados estão disponíveis para download e, em seguida, WinHttpReadData é usado para ler esses dados. Esse processo se repete até que todo o documento seja recuperado e exibido.

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

Requisitos

Requisito Valor
Cliente mínimo com suporte Windows XP, Windows 2000 Professional com SP3 [somente aplicativos da área de trabalho]
Servidor mínimo com suporte Windows Server 2003, Windows 2000 Server com SP3 [somente aplicativos da área de trabalho]
Plataforma de Destino Windows
Cabeçalho winhttp.h
Biblioteca Winhttp.lib
DLL Winhttp.dll
Redistribuível WinHTTP 5.0 e Internet Explorer 5.01 ou posterior no Windows XP e Windows 2000.

Confira também

Sobre os Serviços HTTP do Microsoft Windows (WinHTTP)

Versões do WinHTTP

WinHttpCloseHandle

WinHttpConnect

WinHttpOpen

WinHttpOpenRequest

WinHttpQueryDataAvailable

WinHttpSendRequest

WinHttpWriteData