HTTP 経由のファイル取得

HTTP 経由によりファイルの情報を取得する例題です。URL(http://www.yahoo.co.jp etc.) を指定することにより、URLで指定されるファイルの情報を出力します。

HTTPによるインターネットへの接続にはWINAPIを用いており、

#include <windows.h>
#include <wininet.h>
のインクルードと、ライブラリ: libwininet.a へのリンクが必要です。

コンパイル時のオプションは以下のようになります。

  Gami[226]%   g++ -o list_56 list_56.cpp -lwininet  

HTTP 経由のファイル取得(list_56.cpp)
/*-----------------------------------------------------------------
 * HTTP GETクライアント
 * libwininet.a へのリンクが必要
 * (gcc -o winet winet.cpp -lwininet)
 *-----------------------------------------------------------------*/
#include <stdio.h>
#include <windows.h>
#include <wininet.h>

//-----------------------------------------------------------------
void split_url(char* url,char* host,char* file);
//-----------------------------------------------------------------

int main(int argc, char* argv[])
{
    char url[] = "http://www.geocities.jp/aki_gamyl/";
    // http://www.yahoo.co.jp/
    HINTERNET hInet;
    HINTERNET hConn;
    HINTERNET hReq;
    char szBuf[1024],host[256],file[256];
    DWORD dwSize;
    DWORD dwIndex;
    bool bret;
    memset(host,0,sizeof(char)*256);
    memset(file,0,sizeof(char)*256);

    // URL から[ホスト名]と[ファイル名]の取得
    split_url(url,host,file);
    // Internetに接続する
    hInet = ::InternetOpen("simple http request",
                           INTERNET_OPEN_TYPE_PRECONFIG,
                           NULL,NULL,0);
    if( hInet == NULL) {
        // 作成失敗
        return -1;
    }
    
    // HTTPサーバーに接続
    hConn = ::InternetConnect( hInet,
                               host,
                               INTERNET_default_HTTP_PORT,
                               NULL,
                               NULL,
                               INTERNET_SERVICE_HTTP,
                               0, NULL);
    if( hConn == NULL) {
        ::InternetCloseHandle( hInet);
        return -1;
    }

    // サーバー上で欲しいURLを指定する
    hReq = ::HttpOpenRequest( hConn,
                              "GET",
                              file,
                              NULL, // デフォルトのHTTPバージョン
                              NULL, // 履歴を追加しない
                              NULL,
                              0, NULL);
    if( hReq == NULL) {
        ::InternetCloseHandle( hConn);
        ::InternetCloseHandle( hInet);
        return -1;
    }

    // ヘッダーを要求する
    if( ::HttpSendRequest( hReq, NULL, 0, NULL, 0) != true) {
        ::InternetCloseHandle( hReq);
        ::InternetCloseHandle( hConn);
        ::InternetCloseHandle( hInet);
        return -1;
    }

    // ヘッダーの内容をすべて取得
    bret = true;
    dwIndex = 0;
    while( bret == true) {
        dwSize = sizeof(szBuf) - 1;
        memset(szBuf,0x00,sizeof(szBuf));
        bret = ::HttpQueryInfo( hReq, 
                                HTTP_QUERY_RAW_HEADERS_CRLF |
                                HTTP_QUERY_FLAG_NUMBER,
                                szBuf, &dwSize, &dwIndex);
        dwIndex++;
        printf(szBuf);
    }

    // ファイルの内容を受信する
    bret = true;
    while( bret == true) {
        dwSize = 0;
        memset(szBuf,0x00,sizeof(szBuf));
        bret = ::InternetReadFile( hReq, szBuf, sizeof( szBuf) - 1, &dwSize);
        printf(szBuf);
        if(dwSize == 0) {
            break;
        }
    }

    // すべてのハンドルをクローズする
    ::InternetCloseHandle( hReq);
    ::InternetCloseHandle( hConn);
    ::InternetCloseHandle( hInet);

    return 0;
}

// URL から[ホスト名]と[ファイル名]の取得
void split_url(char* url,char* host,char* file)
{
    int i,sep1=7,sep2=0,urllen=strlen(url);
    for(i=sep1;i<strlen(url);i++,sep2++){
        if(url[i]=='/') break;
    }
    strncpy(host,url+sep1,sizeof(char)*sep2);
    strncpy(file,url+sep1+sep2,sizeof(char)*(urllen-sep1-sep2));
}
inserted by FC2 system