ETC*

WININET 정리 - 2(HTTP)

회사원Z 2008. 12. 9. 15:42

----------------------------------------------

순서

----------------------------------------------

1. InternetOpen
2. InternetConnect
3. HttpOpenRequest
4. HttpSendRequest
5. HttpSendRequestEx
6. InternetQueryDataAvailable
7. InternetReadFile
8. InternetWriteFile
9. HttpEndRequest

예제...

----------------------------------------------

 

1. InternetOpen

----------------------------------------------

HINTERNET InternetOpen(
    IN LPCSTR lpszAgent,
    IN DWORD dwAccessType,
    IN LPCSTR lpszProxyName,
    IN LPCSTR lpszProxyBypass,
    IN DWORD dwFlags
);
----------------------------------------------

기본 설명 : 인터넷 관련 DLL들을 초기화 한다. 이는 HTTP,FTP 모두 공통으로 사용.

대충 사용 방법 :

----------------------------------------------

   HINTERNET hInternet;

   hInternet = InternetOpen("HTTPTEST",
          INTERNET_OPEN_TYPE_PRECONFIG,
          NULL,
          NULL,
          0);

----------------------------------------------

인자 설명:

   lpszAgent : application의 이름을 넣어면 된다. 깡. 아무거나 넣어라. 구분만 되면 된다.

   dwAccessType : 인터넷 연결방식으로 다음과 같은 값이 있다.

       INTERNET_OPEN_TYPE_DIRECT : Resolves all host names locally.

       INTERNET_OPEN_TYPE_PRECONFIG : 레지스트에 세팅된 값을 그대로 사용한다.

       INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY : Retrieves the proxy

                        or direct configuration from the registry and prevents the use of a startup

                         JScript or Internet Setup (INS) file.

       INTERNET_OPEN_TYPE_PROXY : Passes requests to the proxy unless a proxy
                      bypass list is supplied and the name to be resolved bypasses the proxy.
                      In this case, the function uses         

   lpszProxyName, lpszProxyBypass : Proxy를 사용할때만 사용한다 NULL넣어라.

   dwFlags : 인터넷 연결 속성이다. 다음 값을 같는다.

        INTERNET_FLAG_ASYNC : 비동기 방식으로 연결한다.

        INTERNET_FLAG_FROM_CACHE : 실제로 테트웍 요청을 하지 않고 캐시에서

        INTERNET_FLAG_OFFLINE : 요청한 파일이 없으면 에러가 발생한다.

 

2. InternetConnect

----------------------------------------------

HINTERNET InternetConnect(
    IN HINTERNET hInternetSession,
    IN LPCSTR lpszServerName,
    IN INTERNET_PORT nServerPort,
    IN LPCSTR lpszUsername,
    IN LPCSTR lpszPassword,
    IN DWORD dwService,
    IN DWORD dwFlags,
    IN DWORD dwContext
);
----------------------------------------------

기본 설명 : HTTP,FTP,고퍼의 세션을 생성한다.

대충 사용 방법 :

----------------------------------------------

  HINTERNET hHttpSection;

  hHttpSection = InternetConnect(hInternet,

         "www.naver.com" ,

          0,"","",
          INTERNET_SERVICE_HTTP,
          0,
          0);

----------------------------------------------

인자 설명:

   hInternetSession : InternetOpen의 리튼값을 넣어라

   lpszServerName : IP나 URL을 넣어라.

   nServerPort : TCP/IP 포트

        INTERNET_DEFAULT_FTP_PORT : Uses the default port for FTP servers (port 21).

        INTERNET_DEFAULT_GOPHER_PORT : Uses the default port for

                                                      Gopher servers (port 70).

        INTERNET_DEFAULT_HTTP_PORT : Uses the default port for HTTP servers (port 80).

        INTERNET_DEFAULT_HTTPS_PORT : Uses the default port for HTTPS

                                                         servers (port 443).

        INTERNET_DEFAULT_SOCKS_PORT : SOCKS firewall servers (port 1080).

        INTERNET_INVALID_PORT_NUMBER : Uses the default port for the service

                                                           specified by dwService.

    lpszUsername : FTP 에 사용되는 사용자 name (HTTP에서는 ""를 입력한다. NULL이 아니다.)

    lpszPassword : FTP 에 사용되는 사용자 password (HTTP에서는 ""를 입력한다.

                                                                          NULL이 아니다.)

    dwService : 서비스의 종류

        INTERNET_SERVICE_FTP

        INTERNET_SERVICE_GOPHER

        INTERNET_SERVICE_HTTP

    dwFlags : FTP에만 사용되며 현재로서 사용할 수 있는 플래그는

               INTERNET_FLAG_PASSIVE 밖에 없다.

    dwContext : 비 동기 연결에 사용되는 컨텍스트 값인데 이에 관해서는 스타 이기면

                 다시 정리 하겠다.

 

3. HttpOpenRequest

----------------------------------------------

HINTERNET HttpOpenRequest(
    IN HINTERNET hHttpSession,
    IN LPCSTR lpszVerb,
    IN LPCSTR lpszObjectName,
    IN LPCSTR lpszVersion,
    IN LPCSTR lpszReferer,
    IN LPCSTR FAR * lpszAcceptTypes,
    IN DWORD dwFlags,
    IN DWORD dwContext
);
----------------------------------------------

기본 설명 : 서버에 전달한 요구 정보를 만든다. 실제 서버에 전달되지는 않는다.

대충 사용 방법 :

----------------------------------------------

HINTERNET hReq;

hReq = HttpOpenRequest(hHttpSection, "get","index.htm",NULL,NULL,NULL,0,0);

----------------------------------------------

인자 설명:

   hHttpRequest :InternetConnect의 리튼값을 넣어라

   lpszVerb : 요구 종류 GET, PUT, POST NULL이면 GET으로 동작한다.

   lpszObjectName : 요구 사항으로 일반적으로 호출하고자 하는 파일 이름이다.

   lpszVersion : 버젼 정보

   lpszReferer : Address of a string that specifies the address (URL) of the document

                     from which the URL in the request (lpszObjectName) was obtained. If this

                     parameter is NULL, no "referrer" is specified.

   lpszAcceptTypes : Address of a null-terminated array of LPCSTR pointers indicating

                     content types accepted by the client. If this parameter is NULL, no types

                     are accepted by the client. Servers interpret a lack of accept types to

                     indicate that the client accepts only documents of type "text/*" (that is,

                     only text documents, and not pictures or other binary files).

   dwFlags :  Internet flag values.

   dwContext : Application-defined value that associates

                     this operation with any application data

 

4. HttpSendRequest

----------------------------------------------

BOOL HttpSendRequest(
    IN HINTERNET hHttpRequest,
    IN LPCSTR lpszHeaders,
    IN DWORD dwHeadersLength,
    IN LPVOID lpOptional,
    DWORD dwOptionalLength
);
----------------------------------------------

기본 설명 : 만들어진 요구 사항을 서버에 보내 준다.

                Header정보나 옵션 데이터를 같이 보내 줄 수 있다.

                이에 대한 정보는 알아서 찾아라. 지금은 NULL로 한다.

대충 사용 방법 :

----------------------------------------------

HINTERNET hReq;

HttpSendRequest(hReq,NULL,0,NULL,0);

----------------------------------------------

인자 설명:

   hHttpRequest :HttpOpenRequest의 리튼값을 넣어라 

   lpszHeaders : Additional headers to be appended to the request. This parameter can

                      be NULL if there are no additional headers to append.

   dwHeadersLength : Length, in characters, of the additional headers. If this parameter is

                     -1L and lpszHeaders is not NULL, the function assumes that lpszHeaders is

                     zero-terminated (ASCIIZ), and the length is calculated

   lpOptional : Address of any optional data to send immediately after the request

                     headers. This parameter is generally used for POST and PUT operations.

                     The optional data can be the resource or information being posted to the

                     server. This parameter can be NULL if there is no optional data to send.

   dwOptionalLength : Length, in bytes, of the optional data. This parameter can be zero if

                     there is no optional data to send

 

5. HttpSendRequestEx

----------------------------------------------

BOOL HttpSendRequestEx(
    IN HINTERNET hRequest,
    IN LPINTERNET_BUFFERS lpBuffersIn,
    OUT LPINTERNET_BUFFERS lpBuffersOut,
    IN DWORD dwFlags,
    IN DWORD dwContext
);
----------------------------------------------

기본 설명 : 원래의 HttpSendRequest 함수에는 큰 제한이 있습니다. 즉, 이 함수를 호출할 때 요청

                  하는 모든 데이터를 단일 버퍼에 넣어 제공해야 합니다. 이 제한 때문에 종종 불편이 따

                  르고, 특정 클라이언트 응용 프로그램에서 성능이 떨어지며, 메모리가 적은 클라이언트

                  컴퓨터에서 많은 양의 데이터를 업로드하지 못할 수도 있습니다. 반면에 새 

                  HttpSendRequestEx 함수를 이용하면 프로그램에서 요청을 시작하고, 데이터를 가능

                 한 한 작은 조각으로 나누어 전송하고 모든 데이터가 전송되었을 때 요청을 끝낼 수 있습

                 니다. 이 함수가 작동하려면 컴퓨터에 Internet Explorer 4.0이 설치되어야 있어야 합니

                 다. Microsoft 다운로드 센터에서 다음 파일을 다운로드할 수 있습니다.
대충 사용 방법 :

----------------------------------------------

    INTERNET_BUFFERS BufferIn;

    HINTERNET hRequest

    BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS );
    BufferIn.Next = NULL;
    BufferIn.lpcszHeader = NULL;
    BufferIn.dwHeadersLength = 0;
    BufferIn.dwHeadersTotal = 0;
    BufferIn.lpvBuffer = NULL;               
    BufferIn.dwBufferLength = 0;
    BufferIn.dwBufferTotal = dwPostSize;
    BufferIn.dwOffsetLow = 0;
    BufferIn.dwOffsetHigh = 0;

    HttpSendRequestEx( hRequest, &BufferIn, NULL, 0, 0);

----------------------------------------------

인자 설명:

   hHttpRequest :HttpOpenRequest의 리튼값을 넣어라 

   lpBuffersIn : Optional. Address of an INTERNET_BUFFERS structure

   lpBuffersOut : Optional. Address of an INTERNET_BUFFERS structure

   dwFlags:

       HSR_ASYNC : Identical to WININET_API_FLAG_ASYNC.

       HSR_SYNC : Identical to WININET_API_FLAG_SYNC.

       HSR_USE_CONTEXT : Identical to WININET_API_FLAG_USE_CONTEXT.

       HSR_INITIATE : Iterative operation (completed by HttpEndRequest).

       HSR_DOWNLOAD : Download resource to file.

       HSR_CHUNKED : Send chunked data.

   dwContext : DWORD variable that contains the context value to use in

      asynchronous operations.

 

6. InternetQueryDataAvailable

----------------------------------------------

BOOL InternetQueryDataAvailable(
    IN HINTERNET hFile,
    OUT LPDWORD lpdwNumberOfBytesAvailable,
    IN DWORD dwFlags,
    IN DWORD dwContext
);

----------------------------------------------

기본 설명 : 내용적으로 네크웍크카드를 통해서 들어온 데이타가 버퍼에 쌓이게 될거이고,

                      그 버퍼의 양을 얻어내는 녀석이다. 결국 곧바로 파일로 저장하거나 읽어낼때 이용

                     가능한 버퍼사이즈를 얻어낸다.

대충 사용 방법 :

----------------------------------------------

HINTERNET hReq;

DWORD  size;

InternetQueryDataAvailable(hReq, &size,0,0);

----------------------------------------------

인자 설명:

   hFile : 조사할 버퍼의 핸들러 ( 여기서는 Http 요구 핼들러를 사용한다.)

   lpdwNumberOfBytesAvailable : 받은 데이터의 버퍼 크기

   dwFlags : must be zero (사용도 안할거면서 왜 있는거야 훌훌..)

   dwContext : must be zero

7. InternetReadFile

----------------------------------------------

BOOL InternetReadFile(
    IN HINTERNET hFile,
    IN LPVOID lpBuffer,
    IN DWORD dwNumberOfBytesToRead,
    OUT LPDWORD lpNumberOfBytesRead
);
----------------------------------------------

기본 설명 : 이름 그대로다 Internet정보를 읽는다.

대충 사용 방법 :

----------------------------------------------

HINTERNET hReq;

DWORD  size;

DWORD  dwRead;

char  buf[65000];

InternetReadFile(hReq,buf,size,&dwRead);

----------------------------------------------

인자 설명:

   hFile : 조사할 버퍼의 핸들러 ( 여기서는 Http 요구 핼들러를 사용한다.)

   lpBuffer : 읽은 데이터를 저장할 버퍼

   dwNumberOfBytesToRead : 읽고자 하는 데이터의 크기

   lpNumberOfBytesRead : 실재 읽은 데이터의 크기

 

8. InternetWriteFile

----------------------------------------------

BOOL InternetWriteFile(
    IN HINTERNET hFile,
    IN LPCVOID lpBuffer,
    IN DWORD dwNumberOfBytesToWrite,
    OUT LPDWORD lpdwNumberOfBytesWritten
);
----------------------------------------------

기본 설명 : 오픈된 인터넷 파일에 쓴다.

대충 사용 방법 :

----------------------------------------------

HINTERNET hRequest;

DWORD  dwBytesWritten;

char  pBuffer[1024];

InternetWriteFile( hRequest, pBuffer, 1024, &dwBytesWritten);

----------------------------------------------

인자 설명:

   hFile : Valid handle returned from a previous call to FtpOpenFile or an HINTERNET  

             handle sent by HttpSendRequestEx.

   lpBuffer :  버퍼

   dwNumberOfBytesToWrite : 쓰고자 하는 데이터의 크기

   lpdwNumberOfBytesWritten : 실재 쓴 데이터의 크기

 

9. HttpEndRequest

----------------------------------------------

HttpEndRequest(
    IN HINTERNET hRequest,
    OUT LPINTERNET_BUFFERS lpBuffersOut,
    IN DWORD dwFlags,
    IN DWORD dwContext
    );
----------------------------------------------

기본 설명 :  Request를 종료한다. InternetWriteFile를 사용할 때 모든 파일이 전송되었다면

                  이를 호출 해준다.

대충 사용 방법 :

----------------------------------------------

HINTERNET hRequest;

HttpEndRequest(hRequest, NULL, 0, 0)

----------------------------------------------

인자 설명:

   hRequest : HINTERNET handle returned by HttpOpenRequest and sent by HttpSendRequestEx.

   lpBuffersOut :  Address of an INTERNET_BUFFERS structure

   dwFlags :

       HSR_ASYNC : Identical to WININET_API_FLAG_ASYNC.

       HSR_SYNC : Identical to WININET_API_FLAG_SYNC.

       HSR_USE_CONTEXT : Identical to WININET_API_FLAG_USE_CONTEXT.

       HSR_INITIATE : Iterative operation (completed by HttpEndRequest).

       HSR_DOWNLOAD : Download resource to file.

       HSR_CHUNKED : Send chunked data.

   dwContext : Double-word variable that contains the context value to use in

                    asynchronous operations

 

-----------------------------------------------------------------------

기본 예제

-----------------------------------------------------------------------
다음은 API 완전정복(가남사)의 구버젼 P 1471에 있는 예제 이다.

#include <windows.h>
#include <wininet.h>
#include <stdio.h>

void main()
{
 HINTERNET hInternet, hHttp;
 HINTERNET hReq;
 DWORD  size;
 DWORD  dwRead;
 char  buf[65000];
 char  buf2[65000]={0,};

 hInternet = InternetOpen("HTTPTEST",
       INTERNET_OPEN_TYPE_PRECONFIG,
       NULL,
       NULL,
       0);
 if(hInternet == NULL)
 {
  printf("InternetOpen error\n");
  return;
 }
 printf("InternetConnect\n");
 hHttp = InternetConnect(hInternet,
        "www.naver.com",
        0,"","",
        INTERNET_SERVICE_HTTP,
        0,
        0);
 printf("HttpOpenRequest\n");
 hReq = HttpOpenRequest(hHttp, "get","index.htm",NULL,NULL,NULL,0,0);
 printf("HttpSendRequest\n");
 HttpSendRequest(hReq,NULL,0,NULL,0);
 do {
  InternetQueryDataAvailable(hReq, &size,0,0);
  InternetReadFile(hReq,buf,size,&dwRead);
  buf[dwRead] = 0;
  strcat(buf2,buf);
 } while(dwRead != 0);
 
 printf("[%s]\n",buf2);

 InternetCloseHandle(hHttp);
 InternetCloseHandle(hInternet);
}

 

-----------------------------------------------------------------------

기본 예제  HttpSendRequestEx를 사용

-----------------------------------------------------------------------

http://support.microsoft.com/kb/177188/ko 에서 제공하는 예제 이다.

#include <Windows.h>
#include <WinINet.h>
#include <stdio.h>

BOOL UseHttpSendReqEx(HINTERNET hRequest, DWORD dwPostSize);
#define BUFFSIZE 500

void main( int argc, char **argv )
{
 DWORD dwPostSize;

 if (argc < 4)
 {
  printf("Usage: Bigpost <Size> <Server> <Path>\n");
  printf("<Size> is the number of KB to POST\n");
  printf("<Server> is the server to POST to\n");
  printf("<Path> is the virtual path to POST to\n");
  exit(0);
 }

 if ( ((dwPostSize = strtoul(argv[1],NULL,10)) == 0) || (dwPostSize >= 2047999) )
 {
  printf("%s is invalid size.  Valid sizes are from 1 to 2047999\n", argv[1]);
  exit(0);
 }

 printf( "Test of POSTing %luKB with WinInet\n", dwPostSize);

 dwPostSize *= 1024;  // Convert KB to bytes

 HINTERNET hSession = InternetOpen( "HttpSendRequestEx", INTERNET_OPEN_TYPE_PRECONFIG,
  NULL, NULL, 0);
 if(!hSession)
 {
  printf("Failed to open session\n");
  exit(0);
 }


 HINTERNET hConnect = InternetConnect(hSession, argv[2], INTERNET_DEFAULT_HTTP_PORT,
  NULL, NULL, INTERNET_SERVICE_HTTP,NULL, NULL);
 if (!hConnect)
  printf( "Failed to connect\n" );
 else
 {
  HINTERNET hRequest = HttpOpenRequest(hConnect, "POST", argv[3],
   NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
  if (!hRequest)
   printf( "Failed to open request handle\n" );
  else
  {
   if(UseHttpSendReqEx(hRequest, dwPostSize))
   { 
    char pcBuffer[BUFFSIZE];
    DWORD dwBytesRead;

    printf("\nThe following was returned by the server:\n");
    do
    { dwBytesRead=0;
     if(InternetReadFile(hRequest, pcBuffer, BUFFSIZE-1, &dwBytesRead))
     {
      pcBuffer[dwBytesRead]=0x00; // Null-terminate buffer
      printf("%s", pcBuffer);
     }
     else
      printf("\nInternetReadFile failed");
    }while(dwBytesRead>0);
    printf("\n");
   }
   if (!InternetCloseHandle(hRequest))
    printf( "Failed to close Request handle\n" );
  }
  if(!InternetCloseHandle(hConnect))
   printf("Failed to close Connect handle\n");
 }
 if( InternetCloseHandle( hSession ) == FALSE )
  printf( "Failed to close Session handle\n" );

 printf( "\nFinished.\n" );
}

 

BOOL UseHttpSendReqEx(HINTERNET hRequest, DWORD dwPostSize)
{
 INTERNET_BUFFERS BufferIn;
 DWORD dwBytesWritten;
 int n;
 BYTE pBuffer[1024];
 BOOL bRet;

 BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS ); // Must be set or error will occur
    BufferIn.Next = NULL;
    BufferIn.lpcszHeader = NULL;
    BufferIn.dwHeadersLength = 0;
    BufferIn.dwHeadersTotal = 0;
    BufferIn.lpvBuffer = NULL;               
    BufferIn.dwBufferLength = 0;
    BufferIn.dwBufferTotal = dwPostSize; // This is the only member used other than dwStructSize
    BufferIn.dwOffsetLow = 0;
    BufferIn.dwOffsetHigh = 0;

    if(!HttpSendRequestEx( hRequest, &BufferIn, NULL, 0, 0))
    {
        printf( "Error on HttpSendRequestEx %d\n",GetLastError() );
        return FALSE;
    }

 FillMemory(pBuffer, 1024, 'D'); // Fill buffer with data

 bRet=TRUE;
 for(n=1; n<=(int)dwPostSize/1024 && bRet; n++)
 {
  if(bRet=InternetWriteFile( hRequest, pBuffer, 1024, &dwBytesWritten))
   printf( "\r%d bytes sent.", n*1024);
 }
  
 if(!bRet)
 {
        printf( "\nError on InternetWriteFile %lu\n",GetLastError() );
        return FALSE;
    }

    if(!HttpEndRequest(hRequest, NULL, 0, 0))
    {
        printf( "Error on HttpEndRequest %lu \n", GetLastError());
        return FALSE;
    }

 return TRUE;
}

 

 

 

-----------------------------------------------------------------------

기본 예제  URL이 존재하는지 확인

-----------------------------------------------------------------------

bool
cs_util_http_test  (const char* pURL,
       const char* pObjectName)
{
 HINTERNET hInternet, hHttp;
 HINTERNET hReq;

 /*--------------------------------------------------------------------*/
 /* precondition
  */
 /*--------------------------------------------------------------------*/
 if( (pURL    == NULL) ||
  (pObjectName  == NULL))
 {
     return false;
 }

 /*--------------------------------------------------------------------*/
 hInternet = InternetOpen("HTTPTEST",
    INTERNET_OPEN_TYPE_PRECONFIG,
    NULL,
    NULL,
    0);
 if(hInternet == NULL)
 {
  return false;
 }

 hHttp = InternetConnect(hInternet,
    pURL,
    0,"","",
    INTERNET_SERVICE_HTTP,
    0,
    0);
 hReq = HttpOpenRequest(hHttp, "GET",pObjectName,NULL,NULL,NULL,0,0);
 if(hReq == NULL)
  return false;
 if(!HttpSendRequest(hReq,NULL,0,NULL,0))
  return false;

 /*--------------------------------------------------------------------*/
 DWORD  size = 0;
 DWORD  dwRead = 0;
 DWORD  dwTotal = 0;
 char  sBuf[20];
 do {
  //InternetQueryDataAvailable(hReq, &size,0,0);
  InternetReadFile(hReq, sBuf, 10, &dwRead);
  dwTotal += dwRead;
  printf("%s",sBuf);
  if(dwTotal>10)break;
 } while(dwRead != 0);

 InternetCloseHandle(hHttp);
 InternetCloseHandle(hInternet);

 if(dwTotal > 10)
 {
  return true;
 }
 return false;
}