C++使用curl庫(kù)進(jìn)行http請(qǐng)求的方法詳解
實(shí)現(xiàn)代碼
#include <iostream>
#include <string>
#include <curl/curl.h>
#include <ctime>
#include <iomanip>
size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* output) {
size_t totalSize = size * nmemb;
output->append(static_cast<char*>(contents), totalSize);
return totalSize;
}
// 將日期字符串轉(zhuǎn)換為指定格式
std::string formatDateString(const std::string& dateString) {
std::tm t;
std::istringstream iss(dateString);
// 解析日期字符串
iss >> std::get_time(&t, "%a, %d %b %Y %H:%M:%S %Z");
if (iss.fail()) {
return "";
}
std::ostringstream oss;
// 格式化日期
oss << std::put_time(&t, "%m%d%H%M%Y.%S");
return oss.str();
}
int main() {
CURL* curl;
CURLcode res;
std::string responseHeaders;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://your-backend-server/current-time");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &responseHeaders);
curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
std::cerr << "Failed to perform request: " << curl_easy_strerror(res) << std::endl;
} else {
std::string dateHeader = "Date: ";
size_t startPos = responseHeaders.find(dateHeader);
if (startPos != std::string::npos) {
startPos += dateHeader.length();
size_t endPos = responseHeaders.find("\r
", startPos);
std::string dateString = responseHeaders.substr(startPos, endPos - startPos);
std::string formattedDate = formatDateString(dateString);
if (!formattedDate.empty()) {
std::cout << "Formatted date: " << formattedDate << std::endl;
} else {
std::cerr << "Failed to format date string." << std::endl;
}
} else {
std::cerr << "Failed to extract server time from response headers." << std::endl;
}
}
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}formatdatestring方法會(huì)將時(shí)間格式化為指定的格式,但是如果頭部信息返回的時(shí)間如果不是北京時(shí)間,則可以修改方法修改為北京時(shí)間,如下:
// 將日期字符串轉(zhuǎn)換為指定格式(北京時(shí)間)
std::string formatDateString(const std::string& dateString) {
std::tm t;
std::istringstream iss(dateString);
// 解析日期字符串
iss >> std::get_time(&t, "%a, %d %b %Y %H:%M:%S %Z");
if (iss.fail()) {
return "";
}
// 將 tm 結(jié)構(gòu)轉(zhuǎn)換為系統(tǒng)時(shí)鐘的時(shí)間點(diǎn)
std::chrono::system_clock::time_point tp = std::chrono::system_clock::from_time_t(std::mktime(&t));
// 將時(shí)間點(diǎn)轉(zhuǎn)換為北京時(shí)間
std::chrono::hours offset(8); // 北京時(shí)間偏移量為+8小時(shí)
tp += offset;
// 轉(zhuǎn)換為本地時(shí)間
std::time_t tt = std::chrono::system_clock::to_time_t(tp);
t = *std::localtime(&tt);
std::ostringstream oss;
// 格式化日期
oss << std::put_time(&t, "%m%d%H%M%Y.%S");
return oss.str();
}
int main() {
// ...
}知識(shí)補(bǔ)充
可能有小伙伴對(duì)于curl庫(kù)不太熟悉,下面小編為大家簡(jiǎn)單介紹一下curl庫(kù)的使用,需要的可以參考一下
關(guān)于Curl庫(kù)
curl 是一個(gè)利用URL語(yǔ)法在命令行方式下工作的文件傳輸工具。它支持很多協(xié)議:FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE 以及 LDAP。curl不但提供了一個(gè)可執(zhí)行的工具庫(kù),還提供了供程序開(kāi)發(fā)的libcurl庫(kù),該庫(kù)使用c語(yǔ)言編寫,支持跨平臺(tái)。
編譯安裝
編譯curl庫(kù)很簡(jiǎn)單的,找到自己對(duì)應(yīng)的VS目錄,然后打開(kāi)工程,選擇所需要的版本即可編譯。我使用的是VS2010的靜態(tài)庫(kù)版本,因此選擇VC10目錄->LIB Debug版本,然后編譯,編譯后生成libcurld.lib和對(duì)應(yīng)的調(diào)試信息文件libcurld.pdb,這樣我們開(kāi)發(fā)調(diào)試的時(shí)候只需要把該庫(kù)文件和curl庫(kù)的頭文件文件夾curl加到我們的工程里面就可以使用curl庫(kù)給我們提供的功能了。不過(guò)需要注意的是,因?yàn)镃URL的特殊性,需要預(yù)定義一些宏和添加特定的依賴庫(kù),如下所示:
// 需要定義的宏,要不然會(huì)提示找不到某些函數(shù)的定義 #define BUILDING_LIBCURL //#define HTTP_ONLY // 依賴庫(kù) #pragma comment(lib, "ws2_32.lib") #pragma comment(lib, "wldap32.lib") #pragma comment(lib, "libcurld.lib")
主要函數(shù)列表
1.全局初始化
CURLcode curl_global_init(long flags);
描述: 這個(gè)函數(shù)只能用一次(其實(shí)在調(diào)用curl_global_cleanup 函數(shù)后仍然可再用),如果這個(gè)函數(shù)在curl_easy_init函數(shù)調(diào)用時(shí)還沒(méi)調(diào)用,它講由libcurl庫(kù)自動(dòng)完成。
參數(shù):flags
CURL_GLOBAL_ALL //初始化所有的可能的調(diào)用。
CURL_GLOBAL_SSL //初始化支持 安全套接字層。
CURL_GLOBAL_WIN32 //初始化win32套接字庫(kù)。
CURL_GLOBAL_NOTHING //沒(méi)有額外的初始化
2.全局清理
void curl_global_cleanup(void);
描述:在結(jié)束libcurl使用的時(shí)候,用來(lái)對(duì)curl_global_init做的工作清理。類似于close的函數(shù)。
3.獲取Curl版本庫(kù)
char *curl_version();
描述: 打印當(dāng)前l(fā)ibcurl庫(kù)的版本。
4.初始化curl會(huì)話
CURL *curl_easy_init();
描述: curl_easy_init用來(lái)初始化一個(gè)CURL的指針(有些像返回FILE類型的指針一樣),相應(yīng)的在調(diào)用結(jié)束時(shí)要用curl_easy_cleanup函數(shù)清理。一般curl_easy_init意味著一個(gè)會(huì)話的開(kāi)始,它的返回值一般都用在easy系列的函數(shù)。
5.清理cur會(huì)話
void curl_easy_cleanup(CURL *handle);
描述: 這個(gè)調(diào)用用來(lái)結(jié)束一個(gè)會(huì)話,與curl_easy_init配合著用。
參數(shù): CURL類型的指針。
6.設(shè)置curl會(huì)話參數(shù)
CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter);
描述: 這個(gè)函數(shù)最重要了,幾乎所有的curl程序都要頻繁的使用它,用來(lái)設(shè)置參數(shù)。它告訴curl庫(kù),程序?qū)⒂腥绾蔚男袨椋热缫榭匆粋€(gè)網(wǎng)頁(yè)的html代碼等。
- 參數(shù)handle:CURL類型的指針
- 參數(shù)option:各種CURLoption類型的選項(xiàng)。(都在curl.h庫(kù)里有定義,man 也可以查看到)
- 參數(shù)parameter: 這個(gè)參數(shù)既可以是個(gè)函數(shù)的指針,也可以是某個(gè)對(duì)象的指針,也可以是個(gè)long型的變量,它用什么這取決于第二個(gè)參數(shù)。
7.執(zhí)行curl會(huì)話
CURLcode curl_easy_perform(CURL *handle);
描述:這個(gè)函數(shù)在初始化CURL類型的指針以及curl_easy_setopt完成后調(diào)用,就像字面的意思所說(shuō)perform就像是個(gè)舞臺(tái),讓我們?cè)O(shè)置的option運(yùn)作起來(lái),執(zhí)行curl所設(shè)置的動(dòng)作。
到此這篇關(guān)于C++使用curl庫(kù)進(jìn)行http請(qǐng)求的方法詳解的文章就介紹到這了,更多相關(guān)C++ curl進(jìn)行http請(qǐng)求內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言中關(guān)于scanf讀取緩存區(qū)的問(wèn)題
scanf()函數(shù)是通用終端格式化輸入函數(shù),它從標(biāo)準(zhǔn)輸入設(shè)備(鍵盤) 讀取輸入的信息,接下來(lái)通過(guò)本文給大家介紹C語(yǔ)言中關(guān)于scanf讀取緩存區(qū)的問(wèn)題,需要的朋友一起看看吧2021-09-09
你不知道的C++中namespace和using的用法實(shí)例
在C++語(yǔ)言編寫的程序中,變量和函數(shù)等的作用范圍是有一定限制的,下面這篇文章主要給大家介紹了一些你不知道的C++中namespace和using的用法,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12
C++實(shí)現(xiàn)兩個(gè)有序數(shù)組的合并
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)兩個(gè)有序數(shù)組的合并,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02

