最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

LibCurl是一個開源的免費的多協(xié)議數(shù)據(jù)傳輸開源庫,該框架具備跨平臺性,開源免費,并提供了包括HTTP、FTPSMTP、POP3等協(xié)議的功能,使用libcurl可以方便地進(jìn)行網(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對象進(jìn)行初始化,接著通過調(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遠(yuǎn)程獲取文檔的時間,如果無法獲取,則返回值為-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)主機(jī)的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)文章

  • OpenCV實現(xiàn)特征檢測和特征匹配方法匯總

    OpenCV實現(xiàn)特征檢測和特征匹配方法匯總

    一幅圖像中總存在著其獨特的像素點,這些點我們可以認(rèn)為就是這幅圖像的特征,成為特征點,本文主要介紹了OpenCV實現(xiàn)特征檢測和特征匹配方法,感興趣的可以了解一下
    2021-08-08
  • VC實現(xiàn)對話框窗口任意分割

    VC實現(xiàn)對話框窗口任意分割

    最近寫MFC的程序,想在對話框里實現(xiàn)窗口的任意分割。現(xiàn)在網(wǎng)絡(luò)資料一大抄,找個東西實在麻煩??偹氵@個很簡單,很快就搞定了,寫下來做個筆記。
    2015-06-06
  • C++實現(xiàn)LeetCode(692.前K個高頻詞)

    C++實現(xiàn)LeetCode(692.前K個高頻詞)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(692.前K個高頻詞),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • OpenGL通過中點法繪制直線和圓

    OpenGL通過中點法繪制直線和圓

    這篇文章主要為大家詳細(xì)介紹了OpenGL通過中點法繪制直線和圓,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • 利用OpenCV實現(xiàn)綠幕視頻背景替換

    利用OpenCV實現(xiàn)綠幕視頻背景替換

    這篇文章主要介紹了如何利用OpenCV實現(xiàn)綠幕視頻背景替換功能,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)OpenCV有一定的幫助,感興趣的可以學(xué)習(xí)一下
    2022-01-01
  • C語言動態(tài)內(nèi)存管理的原理及實現(xiàn)方法

    C語言動態(tài)內(nèi)存管理的原理及實現(xiàn)方法

    C語言動態(tài)內(nèi)存管理的原理是通過 malloc() 函數(shù)申請一塊連續(xù)的內(nèi)存空間,并返回其地址,通過 free() 函數(shù)釋放該內(nèi)存空間。實現(xiàn)方法是通過在程序運行時動態(tài)地管理內(nèi)存,即在需要內(nèi)存時申請,不需要時釋放,避免了靜態(tài)內(nèi)存分配的浪費和不足
    2023-04-04
  • 使用Qt實現(xiàn)旋轉(zhuǎn)動畫效果

    使用Qt實現(xiàn)旋轉(zhuǎn)動畫效果

    這篇文章主要為大家詳細(xì)介紹了如何使用Qt實現(xiàn)旋轉(zhuǎn)動畫效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-11-11
  • Vue自定義指令最佳實踐教程分享

    Vue自定義指令最佳實踐教程分享

    Vue?3?顯著增強(qiáng)了自定義指令的功能,使其封裝更加靈活和易用,本文將分為基礎(chǔ)和進(jìn)階兩部分,介紹如何實現(xiàn)常用的自定義指令,并提供最佳的項目組織方式,需要的朋友可以參考下
    2024-12-12
  • 安裝OpenMPI來配合C語言程序進(jìn)行并行計算

    安裝OpenMPI來配合C語言程序進(jìn)行并行計算

    這篇文章主要介紹了安裝OpenMPI來配合C語言程序進(jìn)行并行計算的例子,MPI的全稱是Message Passing Interface即標(biāo)準(zhǔn)消息傳遞界面,可以用于并行計算,需要的朋友可以參考下
    2015-11-11
  • C語言中各類指針的用法(小結(jié))

    C語言中各類指針的用法(小結(jié))

    這篇文章主要介紹了C語言中各類指針的用法(小結(jié)),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02

最新評論

龙海市| 乌鲁木齐县| 缙云县| 淮滨县| 德令哈市| 页游| 龙里县| 万安县| 甘洛县| 石嘴山市| 双鸭山市| 明星| 普洱| 定兴县| 介休市| 喀喇沁旗| 福安市| 晋江市| 松原市| 射阳县| 徐州市| 浦东新区| 华池县| 江北区| 内江市| 兖州市| 鸡泽县| 嵩明县| 龙门县| 锡林郭勒盟| 济阳县| 武强县| 长寿区| 同德县| 房山区| 定州市| 抚远县| 江门市| 三江| 上犹县| 普陀区|