Funzione WinHttpReadData (winhttp.h)

La funzione WinHttpReadData legge i dati da un handle aperto dalla funzione WinHttpOpenRequest .

Vedere anche WinHttpReadDataEx.

Sintassi

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

Parametri

[in] hRequest

Handle HINTERNET valido restituito da una chiamata precedente a WinHttpOpenRequest. WinHttpReceiveResponse o WinHttpQueryDataAvailable deve essere stato chiamato per questo handle e deve essere stato completato prima che WinHttpReadData venga chiamato. Anche se la chiamata a WinHttpReadData immediatamente dopo il completamento di WinHttpReceiveResponse evita la spesa di una copia del buffer, in questo modo è necessario che l'applicazione usi un buffer a lunghezza fissa per la lettura.

[out] lpBuffer

Puntatore a un buffer che riceve i dati letti. Assicurarsi che questo buffer rimanga valido fino al completamento di WinHttpReadData .

[in] dwNumberOfBytesToRead

Valore intero lungo senza segno che contiene il numero di byte da leggere.

[out] lpdwNumberOfBytesRead

Puntatore a una variabile integer long senza segno che riceve il numero di byte letti. WinHttpReadData imposta questo valore su zero prima di eseguire qualsiasi controllo di lavoro o errore. Quando si usa WinHTTP in modo asincrono, impostare sempre questo parametro su NULL e recuperare le informazioni nella funzione di callback; non in questo modo può causare un errore di memoria.

Valore restituito

Restituisce TRUE se ha esito positivo o FALSE in caso contrario. Per informazioni sull'errore estese, chiamare GetLastError. La tabella seguente identifica i codici di errore restituiti.

Codice di errore Descrizione
ERROR_WINHTTP_CONNECTION_ERROR
La connessione al server è stata reimpostata o terminata o è stato rilevato un protocollo SSL non compatibile. Ad esempio, WinHTTP 5.1 non supporta SSL2 a meno che il client non lo abilita in modo specifico.
ERROR_WINHTTP_INCORRECT_HANDLE_STATE
Impossibile eseguire l'operazione richiesta perché l'handle fornito non è nello stato corretto.
ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
Il tipo di handle fornito non è corretto per questa operazione.
ERROR_WINHTTP_INTERNAL_ERROR
Si è verificato un errore interno.
ERROR_WINHTTP_OPERATION_CANCELLED
L'operazione è stata annullata, in genere perché l'handle in cui è stata eseguita la richiesta è stata chiusa prima del completamento dell'operazione.
ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW
Restituito quando una risposta in ingresso supera un limite di dimensioni WinHTTP interno.
ERROR_WINHTTP_TIMEOUT
Timeout della richiesta.
ERROR_NOT_ENOUGH_MEMORY
Memoria insufficiente per completare l'operazione richiesta. (Codice errore di Windows)

Commenti

A partire da Windows Vista e Windows Server 2008, WinHttp consente alle applicazioni di eseguire la codifica di trasferimento in blocchi sui dati inviati al server. Quando l'intestazione Transfer-Encoding è presente nella risposta WinHttp, WinHttpReadData esegue lo striping delle informazioni di blocco prima di fornire i dati all'applicazione.

Anche quando WinHTTP viene usato in modalità asincrona, ovvero quando WINHTTP_FLAG_ASYNC è stato impostato in WinHttpOpen, questa funzione può operare in modo sincrono o asincrono. Se questa funzione restituisce FALSE, questa funzione non è riuscita e è possibile chiamare GetLastError per ottenere informazioni di errore estese. Se questa funzione restituisce TRUE, usare il completamento WINHTTP_CALLBACK_STATUS_READ_COMPLETE per determinare se questa funzione è riuscita e il valore dei parametri. Il completamento WINHTTP_CALLBACK_STATUS_REQUEST_ERROR indica che l'operazione è stata completata in modo asincrono, ma non riuscita.

Avviso Quando WinHTTP viene usato in modalità asincrona, impostare sempre il parametro lpdwNumberOfBytesRead su NULL e recuperare i byte letti nella funzione callback; in caso contrario, può verificarsi un errore di memoria.
 
Quando il buffer di lettura è molto piccolo, WinHttpReadData potrebbe completare in modo sincrono. Se il completamento WINHTTP_CALLBACK_STATUS_READ_COMPLETE attiva un'altra chiamata a WinHttpReadData, la situazione può causare un overflow dello stack. In generale, è consigliabile usare un buffer di lettura paragonabile alle dimensioni o maggiore del buffer di lettura interno usato da WinHTTP, ovvero 8 KB.

Se si usa WinHttpReadData in modo sincrono e il valore restituito è TRUE e il numero di byte letti è zero, il trasferimento è stato completato e non sono presenti più byte da leggere nell'handle. Si tratta di un risultato analogo al raggiungimento di un file finale in un file locale. Se si usa la funzione in modo asincrono, il callback WINHTTP_CALLBACK_STATUS_READ_COMPLETE viene chiamato con il parametro dwStatusInformationLength impostato su zero quando viene trovata la fine di una risposta.

WinHttpReadData tenta di riempire il buffer a cui punta lpBuffer fino a quando non sono disponibili altri dati dalla risposta. Se i dati sufficienti non sono arrivati dal server, il buffer non viene riempito.

Per gli handle DI SNAPSHOTNET creati dalla funzione WinHttpOpenRequest e inviati da WinHttpSendRequest, è necessario eseguire una chiamata a WinHttpReceiveResponse nell'handle prima che Sia possibile usare WinHttpReadData .

I caratteri a byte singoli recuperati con WinHttpReadData non vengono convertiti in caratteri multi-byte.

Quando il buffer di lettura è molto piccolo, WinHttpReadData può completare in modo sincrono e se il completamento della WINHTTP_CALLBACK_STATUS_READ_COMPLETE attiva un'altra chiamata a WinHttpReadData, un overflow dello stack può risultare. È consigliabile usare un buffer di lettura con dimensioni pari a 8 Kilobyte o più grandi.

Se i dati sufficienti non sono arrivati dal server, WinHttpReadData non riempie completamente il buffer a cui punta lpBuffer. Il buffer deve essere abbastanza grande almeno per contenere le intestazioni HTTP nella prima lettura e quando si legge le voci di directory codificate HTML, deve essere abbastanza grande per contenere almeno una voce completa.

Se è stata installata una funzione di callback dello stato usando WinHttpSetStatusCallback, quelle delle notifiche seguenti impostate nel parametro dwNotificationFlags di WinHttpSetStatusCallback indicano lo stato di avanzamento nel controllo dei dati disponibili:

  • WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
  • WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
  • WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
  • WINHTTP_CALLBACK_STATUS_READ_COMPLETE
Nota Per Windows XP e Windows 2000, vedere la sezione Requisiti di runtime della pagina iniziale WinHttp.
 

Esempio

Nell'esempio seguente viene illustrato come usare la semantica delle transazioni sicure per scaricare una risorsa da un server HTTPS (Secure Hypertext Transfer Protocol). Il codice di esempio inizializza l'interfaccia di programmazione dell'applicazione WinHTTP (API), seleziona un server HTTPS di destinazione, quindi apre e invia una richiesta per questa risorsa sicura.
WinHttpQueryDataAvailable viene usato con l'handle della richiesta per determinare la quantità di dati disponibile per il download, quindi WinHttpReadData viene usato per leggere tali dati. Questo processo viene ripetuto fino a quando l'intero documento non è stato recuperato e visualizzato.

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

Requisiti

Requisito Valore
Client minimo supportato Windows XP, Windows 2000 Professional con SP3 [solo app desktop]
Server minimo supportato Windows Server 2003, Windows 2000 Server con SP3 [solo app desktop]
Piattaforma di destinazione Windows
Intestazione winhttp.h
Libreria Winhttp.lib
DLL Winhttp.dll
Componente ridistribuibile WinHTTP 5.0 e Internet Explorer 5.01 o versione successiva in Windows XP e Windows 2000.

Vedi anche

Informazioni su Microsoft Windows HTTP Services (WinHTTP)

Versioni WinHTTP

WinHttpCloseHandle

WinHttpConnect

WinHttpOpen

WinHttpOpenRequest

WinHttpQueryDataAvailable

WinHttpSendRequest

WinHttpWriteData