最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

C++ LibCurl 庫的使用方法

2023-08-24 10:23 作者:bili_42682284418  | 我要投稿

LibCurl是一個開源的免費的多協(xié)議數(shù)據(jù)傳輸開源庫,該框架具備跨平臺性,開源免費,并提供了包括HTTP、FTPSMTP、POP3等協(xié)議的功能,使用libcurl可以方便地進行網(wǎng)絡數(shù)據(jù)傳輸操作,如發(fā)送HTTP請求、下載文件、發(fā)送電子郵件等。它被廣泛應用于各種網(wǎng)絡應用開發(fā)中,特別是涉及到數(shù)據(jù)傳輸?shù)膱鼍啊?/p>

  • ??下載地址:https://curl.haxx.se/download.html

首先讀者需要自行下載該庫,如下筆者選擇下載curl-8.0.1.zip這個源代碼版本,讀者可找到如下頁面,并點擊對應版本完成下載,當下載好以后讀者可自行將其解壓縮到任意目錄下。

當讀者解壓縮后,可打開VS2013 開發(fā)人員命令提示并切換帶該目錄中的curl-8.0.1\winbuild目錄,通過執(zhí)行如下兩條命令即可分別實現(xiàn)編譯靜態(tài)庫或動態(tài)庫,我們以靜態(tài)庫編譯為主,執(zhí)行如下命令讀者可自行等待一段時間。

  • ??動態(tài)庫: nmake /f Makefile.vc mode=dll VC=13 MACHINE=x86 DEBUG=no

  • ??靜態(tài)庫: nmake / f Makefile.vc mode = static VC = 13 ENABLE_IDN = no MACHINE = x86 DEBUG = no

這個庫在編譯通過后會自動生成文件到builds\libcurl-vc13-x86-release-static-ipv6-sspi-schannel目錄內(nèi),讀者可自行打開該目錄,即可看到該目錄內(nèi)的頭文件以及庫目錄文件,如下圖所示;

讀者可自行配置這個靜態(tài)庫,通常只需要配置includelib文件即可,該庫的使用很簡單,首先我們需要調(diào)用curl_easy_init()函數(shù)對CURL對象進行初始化,接著通過調(diào)用curl_easy_setopt()并傳入一個訪問URL鏈接,當訪問成功后則可調(diào)用curl_easy_perform()函數(shù)得到訪問結果,這就是該庫基本使用方法,如下代碼。

#define?CURL_STATICLIB
#define?BUILDING_LIBCURL
#include?<iostream>
#include?"curl/curl.h"

#pragma?comment?(lib,"libcurl_a.lib")
#pragma?comment?(lib,"wldap32.lib")
#pragma?comment?(lib,"ws2_32.lib")
#pragma?comment?(lib,"Crypt32.lib")

using?namespace?std;

int?main(int?argc,?char?*argv[])
{
????CURL?*curl;
????CURLcode?res;
????curl?=?curl_easy_init();
????if?(curl)
????{
????????curl_easy_setopt(curl,?CURLOPT_URL,?"https://www.lyshark.com");
????????res?=?curl_easy_perform(curl);
????????curl_easy_cleanup(curl);
????}

????std::cout?<<?"返回狀態(tài):?"?<<?res?<<?std::endl;

????system("pause");
????return?0;
}

運行上述代碼,讀者可看到網(wǎng)站www.lyshark.com的源代碼,如下圖所示;

上述代碼中的curl_easy_setopt()函數(shù)第二個參數(shù)可以使用多種類型的變量定義,我們可以通過傳入不同的常量來定義請求頭中的參數(shù),例如當我們需要修改協(xié)議頭時,可以使用CURLOPT_HTTPHEADER常量,并在其后第三個參數(shù)中傳入該常量所對應的結構即可,這個結構體定義有許多類型,具體如下下表所示;

常量名稱描述CURLINFO_EFFECTIVE_URL最后一個有效的URL地址CURLINFO_HTTP_CODE最后一個收到的HTTP代碼CURLINFO_FILETIME遠程獲取文檔的時間,如果無法獲取,則返回值為-1CURLINFO_TOTAL_TIME最后一次傳輸所消耗的時間CURLINFO_NAMELOOKUP_TIME名稱解析所消耗的時間CURLINFO_CONNECT_TIME建立連接所消耗的時間CURLINFO_PRETRANSFER_TIME從建立連接到準備傳輸所使用的時間CURLINFO_STARTTRANSFER_TIME從建立連接到傳輸開始所使用的時間CURLINFO_REDIRECT_TIME在事務傳輸開始前重定向所使用的時間CURLINFO_SIZE_UPLOAD以字節(jié)為單位返回上傳數(shù)據(jù)量的總值CURLINFO_SIZE_DOWNLOAD以字節(jié)為單位返回下載數(shù)據(jù)量的總值CURLINFO_SPEED_DOWNLOAD平均下載速度CURLINFO_SPEED_UPLOAD平均上傳速度CURLINFO_HEADER_SIZEheader部分的大小CURLINFO_HEADER_OUT發(fā)送請求的字符串CURLINFO_REQUEST_SIZE在HTTP請求中有問題的請求的大小CURLINFO_SSL_VERIFYRESULT通過設置CURLOPT_SSL_VERIFYPEER返回的SSL證書驗證請求的結果CURLINFO_CONTENT_LENGTH_DOWNLOAD從Content-Length: field中讀取的下載內(nèi)容長度CURLINFO_CONTENT_LENGTH_UPLOAD上傳內(nèi)容大小的說明CURLINFO_CONTENT_TYPE下載內(nèi)容的Content-Type:值,NULL表示服務器沒有發(fā)送有效的Content-Type:header

如下案例是一個簡單的GET請求封裝,通過調(diào)用GetStatus()函數(shù)實現(xiàn)對特定頁面發(fā)起請求的功能,其中curl_slist_append()用于增加新的請求頭數(shù)據(jù),在調(diào)用curl_easy_setopt()函數(shù)時,分別傳入了CURLOPT_HTTPHEADER設置請求頭,CURLOPT_WRITEFUNCTION設置回調(diào),CURLINFO_PRIMARY_IP獲取目標IP地址,CURLINFO_RESPONSE_CODE獲取目標返回代碼,此處的write_data()函數(shù)直接返回0則表示屏蔽所有的頁面輸出內(nèi)容。

#define?CURL_STATICLIB
#define?BUILDING_LIBCURL
#include?<iostream>
#include?"curl/curl.h"

#pragma?comment?(lib,"libcurl_a.lib")
#pragma?comment?(lib,"wldap32.lib")
#pragma?comment?(lib,"ws2_32.lib")
#pragma?comment?(lib,"Crypt32.lib")

using?namespace?std;

//?設置CURLOPT_WRITEFUNCTION回調(diào)函數(shù),返回為空屏蔽輸出
static?size_t?write_data(char?*d,?size_t?n,?size_t?l,?void?*p)
{
????return?0;
}

//?獲取網(wǎng)站返回值
void?GetStatus(char?*UrlPage)
{
????CURLcode?return_code;

????//?初始化模塊
????return_code?=?curl_global_init(CURL_GLOBAL_WIN32);
????if?(CURLE_OK?!=?return_code)
????{
????????return;
????}

????//?初始化填充請求頭
????struct?curl_slist?*headers?=?NULL;
????headers?=?curl_slist_append(headers,?"User-Agent:?Mozilla/5.0?(Windows?NT?10.0;?Win64;?x64;?rv:76.0)");
????headers?=?curl_slist_append(headers,?"Referer:?https://www.lyshark.com");

????//?初始化請求庫
????CURL?*easy_handle?=?curl_easy_init();
????if?(NULL?!=?easy_handle)
????{
????????//?CURLOPT_HTTPHEADER?自定義設置請求頭
????????curl_easy_setopt(easy_handle,?CURLOPT_HTTPHEADER,?headers);

????????//?CURLOPT_URL?自定義請求的網(wǎng)站
????????curl_easy_setopt(easy_handle,?CURLOPT_URL,?UrlPage);

????????//?CURLOPT_WRITEFUNCTION?設置回調(diào)函數(shù),屏蔽輸出
????????curl_easy_setopt(easy_handle,?CURLOPT_WRITEFUNCTION,?write_data);

????????//?執(zhí)行CURL訪問網(wǎng)站
????????return_code?=?curl_easy_perform(easy_handle);

????????char?*ipAddress?=?{?0?};

????????//?CURLINFO_PRIMARY_IP?獲取目標IP信息
????????return_code?=?curl_easy_getinfo(easy_handle,?CURLINFO_PRIMARY_IP,?&ipAddress);
????????if?((CURLE_OK?==?return_code)?&&?ipAddress)
????????{
????????????std::cout?<<?"目標IP:?"?<<?ipAddress?<<?std::endl;
????????}

????????long?retcode?=?0;

????????//?CURLINFO_RESPONSE_CODE?獲取目標返回狀態(tài)
????????return_code?=?curl_easy_getinfo(easy_handle,?CURLINFO_RESPONSE_CODE,?&retcode);
????????if?((CURLE_OK?==?return_code)?&&?retcode)
????????{
????????????std::cout?<<?"返回狀態(tài)碼:?"?<<?retcode?<<?std::endl;
????????}
????}
????curl_easy_cleanup(easy_handle);
????curl_global_cleanup();
}

int?main(int?argc,?char?*argv[])
{
????GetStatus("https://www.lyshark.com");
????system("pause");
????return?0;
}

運行上述代碼,則可以獲取到www.lyshark.com目標主機的IP地址以及頁面返回狀態(tài),如下圖所示;

當然該庫同樣支持POST請求方式,在使用POST請求時我們可以通過CURLOPT_COOKIEFILE參數(shù)指定Cookie參數(shù),通過CURLOPT_POSTFIELDS指定POST的數(shù)據(jù)集,而如果需要使用代理模式則可以通過CURLOPT_PROXY方式來指定代理地址,

#define?CURL_STATICLIB
#define?BUILDING_LIBCURL
#include?<iostream>
#include?"curl/curl.h"

#pragma?comment?(lib,"libcurl_a.lib")
#pragma?comment?(lib,"wldap32.lib")
#pragma?comment?(lib,"ws2_32.lib")
#pragma?comment?(lib,"Crypt32.lib")

using?namespace?std;

bool?SendPost(char?*Url,?char?*Cookie,?char?*PostVal)
{
????CURL?*curl;
????CURLcode?res;

????//?初始化庫
????curl?=?curl_easy_init();
????if?(curl)
????{
????????//?設置請求頭
????????struct?curl_slist?*headers?=?NULL;
????????headers?=?curl_slist_append(headers,?"User-Agent:?Mozilla/5.0?(Windows?NT?10.0;?Win64;?x64;?rv:76.0)");
????????headers?=?curl_slist_append(headers,?"Referer:?https://www.lyshark.com");

????????//?設置請求頭
????????curl_easy_setopt(curl,?CURLOPT_HTTPHEADER,?headers);

????????//?指定URL
????????curl_easy_setopt(curl,?CURLOPT_URL,?Url);

????????//?指定cookie參數(shù)
????????curl_easy_setopt(curl,?CURLOPT_COOKIEFILE,?Cookie);

????????//?指定post內(nèi)容
????????curl_easy_setopt(curl,?CURLOPT_POSTFIELDS,?PostVal);

????????//?是否代理
????????//?curl_easy_setopt(curl,?CURLOPT_PROXY,?"10.99.60.201:8080");
????????res?=?curl_easy_perform(curl);
????????curl_easy_cleanup(curl);
????}
????return?true;
}

int?main(int?argc,?char?*argv[])
{
????//?傳入網(wǎng)址?cookie?以及post參數(shù)
????SendPost("https://www.lyshark.com/post.php",?"1e12sde342r2",?"&logintype=uid&u=xieyan&psw=xxx86");

????system("pause");
????return?0;
}

該函數(shù)的調(diào)用需要有一個POST結構才可測試,此處由于我并沒有指定接口所有返回了頁面錯誤信息,如下圖所示;

接著繼續(xù)實現(xiàn)下載頁面到本地的功能,該功能實現(xiàn)的原理是利用write_data回調(diào)函數(shù),當頁面數(shù)據(jù)被讀入到內(nèi)存時回調(diào)函數(shù)會被觸發(fā),在該回調(diào)函數(shù)的內(nèi)部通過調(diào)用fwrite函數(shù)將ptr指針中的數(shù)據(jù)保存本地,實現(xiàn)這段代碼如下所示;

#define?CURL_STATICLIB
#define?BUILDING_LIBCURL
#include?<iostream>
#include?"curl/curl.h"

#pragma?comment?(lib,"libcurl_a.lib")
#pragma?comment?(lib,"wldap32.lib")
#pragma?comment?(lib,"ws2_32.lib")
#pragma?comment?(lib,"Crypt32.lib")

using?namespace?std;

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;
}

BOOL?GetUrl(char?*URL,?char?*FileName)
{
????CURL?*curl;

????curl_global_init(CURL_GLOBAL_ALL);
????curl?=?curl_easy_init();

????curl_easy_setopt(curl,?CURLOPT_URL,?URL);

????//?在屏幕打印請求連接過程和返回http數(shù)據(jù)
????curl_easy_setopt(curl,?CURLOPT_VERBOSE,?1L);

????//?查找次數(shù),防止查找太深
????curl_easy_setopt(curl,?CURLOPT_MAXREDIRS,?1);

????//?設置連接超時
????curl_easy_setopt(curl,?CURLOPT_CONNECTTIMEOUT,?3);

????//?接收數(shù)據(jù)時超時設置
????curl_easy_setopt(curl,?CURLOPT_TIMEOUT,?3);

????if?((fp?=?fopen(FileName,?"w"))?==?NULL)
????{
????????curl_easy_cleanup(curl);
????????return?FALSE;
????}
????//?CURLOPT_WRITEFUNCTION?將后繼的動作交給write_data函數(shù)處理
????curl_easy_setopt(curl,?CURLOPT_WRITEFUNCTION,?write_data);

????curl_easy_perform(curl);
????curl_easy_cleanup(curl);
????return?TRUE;
}

int?main(int?argc,?char?*argv[])
{
????//?下載網(wǎng)頁到本地
????GetUrl("https://www.lyshark.com",?"./lyshark.html");

????system("pause");
????return?0;
}

當讀者運行上述程序后,即可將www.lyshark.com網(wǎng)站頁面源碼,下載到本地當前目錄下lyshark.html,輸出效果如下圖所示;

為了能解析參數(shù),我們還是需要將頁面源代碼讀入到內(nèi)存中,要實現(xiàn)這個需求并不難,首先我們定義一個std::string容器,然后當有新數(shù)據(jù)產(chǎn)生時觸發(fā)WriteCallback在該函數(shù)內(nèi),我們直接將數(shù)據(jù)拷貝到一個內(nèi)存指針中,也就是存儲到read_buffer內(nèi),并將該緩沖區(qū)返回給調(diào)用者即可,如下則是完整源代碼。

#define?CURL_STATICLIB
#define?BUILDING_LIBCURL
#include?<iostream>
#include?<string>
#include?"curl/curl.h"

#pragma?comment?(lib,"libcurl_a.lib")
#pragma?comment?(lib,"wldap32.lib")
#pragma?comment?(lib,"ws2_32.lib")
#pragma?comment?(lib,"Crypt32.lib")

using?namespace?std;

//?存儲回調(diào)函數(shù)
size_t?WriteCallback(char?*contents,?size_t?size,?size_t?nmemb,?void?*userp)
{
????((std::string*)userp)->append((char*)contents,?size?*?nmemb);
????return?size?*?nmemb;
}

//?獲取數(shù)據(jù)并放入string中.
std::string?GetUrlPageOfString(std::string?url)
{
????std::string?read_buffer;
????CURL?*curl;

????curl_global_init(CURL_GLOBAL_ALL);
????curl?=?curl_easy_init();
????if?(curl)
????{
????????//?忽略證書檢查
????????curl_easy_setopt(curl,?CURLOPT_SSL_VERIFYPEER,?0L);

????????//?重定向
????????curl_easy_setopt(curl,?CURLOPT_FOLLOWLOCATION,?1);

????????//?URL路徑
????????curl_easy_setopt(curl,?CURLOPT_URL,?url);

????????//?查找次數(shù),防止查找太深
????????curl_easy_setopt(curl,?CURLOPT_MAXREDIRS,?1);

????????//?連接超時
????????curl_easy_setopt(curl,?CURLOPT_CONNECTTIMEOUT,?3);

????????//?接收數(shù)據(jù)時超時設置
????????curl_easy_setopt(curl,?CURLOPT_TIMEOUT,?3);

????????//?寫入回調(diào)函數(shù)
????????curl_easy_setopt(curl,?CURLOPT_WRITEFUNCTION,?WriteCallback);
????????curl_easy_setopt(curl,?CURLOPT_WRITEDATA,?&read_buffer);

????????curl_easy_perform(curl);
????????curl_easy_cleanup(curl);

????????return?read_buffer;
????}
????return?"None";
}

int?main(int?argc,?char?*argv[])
{
????std::string?urls?=?GetUrlPageOfString("https://www.lyshark.com");
????std::cout?<<?"接收長度:?"?<<?urls.length()?<<?"?bytes"?<<?std::endl;

????system("pause");
????return?0;
}

如下圖所示,則是運行后輸出內(nèi)存數(shù)據(jù)長度,當然我們也可以直接輸出urls中的數(shù)據(jù),也就是網(wǎng)頁的源代碼;

本文作者: 王瑞 本文鏈接: https://www.lyshark.com/post/6aa9753b.html 版權聲明: 本博客所有文章除特別聲明外,均采用 BY-NC-SA 許可協(xié)議。轉載請注明出處!


C++ LibCurl 庫的使用方法的評論 (共 條)

分享到微博請遵守國家法律
招远市| 横峰县| 孝感市| 泰州市| 平南县| 中阳县| 张掖市| 乌鲁木齐市| 义马市| 兰坪| 朝阳县| 万州区| 锦州市| 仁化县| 南溪县| 鲁甸县| 都江堰市| 长武县| 垫江县| 军事| 彭阳县| 尼玛县| 武定县| 徐州市| 阿勒泰市| 德清县| 中山市| 巴林右旗| 北辰区| 泌阳县| 锡林郭勒盟| 甘谷县| 黑龙江省| 泸定县| 阜平县| 泰安市| 天长市| 荆州市| 江津市| 临高县| 天全县|