欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++中LibCurl庫的使用教程分享

 更新時間:2023年08月23日 14:11:49   作者:lyshark  
LibCurl是一個開源的免費的多協(xié)議數(shù)據(jù)傳輸開源庫,該框架具備跨平臺性,開源免費,這篇文章主要為大家介紹了如何在C++中使用LibCurl庫,需要的可以參考下

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

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

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

當(dāng)讀者解壓縮后,可打開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鏈接,當(dāng)訪問成功后則可調(diào)用curl_easy_perform()函數(shù)得到訪問結(jié)果,這就是該庫基本使用方法,如下代碼。

#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ù),例如當(dāng)我們需要修改協(xié)議頭時,可以使用CURLOPT_HTTPHEADER常量,并在其后第三個參數(shù)中傳入該常量所對應(yīng)的結(jié)構(gòu)即可,這個結(jié)構(gòu)體定義有許多類型,具體如下下表所示;

常量名稱描述
CURLINFO_EFFECTIVE_URL最后一個有效的URL地址
CURLINFO_HTTP_CODE最后一個收到的HTTP代碼
CURLINFO_FILETIME遠程獲取文檔的時間,如果無法獲取,則返回值為-1
CURLINFO_TOTAL_TIME最后一次傳輸所消耗的時間
CURLINFO_NAMELOOKUP_TIME名稱解析所消耗的時間
CURLINFO_CONNECT_TIME建立連接所消耗的時間
CURLINFO_PRETRANSFER_TIME從建立連接到準(zhǔn)備傳輸所使用的時間
CURLINFO_STARTTRANSFER_TIME從建立連接到傳輸開始所使用的時間
CURLINFO_REDIRECT_TIME在事務(wù)傳輸開始前重定向所使用的時間
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通過設(shè)置CURLOPT_SSL_VERIFYPEER返回的SSL證書驗證請求的結(jié)果
CURLINFO_CONTENT_LENGTH_DOWNLOAD從Content-Length: field中讀取的下載內(nèi)容長度
CURLINFO_CONTENT_LENGTH_UPLOAD上傳內(nèi)容大小的說明
CURLINFO_CONTENT_TYPE下載內(nèi)容的Content-Type:值,NULL表示服務(wù)器沒有發(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設(shè)置請求頭,CURLOPT_WRITEFUNCTION設(shè)置回調(diào),CURLINFO_PRIMARY_IP獲取目標(biāo)IP地址,CURLINFO_RESPONSE_CODE獲取目標(biāo)返回代碼,此處的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;
// 設(shè)置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 自定義設(shè)置請求頭
		curl_easy_setopt(easy_handle, CURLOPT_HTTPHEADER, headers);
		// CURLOPT_URL 自定義請求的網(wǎng)站
		curl_easy_setopt(easy_handle, CURLOPT_URL, UrlPage);
		// CURLOPT_WRITEFUNCTION 設(shè)置回調(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 獲取目標(biāo)IP信息
		return_code = curl_easy_getinfo(easy_handle, CURLINFO_PRIMARY_IP, &ipAddress);
		if ((CURLE_OK == return_code) && ipAddress)
		{
			std::cout << "目標(biāo)IP: " << ipAddress << std::endl;
		}
		long retcode = 0;
		// CURLINFO_RESPONSE_CODE 獲取目標(biāo)返回狀態(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目標(biāo)主機的IP地址以及頁面返回狀態(tài),如下圖所示;

當(dāng)然該庫同樣支持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)
	{
		// 設(shè)置請求頭
		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");
		// 設(shè)置請求頭
		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結(jié)構(gòu)才可測試,此處由于我并沒有指定接口所有返回了頁面錯誤信息,如下圖所示;

接著繼續(xù)實現(xiàn)下載頁面到本地的功能,該功能實現(xiàn)的原理是利用write_data回調(diào)函數(shù),當(dāng)頁面數(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);
	// 設(shè)置連接超時
	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3);
	// 接收數(shù)據(jù)時超時設(shè)置
	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;
}

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

為了能解析參數(shù),我們還是需要將頁面源代碼讀入到內(nèi)存中,要實現(xiàn)這個需求并不難,首先我們定義一個std::string容器,然后當(dāng)有新數(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ù)時超時設(shè)置
		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ù)長度,當(dāng)然我們也可以直接輸出urls中的數(shù)據(jù),也就是網(wǎng)頁的源代碼;

到此這篇關(guān)于C++中LibCurl庫的使用教程分享的文章就介紹到這了,更多相關(guān)C++ LibCurl內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一篇文章帶你了解C語言內(nèi)存對齊公式

    一篇文章帶你了解C語言內(nèi)存對齊公式

    這篇文章主要介紹了C語言內(nèi)存對齊,包括內(nèi)存對其的基本概念及用法,以及注意事項,并以實例形式加以說明,需要的朋友可以參考下,希望能給你帶來幫助
    2021-08-08
  • C++實現(xiàn)多源最短路徑之Floyd算法示例

    C++實現(xiàn)多源最短路徑之Floyd算法示例

    這篇文章主要介紹了C++實現(xiàn)多源最短路徑之Floyd算法,結(jié)合實例形式分析了多源最短路徑之Floyd算法的原理、實現(xiàn)方法及核心代碼,需要的朋友可以參考下
    2017-08-08
  • 基于C語言實現(xiàn)五子棋游戲完整實例代碼

    基于C語言實現(xiàn)五子棋游戲完整實例代碼

    這篇文章主要介紹了基于C語言實現(xiàn)五子棋游戲完整實例代碼,相信對于學(xué)習(xí)游戲開發(fā)的朋友會有一定的幫助與借鑒價值,需要的朋友可以參考下
    2014-08-08
  • Linux編程實現(xiàn)制作文件的ed2k鏈

    Linux編程實現(xiàn)制作文件的ed2k鏈

    這篇文章主要介紹了Linux編程實現(xiàn)制作文件的ed2k鏈的相關(guān)資料,需要的朋友可以參考下
    2015-03-03
  • C++改變參數(shù)值的方式小結(jié)

    C++改變參數(shù)值的方式小結(jié)

    本文主要介紹了C++改變參數(shù)值的方式小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • C/C++實現(xiàn)枚舉網(wǎng)上鄰居信息的示例詳解

    C/C++實現(xiàn)枚舉網(wǎng)上鄰居信息的示例詳解

    在Windows系統(tǒng)中,通過網(wǎng)絡(luò)鄰居可以方便地查看本地網(wǎng)絡(luò)中的共享資源和計算機,本文將介紹一個簡單的C++程序,使用Windows API枚舉網(wǎng)絡(luò)鄰居信息,并獲取對端名稱、本機名稱、主機名稱以及主機IP等信息,文中通過代碼示例給大家講解非詳細,需要的朋友可以參考下
    2023-12-12
  • 使用C++實現(xiàn)順序鏈表

    使用C++實現(xiàn)順序鏈表

    今天小編就為大家分享一篇關(guān)于使用C++實現(xiàn)順序鏈表,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • C語言結(jié)構(gòu)體(struct)常見使用方法(細節(jié)問題)

    C語言結(jié)構(gòu)體(struct)常見使用方法(細節(jié)問題)

    這篇文章主要介紹了C語言結(jié)構(gòu)體(struct)常見使用方法(細節(jié)問題),需要的朋友可以參考下
    2017-03-03
  • Qt讀取Json文件的方法詳解(含源碼+注釋)

    Qt讀取Json文件的方法詳解(含源碼+注釋)

    QT本身就有讀取json的接口,簡單又方便,下面這篇文章主要給大家介紹了關(guān)于Qt讀取Json文件(含源碼+注釋)的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-10-10
  • 淺談c++中的while(cin)問題

    淺談c++中的while(cin)問題

    下面小編就為大家?guī)硪黄獪\談c++中的while(cin)問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05

最新評論