1. 程式人生 > >Curl的移植編譯以及注意事項

Curl的移植編譯以及注意事項

     最近需要用curl來發送http請求,遇到了不少問題,查了不少資料,都是零零散散的,現在總結下。

     1、移植編譯

      1 ./configure --prefix=$(PWD)/build --host=arm-XXX-linux;make ;make install 

      這步基本都沒有問題,生成的動態連結庫libcurl.a,可以直接給應用程式去使用。

    2、API使用

      1)全域性初始化 curl_global_init(CURL_GLOBAL_ALL);

      2)通過curl_easy_init得到一個CURL指標m_pCurl

      3)通過curl_formadd封裝引數

          通過curl_easy_setopt設定各種選項

         通過curl_easy_perform執行curl的各種操作

     4)curl_easy_getinfo 獲得http返回的狀態碼

     5)curl_easy_cleanup釋放CURL指標

     6)curl_global_cleanup釋放全域性物件

  3、http的響應內容獲取

   先通過 curl_easy_setopt設定CURLOPT_WRITEFUNCTION,CURLOPT_WRITEDATA選項

size_t ReviceData(char *buffer, size_t size, size_t nmemb, std::stringstream & stream)
{

    size_t total = size * nmemb;
    std::string str = "";
    if (total)
    {
        str.append(buffer, total);
    }

    stream << str.c_str();

    return total;
}


std::stringstream out;

curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, ReviceData);

curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA, &out);

 

    當有響應回來的時候,會觸發ReviceData函式,在這個回撥函式,會把響應的內容,賦值給out變數,這樣響應就取得了。

 

    4、遇到的一些問題

    curl_easy_setopt(m_pCurl, CURLOPT_CONNECTTIMEOUT, 4L);
    curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT, 25L);

    設定了超時時間後(一個是等待連線的時間,一個是等待接收響應的時間)一旦域名解析失敗,程式會莫名的掛掉,而且每次掛掉的地方都不一樣。當時也是通過一點一點註釋程式碼,才定位到這兩行程式碼。

    coredump的原因是因為curl的DNS解析超時控制是使用SIGALARM實現的。

    這樣導致發現SIGALARM會出現多執行緒修改同一個全域性變數,由此產生了COREDUMP。

    問題發生的前提是設定了CURLOPT_TIMEOUT或CURLOPT_CONNECTTIMEOUT,並且值不為0。

  解決辦法:
   1) 設定CURLOPT_NOSIGNAL的值為1

    curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1);

     設定之後,發現的確不會coredump了,但是設定的超時時間沒有用了,需要等很久,才能出結果。

 
   2) 使用c-ares(configure時指定引數--enable-ares)

    使用這個方法比較好,不會coredump,而且超時時間設定後生效。

    下面介紹下這個方法:

     a、下載cares的原始碼,進行編譯移植

     https://c-ares.haxx.se/

     編譯方法和curl的編譯方法類似,都是通過configure ,最終生成libcares.a

    b、修改curl原始碼裡的configure檔案

     找到下面的程式碼,新增embedded_ares="yes",箭頭所指的地方,不然check

的時候,會報c-ares library defective or too old

   

     c、重新編譯curl

./configure --enable-ares=$(PWD)/depends --prefix=$(PWD)/build --host=arm-XXX-linux;make ;make install

 

這裡指定了enable-ares使用的libares所在的目錄。depends目錄下需要再建立一個子目錄lib,在子目錄下放入libcares.a即可。

 還要把libcares的標頭檔案都拷貝到curl主目錄裡的lib目錄裡,這樣編譯就不會出錯了。

&n