日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

利用libcurl库进行http通讯网络

發布時間:2024/1/1 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 利用libcurl库进行http通讯网络 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 一、了解libcurl
  • 二、通過實例認識libcurl
  • 三、總結
  • 四、參考資料

本文章使用的是Ubuntu18.04來完成程序編譯運行。

一、了解libcurl

  • libcurl是什么
    libcurl是一個跨平臺的網絡協議庫,支持http, https, ftp, gopher, telnet, dict, file, ldap 協議等。
    libcurl同樣支持HTTPS證書授權,HTTP POST, HTTP PUT, FTP 上傳, HTTP基本表單上傳,代理,cookies,用戶認證等。

  • libcurl基本函數
    ①CURLcode curl_global_init(long flags)
    這個函數只能用一次。

    參數:flags
    CURL_GLOBAL_ALL //初始化所有的可能的調用。
    CURL_GLOBAL_SSL //初始化支持 安全套接字層。
    CURL_GLOBAL_WIN32 //初始化win32套接字庫。
    CURL_GLOBAL_NOTHING //沒有額外的初始化。

    ②void curl_global_cleanup(void)
    在結束libcurl使用的時候,用來對curl_global_init做的工作清理。類似于clean。
    ③char *curl_version( )
    打印當前libcurl庫的版本。
    ④CURL *curl_easy_init( )
    用來初始化一個CURL的指針, 相應的在調用結束時要用curl_easy_cleanup函數清理。
    ⑤void curl_easy_cleanup(CURL *handle);
    用來結束一個會話。

    參數:
    CURL類型的指針。

    ⑥CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);
    用于告訴curl庫程序將有如何的行為。

    參數:
    CURL類型的指針。
    各種CURLoption類型的選項。
    parameter 這個參數 既可以是個函數的指針,也可以是某個對象的指針,也可以是個long型的變量.它用什么這取決于第二個參數。
    CURLoption 這個參數的取值很多。

  • 利用libcurl完成傳輸任務的流程
    ①調用curl_global_init()初始化libcurl
    ②調用curl_easy_init()函數得到 easy interface型指針
    ③調用curl_easy_setopt()設置傳輸選項
    ④根據curl_easy_setopt()設置的傳輸選項,實現回調函數以完成用戶特定任務
    ⑤調用curl_easy_perform()函數完成傳輸任務
    ⑥調用curl_easy_cleanup()釋放內存

    注意:curl_easy_setopt()極其重要。

  • 二、通過實例認識libcurl

  • 基本的http GET/POST操作
    代碼

    #include <stdio.h> #include <curl/curl.h> bool getUrl(char *filename) {CURL *curl;CURLcode res;FILE *fp;if ((fp = fopen(filename, "w")) == NULL) // 返回結果用文件存儲return false;struct curl_slist *headers = NULL;headers = curl_slist_append(headers, "Accept: Agent-007");curl = curl_easy_init(); // 初始化if (curl){//curl_easy_setopt(curl, CURLOPT_PROXY, "10.99.60.201:8080");// 代理curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);// 改協議頭curl_easy_setopt(curl, CURLOPT_URL,"http://www.baidu.com");curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); //將返回的http頭輸出到fp指向的文件curl_easy_setopt(curl, CURLOPT_HEADERDATA, fp); //將返回的html主體數據輸出到fp指向的文件res = curl_easy_perform(curl); // 執行if (res != 0) {curl_slist_free_all(headers);curl_easy_cleanup(curl);}fclose(fp);return true;} } bool postUrl(char *filename) {CURL *curl;CURLcode res;FILE *fp;if ((fp = fopen(filename, "w")) == NULL)return false;curl = curl_easy_init();if (curl){curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt"); // 指定cookie文件curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "&logintype=uid&u=xieyan&psw=xxx86"); // 指定post內容//curl_easy_setopt(curl, CURLOPT_PROXY, "10.99.60.201:8080");curl_easy_setopt(curl, CURLOPT_URL, " http://mail.sina.com.cn/cgi-bin/login.cgi "); // 指定urlcurl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);res = curl_easy_perform(curl);curl_easy_cleanup(curl);}fclose(fp);return true; } int main(void) {getUrl("/tmp/get.html");postUrl("/tmp/post.html"); }

    編譯

    gcc get_post.c -o get_post –curl


    解決方式

    gcc get_post.c -o get_post


    將代碼中的bool修改成int,false修改為0,true修改為1。

    將編譯語句修改

    gcc get_post.c -o get_post –curl

    運行

    ./get_post

    運行后get.html文件內容如下
    post.html文件內容為空。

  • 獲取html網頁
    代碼

    #include <stdio.h> #include <curl/curl.h> #include <stdlib.h> int main(int argc, char *argv[]) {CURL *curl; //定義CURL類型的指針 CURLcode res; //定義CURLcode類型的變量,保存返回狀態碼if(argc!=2){printf("Usage : file <url>;\n");exit(1);}curl = curl_easy_init(); //初始化一個CURL類型的指針if(curl!=NULL){//設置curl選項. 其中CURLOPT_URL是讓用戶指 定url. argv[1]中存放的命令行傳進來的網址curl_easy_setopt(curl, CURLOPT_URL, argv[1]); //調用curl_easy_perform 執行我們的設置.并進行相關的操作. 在這 里只在屏幕上顯示出來.res = curl_easy_perform(curl);//清除curl操作.curl_easy_cleanup(curl);}return 0; }

    編譯

    gcc get_html.c -o get_html -lcurl

    運行

    ./get_html http://www.baidu.com

  • 網頁下載保存
    代碼

    // 采用CURLOPT_WRITEFUNCTION 實現網頁下載保存功能 #include <stdio.h> #include <stdlib.h> #include <unistd.h>#include <curl/curl.h> //#include <curl/types.h> #include <curl/easy.h>FILE *fp; //定義FILE類型指針 //這個函數是為了符合CURLOPT_WRITEFUNCTION而構造的 //完成數據保存功能 size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream) {int written = fwrite(ptr, size, nmemb, (FILE *)fp);return written; }int main(int argc, char *argv[]) {CURL *curl;curl_global_init(CURL_GLOBAL_ALL); curl=curl_easy_init();curl_easy_setopt(curl, CURLOPT_URL, argv[1]); if((fp=fopen(argv[2],"w"))==NULL){curl_easy_cleanup(curl);exit(1);} //CURLOPT_WRITEFUNCTION 將后繼的動作交給write_data函數處理curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_perform(curl);curl_easy_cleanup(curl);exit(0); }

    編譯

    gcc save_html.c -o save_html -lcurl

    運行

    ./save_html http://www.baidu.com ./baidu
    將百度的網頁html保存到當前文件夾的baidu文件中。

  • 斷點續傳
    代碼

    //采用CURLOPT_RESUME_FROM_LARGE 實現文件斷點續傳功能 #include <stdlib.h> #include <stdio.h> #include <sys/stat.h>#include <curl/curl.h> //這個函數為CURLOPT_HEADERFUNCTION參數構造 /* 從http頭部獲取文件size*/ size_t getcontentlengthfunc(void *ptr, size_t size, size_t nmemb, void *stream) {int r;long len = 0;/* _snscanf() is Win32 specific */// r = _snscanf(ptr, size * nmemb, "Content-Length: %ld\n", &len);r = sscanf(ptr, "Content-Length: %ld\n", &len);if (r) /* Microsoft: we don't read the specs */*((long *) stream) = len;return size * nmemb; }/* 保存下載文件 */ size_t wirtefunc(void *ptr, size_t size, size_t nmemb, void *stream) {return fwrite(ptr, size, nmemb, stream); }/*讀取上傳文件 */ size_t readfunc(void *ptr, size_t size, size_t nmemb, void *stream) {FILE *f = stream;size_t n;if (ferror(f))return CURL_READFUNC_ABORT;n = fread(ptr, size, nmemb, f) * size;return n; }// 下載 或者上傳文件函數 int download(CURL *curlhandle, const char * remotepath, const char * localpath,long timeout, long tries) {FILE *f;curl_off_t local_file_len = -1 ;long filesize =0 ;CURLcode r = CURLE_GOT_NOTHING;int c;struct stat file_info;int use_resume = 0;/* 得到本地文件大小 *///if(access(localpath,F_OK) ==0)if(stat(localpath, &file_info) == 0) {local_file_len = file_info.st_size;use_resume = 1;}//采用追加方式打開文件,便于實現文件斷點續傳工作f = fopen(localpath, "ab+"); if (f == NULL) {perror(NULL);return 0;}//curl_easy_setopt(curlhandle, CURLOPT_UPLOAD, 1L);curl_easy_setopt(curlhandle, CURLOPT_URL, remotepath);curl_easy_setopt(curlhandle, CURLOPT_CONNECTTIMEOUT, timeout); // 設置連接超時,單位秒//設置http 頭部處理函數curl_easy_setopt(curlhandle, CURLOPT_HEADERFUNCTION, getcontentlengthfunc);curl_easy_setopt(curlhandle, CURLOPT_HEADERDATA, &filesize);// 設置文件續傳的位置給libcurlcurl_easy_setopt(curlhandle, CURLOPT_RESUME_FROM_LARGE, use_resume?local_file_len:0);curl_easy_setopt(curlhandle, CURLOPT_WRITEDATA, f);curl_easy_setopt(curlhandle, CURLOPT_WRITEFUNCTION, wirtefunc);//curl_easy_setopt(curlhandle, CURLOPT_READFUNCTION, readfunc);//curl_easy_setopt(curlhandle, CURLOPT_READDATA, f);curl_easy_setopt(curlhandle, CURLOPT_NOPROGRESS, 1L);curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1L);r = curl_easy_perform(curlhandle);fclose(f);if (r == CURLE_OK)return 1;else {fprintf(stderr, "%s\n", curl_easy_strerror(r));return 0;} }int main(int c, char **argv) {CURL *curlhandle = NULL;curl_global_init(CURL_GLOBAL_ALL);curlhandle = curl_easy_init();//download(curlhandle, "ftp://user:pass@host/path/file", "C:\\file", 0, 3);download(curlhandle , "https://sunlight-dazzling.github.io/file/introduce.txt","./index.asp",1,3);curl_easy_cleanup(curlhandle);curl_global_cleanup();return 0; }

    編譯

    gcc resume.c -o resume -lcurl

    運行

    ./resume


    在當前目錄下可以看到對應下載的文件。

  • 三、總結

    通過幾個實際例子,可以清楚看出libcurl在獲取http網址的網頁信息上,是比較方便的。其中,幾個實例中,比較難理解應該是斷點續傳。斷點續傳指的是將下載或上傳任務(一個文件或一個壓縮包)人為的劃分為幾個部分,每一個部分采用一個線程進行上傳或下載,當碰到網絡故障,可以從已經上傳或下載的部分開始繼續上傳下載未完成的部分,而沒有必要從頭開始上傳下載。這樣的方式可以幫助用戶節省時間,提高下載或上傳的速度。要想更加深入了解libcurl,還需要看更多的資料,才能夠正在理解libcurl。

    四、參考資料

    C++ 用libcurl庫進行http通訊網絡編程

    總結

    以上是生活随笔為你收集整理的利用libcurl库进行http通讯网络的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。