WinHttpReadData 함수(winhttp.h)

WinHttpReadData 함수는 WinHttpOpenRequest 함수에서 연 핸들에서 데이터를 읽습니다.

WinHttpReadDataEx도 참조하세요.

구문

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

매개 변수

[in] hRequest

WinHttpOpenRequest에 대한 이전 호출에서 반환된 유효한 HINTERNET 핸들입니다. WinHttpReceiveResponse 또는 WinHttpQueryDataAvailable 은 이 핸들에 대해 호출되어야 하며 WinHttpReadData 가 호출되기 전에 완료되어야 합니다. WinHttpReceiveResponse가 완료된 직후 WinHttpReadData를 호출하면 버퍼 복사 비용이 발생하지 않지만 이렇게 하려면 애플리케이션에서 읽기에 고정 길이 버퍼를 사용해야 합니다.

[out] lpBuffer

데이터를 읽은 버퍼에 대한 포인터입니다. WinHttpReadData가 완료될 때까지 이 버퍼가 유효한지 확인합니다.

[in] dwNumberOfBytesToRead

읽을 바이트 수를 포함하는 부호 없는 long 정수 값입니다.

[out] lpdwNumberOfBytesRead

읽은 바이트 수를 수신하는 부호 없는 long 정수 변수에 대한 포인터입니다. WinHttpReadData 는 작업 또는 오류 검사를 수행하기 전에 이 값을 0으로 설정합니다. WinHTTP를 비동기적으로 사용하는 경우 항상 이 매개 변수를 NULL 로 설정하고 콜백 함수에서 정보를 검색합니다. 이렇게 하지 않을 경우 메모리 오류가 발생할 수 있습니다.

반환 값

성공하면 TRUE를 반환하고 그렇지 않으면 FALSE를 반환합니다. 확장된 오류 정보는 GetLastError를 호출합니다. 다음 표에서는 반환되는 오류 코드를 식별합니다.

오류 코드 Description
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를 사용하면 애플리케이션이 서버로 전송된 데이터에 대해 청크 분할 전송 인코딩을 수행할 수 있습니다. winHttp 응답에 Transfer-Encoding 헤더가 있으면 WinHttpReadData 는 애플리케이션에 데이터를 제공하기 전에 청크 정보를 제거합니다.

WinHTTP가 비동기 모드에서 사용되는 경우에도(즉, WinHttpOpen에서 WINHTTP_FLAG_ASYNC 설정된 경우) 이 함수는 동기적으로 또는 비동기적으로 작동할 수 있습니다. 이 함수가 FALSE를 반환하는 경우 이 함수가 실패했으며 GetLastError 를 호출하여 확장된 오류 정보를 가져올 수 있습니다. 이 함수가 TRUE를 반환하는 경우 WINHTTP_CALLBACK_STATUS_READ_COMPLETE 완료를 사용하여 이 함수가 성공했는지 여부와 매개 변수 값을 확인합니다. WINHTTP_CALLBACK_STATUS_REQUEST_ERROR 완료는 작업이 비동기적으로 완료되었지만 실패했음을 나타냅니다.

경고 WinHTTP가 비동기 모드에서 사용되는 경우 항상 lpdwNumberOfBytesRead 매개 변수를 NULL 로 설정하고 콜백 함수에서 읽은 바이트를 검색합니다. 그렇지 않으면 메모리 오류가 발생할 수 있습니다.
 
읽기 버퍼가 매우 작은 경우 WinHttpReadData 가 동기적으로 완료될 수 있습니다. WINHTTP_CALLBACK_STATUS_READ_COMPLETE 완료 시 WinHttpReadData에 대한 또 다른 호출이 트리거되면 스택 오버플로가 발생할 수 있습니다. 일반적으로 크기가 비슷한 읽기 버퍼 또는 WinHTTP에서 사용하는 내부 읽기 버퍼(8KB)보다 큰 읽기 버퍼를 사용하는 것이 가장 좋습니다.

WinHttpReadData를 동기적으로 사용하고 반환 값이 TRUE이고 읽은 바이트 수가 0인 경우 전송이 완료되었으며 핸들에서 읽을 바이트가 더 이상 없습니다. 이는 로컬 파일의 파일 끝에 도달하는 것과 유사합니다. 함수를 비동기적으로 사용하는 경우 응답의 끝을 찾을 때 dwStatusInformationLength 매개 변수를 0으로 설정하여 WINHTTP_CALLBACK_STATUS_READ_COMPLETE 콜백이 호출됩니다.

WinHttpReadData 는 응답에서 사용할 수 있는 데이터가 더 이상 없을 때까지 lpBuffer 가 가리키는 버퍼를 채우려고 합니다. 서버에서 충분한 데이터가 도착하지 않으면 버퍼가 채워지지 않습니다.

WinHttpOpenRequest 함수에서 만들고 WinHttpSendRequest에서 보낸 HINTERNET 핸들의 경우 WinHttpReadData를 사용하려면 먼저 핸들에서 WinHttpReceiveResponse를 호출해야 합니다.

WinHttpReadData로 검색된 단일 바이트 문자는 멀티바이트 문자로 변환되지 않습니다.

읽기 버퍼가 매우 작은 경우 WinHttpReadData 가 동기적으로 완료될 수 있으며 , WINHTTP_CALLBACK_STATUS_READ_COMPLETE 완료되면 WinHttpReadData에 대한 또 다른 호출이 트리거되면 스택 오버플로가 발생할 수 있습니다. 크기가 8K바이트 이상인 읽기 버퍼를 사용하는 것이 가장 좋습니다.

서버에서 충분한 데이터가 도착하지 않은 경우 WinHttpReadDatalpBuffer가 가리키는 버퍼를 완전히 채우지 않습니다. 버퍼는 최소한 첫 번째 읽기에서 HTTP 헤더를 저장할 수 있을 만큼 커야 하며 HTML로 인코딩된 디렉터리 항목을 읽을 때 하나 이상의 전체 항목을 저장할 수 있을 만큼 커야 합니다.

WinHttpSetStatusCallback을 사용하여 상태 콜백 함수를 설치한 경우 WinHttpSetStatusCallbackdwNotificationFlags 매개 변수에 설정된 다음 알림 중에서 사용 가능한 데이터를 확인하는 진행률을 나타냅니다.

  • 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(Secure Hypertext Transfer Protocol) 서버에서 리소스를 다운로드하는 방법을 보여 줍니다. 샘플 코드는 WinHTTP API(애플리케이션 프로그래밍 인터페이스)를 초기화하고, 대상 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 Professional SP3 [데스크톱 앱만 해당]
지원되는 최소 서버 Windows Server 2003, Windows 2000 Server SP3 [데스크톱 앱만 해당]
대상 플랫폼 Windows
헤더 winhttp.h
라이브러리 Winhttp.lib
DLL Winhttp.dll
재배포 가능 파일 Windows XP 및 Windows 2000에서 WinHTTP 5.0 및 인터넷 Explorer 5.01 이상.

추가 정보

Microsoft Windows HTTP 서비스 정보(WinHTTP)

WinHTTP 버전

WinHttpCloseHandle

WinHttpConnect

WinHttpOpen

WinHttpOpenRequest

WinHttpQueryDataAvailable

WinHttpSendRequest

WinHttpWriteData