libcurl 使用的幾個注意事項

來源:互聯網
上載者:User

標籤:curl   c   libcurl   文檔   linux   

0. 為使用的curl url 添加確定的協議頭

原文:
If you specify URL without protocol:// prefix, curl will attempt to guess what protocol you might want. It will then default to HTTP but try other protocols based on often-used host name prefixes. For example, for host names starting with "ftp." curl will assume you want to speak FTP.

1. 把 curl_easy_perform() 回調資料直接寫到檔案中(FILE *)

原文:
libcurl offers its own default internal callback that will take care of the data if you don‘t set the callback with CURLOPT_WRITEFUNCTION. It will then simply output the received data to stdout. You can have the default callback write the data to a different file handle by passing a ‘FILE *‘ to a file opened for writing with the CURLOPT_WRITEDATA option.
源碼中的實現:

這樣,就可以少寫一個回呼函數了(喂,你是有多懶啊),樣本如下

FILE *fp;fp = fopen("/root/test.bmp", "wb");...curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);...fclose(fp);

2. curl_easy_perform 返回值處理

使用 CURLOPT_ERRORBUFFER 儲存錯誤, buf_size=CURL_ERROR_SIZE
或使用 curl_easy_strerror(res) (感覺這個簡便)
樣本:

 /* Perform the request, res will get the return code */  res = curl_easy_perform(curl); /* Check for errors */  if(res != CURLE_OK) {   printf("%s curl_easy_perform() error! \n", __FUNCTION__);   printf("error msg = %s\n",  curl_easy_strerror(res));   return -1; }

3. 多線程環境配置 CURLOPT_NOSIGNAL

原文:
When using multiple threads you should set the CURLOPT_NOSIGNAL option to 1 for all handles. Everything will or might work fine except that timeouts are not honored during the DNS lookup - which you can work around by building libcurl with c-ares support. c-ares is a library that provides asynchronous name resolves. On some platforms, libcurl simply will not function properly multi-threaded unless this option is set.
對於 CURLOPT_TIMEOUT(預設0), CURLOPT_CONNECTTIMEOUT(預設300)選項:
In unix-like systems, this might cause signals to be used unless CURLOPT_NOSIGNAL is set.

4. 設定 CURLOPT_VERBOSE、CURLOPT_HEADER 的必要性

原文:
There‘s one golden rule when these things occur: set the CURLOPT_VERBOSE option to 1. It‘ll cause the library to spew out the entire protocol details it sends, some internal info and some received protocol data as well (especially when using FTP). If you‘re using HTTP, adding the headers in the received output to study is also a clever way to get a better understanding why the server behaves the way it does. Include headers in the normal body output with CURLOPT_HEADER set 1.
經實驗:
設定 curl_easy_setopt(curl, CURLOPT_HEADER, 1L) 後,回呼函數會返回 http頭相關資訊(原本是直接輸出到stdout的),考慮到還要過濾這些資訊,所以還是不要設定這個了

5. curl post 注意事項

原文:
Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue" header. You can disable this header with CURLOPT_HTTPHEADER as usual.
解釋:
當使用libcurl的POST方式時,如果POST資料的大小大於1024個位元組,libcurl不會直接發送POST請求,而是會分為兩步執行請求:
<1> 發送一個請求,該要求標頭部包含一個Expect: 100-continue的欄位,用來詢問server是否願意接受資料
<2> 當接收到從server返回的100-continue的應答後,它才會真正的發起POST請求,將資料發送給server。
對於“100-continue"這個欄位,RFC文檔(http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3)是這麼解釋的:
它可以讓用戶端在發送請求資料之前去判斷伺服器是否願意接收該資料,如果伺服器願意接收,用戶端才會真正發送資料,
這麼做的原因是如果用戶端直接發送請求資料,但是伺服器又將該請求拒絕的話,這種行為將帶來很大的資源開銷。
所以為了避免這種情況,libcurl在發送大於1024位元組的POST請求時採用了這種方法,但是相對的,它會引起請求延遲的加大,
另外並不是所有的server都會正確處理並且應答”100-continue“,比如lighttpd,就會返回417”Expectation Failed“,造成請求邏輯出錯。
解決辦法:

// POST資料的大於1024個位元組struct curl_slist *headerlist = NULL;static const char buf[] = "Expect:";headerlist = curl_slist_append(headerlist, buf); /* initalize custom header list */curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); /* set header*/curl_slist_free_all(headerlist); /* free slist */

6. 回呼函數的正確返回
return (size * nmemb);

原因:
Your callback function should return the number of bytes it "took care of". If that is not the exact same amount of bytes that was passed to it, libcurl will abort the operation and return with an error code.

如果回呼函數中接收的資料有誤,個人感覺可以返回0或者返回你已經處理的資料數,
因為源碼的處理如下:

 /* If the previous block of data ended with CR and this block of data is    just a NL, then the length might be zero */ // len 為要發送給回呼函數的資料長度 if(len) {   wrote = data->set.fwrite_func(ptr, 1, len, data->set.out); } else {   wrote = len; }if(wrote != len) {  failf(data, "Failed writing body (%zu != %zu)", wrote, len);  return CURLE_WRITE_ERROR;}

libcurl 使用的幾個注意事項

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.