C/C++中libcurlの使用-Http GET方法の使用について詳しく説明します。


Curlは、特定のURL文法でデータ伝送を行うコマンドラインツールである。libcrulはこの仕事を完成するためのcurlライブラリです。libcurlを使って、C/C++を使ってファイルのダウンロード、HTTP get、postなど多くの仕事ができます。ここでは、libcurlを使用したC APIがHTTPにおけるGET動作を完了することを紹介する。以下のコードはHTTP getプロトコルを使用して、あるURLに要求を送信します。要求が正しく応答されると、応答の結果ページの内容をファイルとしてローカルディスクに保存します。
//getDataByCurl.cpp
#include 
#include 

#include 
#include 
#include 

#include 
#include 
using namespace std;

struct MemoryStruct 
{
    char *memory;
    size_t size;
    MemoryStruct()
    {
        memory = (char *)malloc(1);
        size = 0;
    }
    ~MemoryStruct()
    {
        free(memory);
        memory = NULL;
        size = 0;
    }
};

size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
    size_t realsize = size * nmemb;
    struct MemoryStruct *mem = (struct MemoryStruct *)data;

    mem->memory = (char *)realloc(mem->memory, mem->size + realsize + 1);
    if (mem->memory) 
    {
        memcpy(&(mem->memory[mem->size]), ptr, realsize);
        mem->size += realsize;
        mem->memory[mem->size] = 0;
    }
    return realsize;
}

int main()
{
    CURLcode res = curl_global_init(CURL_GLOBAL_ALL);
    if(CURLE_OK != res)
    {
        cout<<"curl init failed"<return 1;
    }

    CURL *pCurl = NULL;
    pCurl = curl_easy_init();

    if( NULL == pCurl)
    {
        cout<<"Init CURL failed..."<return -1;
    }

    string url = "http://xx.xx.xx.xx:50070/dfshealth.html"; //      
    string filename = "dfshealth.html"; //     ,                 ,         

    curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, 3L);//      
    curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT, 10L); //       
    curl_easy_setopt(pCurl, CURLOPT_FOLLOWLOCATION, 1L);//     
    curl_easy_setopt(pCurl, CURLOPT_HEADER, 0L);  //   ,               
    curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);  //            

    MemoryStruct oDataChunk;  //         
    curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, &oDataChunk);

    curl_easy_setopt(pCurl, CURLOPT_NOSIGNAL, 1L); //        
    curl_easy_setopt(pCurl, CURLOPT_VERBOSE, 1L); //           
    curl_easy_setopt(pCurl, CURLOPT_URL, url.c_str() ); //     URL  

    curl_slist *pList = NULL;
    pList = curl_slist_append(pList,"Accept-Encoding:gzip, deflate, sdch"); 
    pList = curl_slist_append(pList,"Accept-Language:zh-CN,zh;q=0.8"); 
    pList = curl_slist_append(pList,"Connection:keep-alive");
    curl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, pList); 

    res = curl_easy_perform(pCurl);  //    

    long res_code=0;
    res=curl_easy_getinfo(pCurl, CURLINFO_RESPONSE_CODE, &res_code);

    //     ,             
    if(( res == CURLE_OK ) && (res_code == 200 || res_code == 201))
    {
        FILE* fTmpMem = (FILE*)oDataChunk.memory;
        if (!fTmpMem) {

        }

        FILE *fp=fopen(filename.c_str(),"wb");
        if(!fp)
        {   
            cout<<"open file failed";
            return -1;
        }   

        fwrite(fTmpMem, 1, oDataChunk.size, fp);
        fclose(fp);
        return true;
    }
    curl_slist_free_all(pList); 
    curl_easy_cleanup(pCurl);
    curl_global_cleanup();

    return 0;
}
コンパイル、実行:
# g++ -g getDataByCurl.cpp -o run -lcurl
# ./run
* About to connect() to xx.xx.xx.xx port 50070 (#0)
*   Trying xx.xx.xx.xx... * connected
* Connected to xx.xx.xx.xx (xx.xx.xx.xx) port 50070 (#0)
> GET /dfshealth.html HTTP/1.1
Host: xx.xx.xx.xx:50070
Accept: */*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:zh-CN,zh;q=0.8
Connection:keep-alive

< HTTP/1.1 200 OK
< Cache-Control: no-cache
< Expires: Tue, 17 Oct 2017 02:49:59 GMT
< Date: Tue, 17 Oct 2017 02:49:59 GMT
< Pragma: no-cache
< Expires: Tue, 17 Oct 2017 02:49:59 GMT
< Date: Tue, 17 Oct 2017 02:49:59 GMT
< Pragma: no-cache
< Content-Type: text/html; charset=utf-8
< Accept-Ranges: bytes
< Content-Length: 13320
< Last-Modified: Thu, 18 Aug 2016 01:49:57 GMT
< Server: Jetty(6.1.26)
< 
* Connection #0 to host xx.xx.xx.xx left intact
プログラムが実行されると、現在のディレクトリの下にdfshealthというファイルが作成されます。このファイルの内容は設定されたurlアドレスのページです。上記のコードでは、プログラムはウェブページ全体の結果を取得しようとしていますが、クライアントがマルチスレッドの場合は、必ずCURLOPT_を実行します。NOSIGNALは1にセットされます。構造体MemoryStructは、C URLを保存して実行した結果、CURLOPT_WRITEDATAは、このオブジェクトをコールバック関数に伝達し、コールバック関数WriteMemoryCallbackでは、戻り結果を格納空間に割り当て、メモリをメモリにコピーしてメモリに戻す。カーラーを通してイージー.getingfoは、curl実行結果のセッション情報を取得し、実行に成功したと判定した場合、クライアントは、MemoryStructオブジェクトの内容を指定ファイルに書き込む。
関連インターフェースとパラメータの説明:
CURL_EXTERN CURLcode curl_global_init(long flags);
この関数は、操作前のグローバル初期化に使用され、非スレッドセキュリティであり、他のすべてのlibcurl関数が呼び出される前に呼び出されるべきであり、一回だけ呼び出される。ユーザがこの関数を起動していない場合、その後にcurl_を呼び出します。イージー.init()を初期化すると、自動的にcurl_を呼び出します。global_init(CURLUGLOL BALULT)は、初期化された「global SSL stuff」を確保するため、lib/easy.cソースを参照してください。パラメータ:C URL_GLOOBAL_ALLはC URL_を初期化します。GLOOBAL_ACK_ENTR以外の全てのシステム。C URL_GLOOBAL_SSL初期化SSL C URL_GLOOBAL_WIN 32初期化Win 32 socket libries.C URL_GLOOBAL_NOTHINGは初期化されていません。GLOOBAL_DEFAULTはC URL_に相当します。GLOOBAL_ALL C URL_GLOOBAL_ACK_ENTRはこのラベルを設定した後、curlがデータ要求を接続している時や待っている時に、CrlはENTR条件を受信します。そうでないと、curlはずっと待ちます。戻り値:正常通過時は0を返し、非ゼロ値はエラーが発生したことを表します。
CURL_EXTERN void curl_global_cleanup(void);
この関数はグローバルのクリーンアップ作業に使用されます。libcurlを使用する各アプリケーションに対しては一回だけ呼び出すべきです。
CURL_EXTERN CURL *curl_easy_init(void);
外部インターフェースは、作成のために、他のCURLハンドルとして初期化されたCURLハンドルを割り当てて返す。easy関数の作用対象。
CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_TIMEOUT, long timeout);
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_TIMEOUT_MS, long timeout);
外部インターフェースは、C URLオブジェクトのオプションパラメータを設定するためのものである。上記のコードに含まれるいくつかのパラメータオプション:CURLOPT_TIMEOUT:一つの完全な要求のタイムアウト時間は長くて、前者の時間単位は秒で、後者はミリ秒です。CURLOPT_TIMEOUTとCURLOPT_TIMEOUTMSが設定されている場合、後ろの設定は前の設定を上書きします。
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_CONNECTTIMEOUT, long timeout);
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_CONNECTTIMEOUT_MS, long timeout);
CURLOPT_CONNEECTTIMEOUT:要求されたリンク段階のタイムアウト時に配置されています。時間の長いパラメータは上記のTIMEOUTと類似しています。
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_FOLLOWLOCATION, long enable);
CURLOPT_FOLLOWLOCATION:  enable        URL      ,               。

CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HEADER, long onoff);
CURLOPT_HEADER: onoff    1 ,   libcurl             。

CURLcode curl_easy_setopt(CURL *handle, CURLOPT_WRITEFUNCTION, write_callback);
CURLOPT_WRITEFUNCTION:            ,        :
size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata);

CURLcode curl_easy_setopt(CURL *handle, CURLOPT_WRITEDATA, void *pointer);
CURLOPT_WRITEDATA:        pointer,        write_callback

CURLcode curl_easy_setopt(CURL *handle, CURLOPT_NOSIGNAL, long onoff);
CURLOPT_NOSIGNAL:      ,       1。      unix                 timeout  ,               。

CURLcode curl_easy_setopt(CURL *handle, CURLOPT_VERBOSE, long onoff);
CURLOPT_VERBOSE:   onoff  1,                          。

CURLcode curl_easy_setopt(CURL *handle, CURLOPT_URL, char *URL);
CURLOPT_URL:   url  

curl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, pList); 
CURLOPT_HTTPHEADER:  HTTP      
その他のパラメータの詳細はソースコードを参照してください。"docs/libcurl/opts"
CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *,const char *);
 curl_slist       ,curl_slist_append()       ,          ,CUrl       "Get /     accept:*/*"       ,             ,   Http          。 curl_slist_append()  API                    。         ,                   。

CURL_EXTERN void curl_slist_free_all(struct curl_slist *);
      curl_slist   

CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
    ,    CURL  ,          

CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
 curl           。                long,char  double     ,         CURLE_OK ,                      。

CURL_EXTERN void curl_easy_cleanup(CURL *curl);
          curl easy  。     curl_easy_init()   handle