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選項

struct CResponseResult
{
      int m_iResponseSize;                                // 響應的實際大小
      char* m_p_responseBuffer;                           // 指向響應內存的指針
};

size_t ReviceData(char *buffer, size_t size, size_t nmemb, CResponseResult & stream) { size_t total = size * nmemb;
    if (total <= 0 || (stream.m_iResponseSize + total) > MAX_RESPONSE_DATA_BUF_SIZE)
    {
        return 0;
    }

    memcpy(&stream.m_p_responseBuffer[stream.m_iResponseSize], buffer, total);
    stream.m_iResponseSize += total;
    return total; }
// 每次發請求前,把buffer清空下
memset(m_ResponseResult.m_p_responseBuffer, 0, MAX_RESPONSE_DATA_BUF_SIZE);
m_ResponseResult.m_iResponseSize = 0;
curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, ReviceData); curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA,
&m_ResponseResult);

    當有響應回來的時候,會觸發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目錄里,這樣編譯就不會出錯了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM