Share via


Función WinHttpReadData (winhttp.h)

La función WinHttpReadData lee los datos de un identificador abierto por la función WinHttpOpenRequest .

Consulte también WinHttpReadDataEx.

Sintaxis

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

Parámetros

[in] hRequest

Identificador HINTERNET válido devuelto de una llamada anterior a WinHttpOpenRequest. Se debe haber llamado a WinHttpReceiveResponse o WinHttpQueryDataAvailable para este identificador y debe haberse completado antes de llamar a WinHttpReadData. Aunque llamar a WinHttpReadData inmediatamente después de la finalización de WinHttpReceiveResponse evita el gasto de una copia de búfer, esto requiere que la aplicación use un búfer de longitud fija para la lectura.

[out] lpBuffer

Puntero a un búfer que recibe los datos leídos. Asegúrese de que este búfer sigue siendo válido hasta que WinHttpReadData se haya completado.

[in] dwNumberOfBytesToRead

Valor entero largo sin signo que contiene el número de bytes que se van a leer.

[out] lpdwNumberOfBytesRead

Puntero a una variable de entero largo sin signo que recibe el número de bytes leídos. WinHttpReadData establece este valor en cero antes de realizar cualquier comprobación de errores o trabajo. Cuando se usa WinHTTP de forma asincrónica, establezca siempre este parámetro en NULL y recupere la información de la función de devolución de llamada; no hacerlo puede provocar un error de memoria.

Valor devuelto

Devuelve TRUE si se ejecuta correctamente o FALSE de lo contrario. Para obtener información de error extendida, llame a GetLastError. En la tabla siguiente se identifican los códigos de error que se devuelven.

Código de error Descripción
ERROR_WINHTTP_CONNECTION_ERROR
Se ha restablecido o finalizado la conexión con el servidor, o se encontró un protocolo SSL incompatible. Por ejemplo, WinHTTP 5.1 no admite SSL2 a menos que el cliente lo habilite específicamente.
ERROR_WINHTTP_INCORRECT_HANDLE_STATE
No se puede llevar a cabo la operación solicitada porque el identificador proporcionado no está en el estado correcto.
ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
El tipo de identificador proporcionado es incorrecto para esta operación.
ERROR_WINHTTP_INTERNAL_ERROR
Se ha producido un error interno.
ERROR_WINHTTP_OPERATION_CANCELLED
La operación se canceló, normalmente porque el identificador en el que estaba funcionando la solicitud se cerró antes de que se completara la operación.
ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW
Se devuelve cuando una respuesta entrante supera un límite interno de tamaño winHTTP.
ERROR_WINHTTP_TIMEOUT
La solicitud ha agotado el tiempo de espera.
ERROR_NOT_ENOUGH_MEMORY
No había suficiente memoria disponible para completar la operación solicitada. (Código de error de Windows)

Comentarios

A partir de Windows Vista y Windows Server 2008, WinHttp permite a las aplicaciones realizar codificación de transferencia fragmentada en los datos enviados al servidor. Cuando el encabezado Transfer-Encoding está presente en la respuesta WinHttp, WinHttpReadData quita la información de fragmentación antes de proporcionar los datos a la aplicación.

Incluso cuando WinHTTP se usa en modo asincrónico (es decir, cuando se ha establecido WINHTTP_FLAG_ASYNC en WinHttpOpen), esta función puede funcionar de forma sincrónica o asincrónica. Si esta función devuelve FALSE, se produjo un error en esta función y puede llamar a GetLastError para obtener información de error extendida. Si esta función devuelve TRUE, use el WINHTTP_CALLBACK_STATUS_READ_COMPLETE finalización para determinar si esta función se realizó correctamente y el valor de los parámetros. La finalización del WINHTTP_CALLBACK_STATUS_REQUEST_ERROR indica que la operación se completó de forma asincrónica, pero no se pudo realizar.

Advertencia Cuando WinHTTP se usa en modo asincrónico, establezca siempre el parámetro lpdwNumberOfBytesRead en NULL y recupere los bytes leídos en la función de devolución de llamada; de lo contrario, se puede producir un error de memoria.
 
Cuando el búfer de lectura es muy pequeño, WinHttpReadData puede completarse de forma sincrónica. Si el WINHTTP_CALLBACK_STATUS_READ_COMPLETE finalización desencadena otra llamada a WinHttpReadData, la situación puede dar lugar a un desbordamiento de pila. En general, es mejor usar un búfer de lectura que sea comparable en tamaño o mayor que el búfer de lectura interno usado por WinHTTP, que es de 8 KB.

Si usa WinHttpReadData de forma sincrónica y el valor devuelto es TRUE y el número de bytes leídos es cero, la transferencia se ha completado y no hay más bytes para leer en el identificador. Esto es análogo a llegar al final del archivo en un archivo local. Si usa la función de forma asincrónica, se llama a la devolución de llamada WINHTTP_CALLBACK_STATUS_READ_COMPLETE con el parámetro dwStatusInformationLength establecido en cero cuando se encuentra el final de una respuesta.

WinHttpReadData intenta rellenar el búfer al que apunta lpBuffer hasta que no haya más datos disponibles en la respuesta. Si no han llegado suficientes datos desde el servidor, el búfer no se rellena.

Para los identificadores HINTERNET creados por la función WinHttpOpenRequest y enviados por WinHttpSendRequest, se debe realizar una llamada a WinHttpReceiveResponse en el identificador antes de que se pueda usar WinHttpReadData .

Los caracteres de un solo byte recuperados con WinHttpReadData no se convierten en caracteres de varios bytes.

Cuando el búfer de lectura es muy pequeño, WinHttpReadData puede completarse de forma sincrónica y, si el WINHTTP_CALLBACK_STATUS_READ_COMPLETE finalización desencadena otra llamada a WinHttpReadData, puede producirse un desbordamiento de pila. Es mejor usar un búfer de lectura que tenga un tamaño de 8 kilobytes o mayor.

Si no han llegado suficientes datos desde el servidor, WinHttpReadData no rellena completamente el búfer al que apunta lpBuffer. El búfer debe ser lo suficientemente grande como para contener los encabezados HTTP en la primera lectura y, al leer entradas de directorio codificadas HTML, debe ser lo suficientemente grande como para contener al menos una entrada completa.

Si se ha instalado una función de devolución de llamada de estado mediante WinHttpSetStatusCallback, las de las siguientes notificaciones que se han establecido en el parámetro dwNotificationFlags de WinHttpSetStatusCallback indican el progreso en la comprobación de los datos disponibles:

  • WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
  • WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
  • WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
  • WINHTTP_CALLBACK_STATUS_READ_COMPLETE
Nota Para Windows XP y Windows 2000, consulta la sección Requisitos en tiempo de ejecución de la página de inicio de WinHttp.
 

Ejemplos

En el ejemplo siguiente se muestra cómo usar la semántica de transacciones seguras para descargar un recurso desde un servidor de Protocolo de transferencia de hipertexto seguro (HTTPS). El código de ejemplo inicializa la interfaz de programación de aplicaciones (API) WinHTTP, selecciona un servidor HTTPS de destino y, a continuación, abre y envía una solicitud para este recurso seguro.
WinHttpQueryDataAvailable se usa con el identificador de solicitud para determinar la cantidad de datos disponibles para su descarga y, a continuación, WinHttpReadData se usa para leer esos datos. Este proceso se repite hasta que se haya recuperado y mostrado todo el documento.

    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 Value
Cliente mínimo compatible Windows XP, Windows 2000 Professional con SP3 [solo aplicaciones de escritorio]
Servidor mínimo compatible Windows Server 2003, Windows 2000 Server con SP3 [solo aplicaciones de escritorio]
Plataforma de destino Windows
Encabezado winhttp.h
Library Winhttp.lib
Archivo DLL Winhttp.dll
Redistribuible WinHTTP 5.0 e Internet Explorer 5.01 o posterior en Windows XP y Windows 2000.

Consulte también

Acerca de los servicios HTTP de Microsoft Windows (WinHTTP)

Versiones winHTTP

WinHttpCloseHandle

WinHttpConnect

WinHttpOpen

WinHttpOpenRequest

WinHttpQueryDataAvailable

WinHttpSendRequest

WinHttpWriteData