生活随笔
收集整理的這篇文章主要介紹了
利用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_HTTPHEADER, headers);curl_easy_setopt(curl, CURLOPT_URL,"http://www.baidu.com");curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); curl_easy_setopt(curl, CURLOPT_HEADERDATA, 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"); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "&logintype=uid&u=xieyan&psw=xxx86"); curl_easy_setopt(curl, CURLOPT_URL, " http://mail.sina.com.cn/cgi-bin/login.cgi "); curl_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;
CURLcode res; if(argc!=2){printf("Usage : file <url>;\n");exit(1);}curl = curl_easy_init(); if(curl!=NULL){curl_easy_setopt(curl, CURLOPT_URL, argv[1]); res = curl_easy_perform(curl);curl_easy_cleanup(curl);}return 0;
}
編譯
gcc get_html.c -o get_html -lcurl
運行
./get_html http://www.baidu.com
網頁下載保存
代碼
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>#include <curl/curl.h>
#include <curl/easy.h>FILE *fp;
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);}
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文件中。
斷點續傳
代碼
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>#include <curl/curl.h>
size_t getcontentlengthfunc(void *ptr, size_t size, size_t nmemb, void *stream) {int r;long len = 0;r = sscanf(ptr, "Content-Length: %ld\n", &len);if (r) *((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(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_URL, remotepath);curl_easy_setopt(curlhandle, CURLOPT_CONNECTTIMEOUT, timeout); curl_easy_setopt(curlhandle, CURLOPT_HEADERFUNCTION, getcontentlengthfunc);curl_easy_setopt(curlhandle, CURLOPT_HEADERDATA, &filesize);curl_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_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 , "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通讯网络的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。