CURL使用

最近開發的遊戲之中需要用到大量的客戶端與服務端交互的 東西,開始參考大量的技術文章,感覺是五花八門,眼花繚亂。到後面,真正感受到,學習一門技術,還是需要從它最開始的東西開始學起,要不就是一頭霧水,這種感覺實在是太難受了。而且建議要學習技術的人,直接去官網學習,反而是最高效的途徑。

curl的官網地址是:http://curl.haxx.se/

好的,現在開始介紹下curl這個強大的工具。

curl是一個基於命令行的應用工具,提供利用URL標準進行文件傳輸的功能。目前已經支持非常多的流行的互聯網協議,如:FTP, FTPS, HTTP, HTTPS, SCP, SFTP, TFTP, TELNET, DICT, LDAP, LDAPS and FILE等。curl支持SSL認證,HTTP POST/PUT,FTP上傳,HTTP上傳、代理、cookies、用戶+密碼認證、文件續傳、代理管道等一系列強大功能。curl是用C語言寫的,但是綁定了很多開發語言。大體上可以把curl分成命令行工具和libcurl庫兩個部分,命令行工具可以直接輸入指令完成相應功能,libcurl則是一個客戶端URL傳輸庫,是線程安全且兼容IPv6,可以非常方便地用來做相關開發。

    curl可以使用命令行直接操作,也可以使用libcurl庫進行上層應用的開發。我們這裏主要講解libcurl庫的使用。使用環境是mac系統,xcode編譯環境和cocos2d-X遊戲引擎。

   libcurl提供了一組C語言API函數直接調用。首先需要提到的兩個函數就是curl_global_init()和curl_global_cleanup()。libcurl要用到一系列的全局常量,curl_global_init()函數就是初始化這些變量,並分配一些全局資源;curl_global_cleanup()則負責釋放這些資源。因此一般情況下,在調用libcurl函數之前,先用curl_global_init(CURL_GLOBAL_ALL)做初始化,在調用完畢後,用curl_global_cleanup()

退出。需要注意的是,這些全局變量和資源並不是線程安全的,因此,在多線程應用的環境中,最好不要多次調用curl_global_init()和curl_global_cleanup(),調用其他函數並不會改變這些全局變量和資源。
libcurl支持3種不同的接口調用方式,分別是"easy"、"multi"和"share"模式。libcurl-easy是一組同步接口,函數都是curl_easy_*形式,這種模式調用curl_easy_perform()函數進行URL數據傳輸,直到傳輸完成函數才返回;libcurl-multi是一組異步接口,函數都是curl_multi_*形式,調用curl_multi_perform()函數進行傳輸,但是每次調用只傳一片數據,我們可以用select()函數控制多個下載任務進行同步下載,來實現在一個線程中同時下載多個文件;libcurl-share允許在多線程中操作共享數據。下面以libcurl-easy爲例講一下libcurl的函數。

1、CURL *curl_easy_init()
此函數需要最先被調用,返回CRUL easy句柄;後續其他函數調用都要用到這個句柄。如果沒有調用curl_global_init(),該函數自動調用,但是考慮到線程安全的問題,最好自己調用curl_global_init()。



2、CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter)
所有參數和選項設置都是通過這個函數完成的,它告訴libcurl怎樣去進行傳輸。參數handle即爲curl_easy_init()返回的句柄,後面根據option的類型,設置相應的parameter值,該函數每次調用只能設置一個選項。具體的option講解在這篇博文中有較全面的介紹:

CURLOPT_URL
字符串類型,該選項設置要處理的URL地址,該選項是進行curl_easy_perform之前唯一必須要設置的選項。

CURLOPT_COOKIE
字符串類型,設置http頭中的cookie信息。

CURLOPT_COOKIEFILE
字符串類型,同CURLOPT_COOKIE,不過cookie信息從文件中讀取。

CURLOPT_FOLLOWLOCATION
布爾值類型,該參數設置爲非零值表示follow服務器返回的重定向信息。

CURLOPT_POSTFIELDS
字符串類型,提交http的post操作字符串數據。

CURLOPT_TIMEOUT
long數值類型,設置函數執行的最長時間,時間單位爲s。

CURLOPT_CONNECTTIMEOUT
long數值類型,設置連接服務器最長時間,時間單位爲s;當置爲0時表示無限長。

CURLOPT_MAX_RECV_SPEED_LARGE
curl_off_t類型數據,指定下載過程中最大速度,單位bytes/s。

CURLOPT_HEADERFUNCTION
函數指針類型,該選項設置一個處理接收到的header數據的回調函數,函數原型爲:
size_t function( void *ptr, size_t size, size_t nmemb, void *stream);
其中,ptr指向接收到的header頭數據,數據大小爲size*nmemb,stream指向調用CURLOPT_WRITEHEADER選項設置的參數。該回調函數應返回實際處理的數據量大小,或者出錯返回-1。



CURLOPT_WRITEFUNCTION
函數指針類型,該選項設置一個處理接收到的下載數據的回調函數,函數原型爲:
size_t function( void *ptr, size_t size, size_t nmemb, void *stream);
其中,ptr指向接收到的數據,數據大小爲size*nmemb,stream指向調用CURLOPT_WRITEDATA選項設置的參數。
如果函數指針置爲NULL,則會調用默認的函數,將數據寫入到由CURLOPT_WRITEDATA指定的FILE*中。

CURLOPT_HTTPHEADER
curl_slist結構體類型,該選項自定義請求頭信息。

CURLOPT_NOPROGRESS
布爾值類型,設置該值爲非零值關閉PHP爲CRUL傳輸顯示的進度條。

3、void curl_easy_reset(CURL *handle )
重新初始化CURL句柄的選項設置。

4、CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ... )
查詢CRUL會話的內部信息,具體說明請參考curl自帶文檔。

5、void curl_easy_cleanup(CURL * handle )
該函數與curl_easy_init函數成對出現,handle即爲調用curl_easy_init返回的句柄。該函數在CURL會話結束退出時調用,之後handle無效。

一:LibCurl 編程流程
1.調用curl_global_init()初始化libcurl
2.調用 curl_easy_init()函數得到 easy interface型指針
3.調用curl_easy_setopt設置傳輸選項
4.根據curl_easy_setopt設置的傳輸選項,實現回調函數以完成用戶特定任務
5.調用curl_easy_perform()函數完成傳輸任務
6.調用curl_easy_cleanup()釋放內存

二:重要函數
1、CURLcode curl_global_init(long flags); //初始化libcurl
描述:這個函數只能用一次。(其實在調用curl_global_cleanup 函數後仍然可再用),如果這個函數在curl_easy_init函數調用時還沒調用,它全由libcurl庫自動完成。
參數:flags
CURL_GLOBAL_ALL //初始化所有的可能的調用。
CURL_GLOBAL_SSL //初始化支持 安全套接字層。
CURL_GLOBAL_WIN32 //初始化win32套接字庫。
CURL_GLOBAL_NOTHING //沒有額外的初始化。

2、void curl_global_cleanup(void);
描述:在結束libcurl使用的時候,用來對curl_global_init做的工作清理。類似於close的函數。

3、char *curl_version( );
描述: 打印當前libcurl庫的版本。

4、CURL *curl_easy_init( ); //得到 easy interface型指針
描述:curl_easy_init用來初始化一個CURL的指針(有些像返回FILE類型的指針一樣). 相應的在調用結束時要用curl_easy_cleanup函數清理.
一般curl_easy_init意味着一個會話的開始. 它的返回值一般都用在easy系列的函數中.
5、void curl_easy_cleanup(CURL *handle); //釋放內存
描述:這個調用用來結束一個會話.與curl_easy_init配合着用.
參數:CURL類型的指針.

6、CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter); //設置的傳輸選項,實現回調函數以完成用戶特定任務
描述: 這個函數最重要了.幾乎所有的curl 程序都要頻繁的使用它.它告訴curl庫.程序將有如何的行爲. 比如要查看一個網頁的html代碼等.(這個函數有些像ioctl函數)參數:
(1) CURL類型的指針
(2) 各種CURLoption類型的選項.(都在curl.h庫裏有定義,man 也可以查看到)
(3) parameter 這個參數既可以是個函數的指針,也可以是某個對象的指針,也可以是個long型的變量.它用什麼這取決於第二個參數.
(4) CURLoption 這個參數的取值很多.具體的可以查看man手冊.

7、CURLcode curl_easy_perform(CURL *handle); //完成傳輸任務;返回0意味一切ok,非0代表錯誤發生
描述:這個函數在初始化CURL類型的指針 以及curl_easy_setopt完成後調用. 就像字面的意思所說perform就像是個舞臺.讓我們設置的option 運作起來.
參數:CURL類型的指針.
補充:
(1)在連接過程中,如果出現異常,如網線拔掉,返回CURLE_COULDNT_CONNECT;
(2)在下載過程中,即已經連接上了,後面如果出現異常,如網線拔掉,返回CURLE_OPERATION_TIMEOUTED

8、curl_slist_append(struct curl_slist * list, const char * string ); //add a string to an slist
9、curl_slist_free_all(slist); // free the list again
10、curl_formadd(struct curl_httppost ** firstitem, struct curl_httppost ** lastitem, …) //add a section to a multipart/formdata HTTP POST

11、其它
/****************************************************************/
libcurl note(Http應用)
設置Callback function處理Http頭,返回內容,進度
CURLOPT_WRITEFUNCTION
CURLOPT_WRITEDATA
CURLOPT_HEADERFUNCTION
CURLOPT_HEADERDATA
CURLOPT_NOPROGRESS
CURLOPT_PROGRESSFUNCTION
CURLOPT_PROGRESSDATA

設置連接等待時間,傳輸等待時間:

CURLOPT_TIMEOUT:
CURLOPT_CONNECTIONTIMEOUT:

設置重定位URL:

CURLOPT_FOLLOWLOCATION

實現斷點續傳:
CURLOPT_RANGE:
CURLOPT_RESUME_FROM:

CURLOPT_RANGE:
CURLOPT_RESUME_FROM:
注: 在我的測試中 這兩個參數無效。

設置RANGE後 下載全部數據,而不是後續數據;

設置RESUME_FROM後,程序無響應。

Http頭設置:
Range: bytes=xx- [可以用來實現斷點續傳]
User-Agent: xx
Location: [網頁重定位 url]
Set-Cookie: [Cookie]
Content-Length: [報文長度]
Content-Type: [報文類型]
/****************************************************************/

三:應用實例
1、爲什麼要使用libcurl,
(1)作爲http的客戶端,可以直接用socket連接服務器,然後對到的數據進行http解析,但要分析協議頭,實現代理…這樣太麻煩了。
(2)libcurl是一個開源的客戶端url傳輸庫,支持FTP,FTPS,TFTP,HTTP,HTTPS,GOPHER,TELNET,DICT,FILE和LDAP,支持Windows,Unix,Linux等平臺,簡單易用,且庫文件佔用空間不到200K。

2、get和post方式
客戶端在http連接時向服務提交數據的方式分爲get和post兩種
(1)Get方式將所要傳輸的數據附在網址後面,然後一起送達服務器,它的優點是效率比較高;缺點是安全性差、數據不超過1024個字符、必須是7位的ASCII編碼;查詢時經常用此方法。
(2)Post通過Http post處理髮送數據,它的優點是安全性較強、支持數據量大、支持字符多;缺點是效率相對低;編輯修改時多使用此方法。

3、cookie與session
(1)cookie是發送到客戶瀏覽器的文本串句柄,並保存在客戶機硬盤上,可以用來在某個Web站點會話之間持久地保持數據。cookie在客戶端。
(2)session是訪問者從到達某個特定主頁到離開爲止的那段時間。每一訪問者都會單獨獲得一個session,實現站點多個用戶之間在所有頁面中共享信息。session在服務器上。
(3)libcurl中使用cookie,保存cookie, 使之後的鏈接與此鏈接使用相同的cookie
(3.1)在關閉鏈接的時候把cookie寫入指定的文件: curl_easy_setopt(curl, CURLOPT_COOKIEJAR, “/tmp/cookie.txt”);
(3.2)取用現在有的cookie,而不重新得到cookie: curl_easy_setopt(curl, CURLOPT_COOKIEFILE, “/tmp/cookie.txt”);

4、http與https的區別
(1)Http是明文發送,任何人都可以攔截並讀取內容
(2)Https是加密傳輸協議,用它傳輸的內容都是加密過的,https是http的擴展,其安全基礎是SSL協議
5、base64編碼
(1)如果要傳一段包含特殊字符比較多的數據,直接上傳就需要處理轉意符之類的很多問題,用base64編碼,它可以把數據轉成可讀的字串,base64由a-z, A-Z, +/總計64個字符組成。
(2)由於base64的組成部分有加號,而加號是url中的轉意字符,所以無論是get方式還是post,傳到服務器的過程中,都會把加號轉成空格,所以在傳base64之前需要把base64編碼後的加號替換成”%2B”,這樣就可以正常發送了。

6、curl_setop()函數中的參數中文說明

curl_setopt()函數將爲一個CURL會話設置選項。option參數是你想要的設置,value是這個選項給定的值。下列選項的值將被作爲長整形使用(在option參數中指定)
代碼例程

轉自:http://www.cnblogs.com/hewei2012/archive/2013/09/08/3308983.html

http://www.cnblogs.com/hewei2012/archive/2013/09/08/3308997.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章