c/c++開發中經常要用到http/https協議,直接使用socket工作量很大,要是使用socket實現https,那更不可思議,開源的c/c++的http客戶端框架,libcurl是首選,而且也相當成熟穩定,最近C++專案中用到https請求,就做下研究。
libcurl簡介(來源官網)
libcurl是一個跨平臺的網路協議庫,支援http, https, ftp, gopher, telnet, dict, file, 和ldap 協議。libcurl同樣支援HTTPS證照授權,HTTP POST, HTTP PUT, FTP 上傳, HTTP基本表單上傳,代理,cookies,和使用者認證。官網地址:https://curl.haxx.se/libcurl/
實現HTTP/GET:
Get.cpp
1 /******************************************************** 2 Copyright (C), 2016-2018, 3 FileName: Get 4 Author: woniu201 5 Email: wangpengfei.201@163.com 6 Created: 2018/10/15 7 Description: 實現HTTP/HTTPS GET請求 8 ********************************************************/ 9 #include "main.h" 10 11 size_t WriteGetResp(void *buffer, size_t size, size_t nmemb, void *userp) 12 { 13 ((string*)userp)->append((char*)buffer, 0, size*nmemb); 14 return size*nmemb; 15 } 16 17 /************************************ 18 @ Brief: GET請求 19 @ Author: woniu201 20 @ Created: 2018/10/15 21 @ Return: 22 ************************************/ 23 int HttpGet(char* url) 24 { 25 string respData; 26 CURL* curl; 27 CURLcode res; 28 29 curl = curl_easy_init(); 30 if (curl == NULL) 31 { 32 return 1; 33 } 34 35 curl_easy_setopt(curl, CURLOPT_URL, url); 36 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteGetResp); 37 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &respData); 38 39 // curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 5000); //libcurl存在毫秒超時bug,如果裝置小於1000ms立即返回失敗 40 // curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 5000); //設定超時時間 41 42 bool bCA = FALSE; 43 if (!bCA) 44 { 45 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);//設定為不驗證證照和HOST 46 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, FALSE); 47 } 48 else 49 { 50 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, TRUE); 51 curl_easy_setopt(curl, CURLOPT_CAINFO, ""); 52 } 53 54 res = curl_easy_perform(curl); 55 if (res != CURLE_OK) 56 { 57 cout << curl_easy_strerror(res) << endl; 58 } 59 60 curl_easy_cleanup(curl); 61 62 cout << Utf8ToAscii(respData) << endl; 63 return 0; 64 }
實現HTTP/POST:
Post.cpp
1 /******************************************************** 2 Copyright (C), 2016-2018, 3 FileName: Post 4 Author: woniu201 5 Email: wangpengfei.201@163.com 6 Created: 2018/10/15 7 Description: 實現HTTP/HTTPS POST請求 8 ********************************************************/ 9 #include "main.h" 10 11 size_t WritePostBodyResp(void *buffer, size_t size, size_t nmemb, void *userp) 12 { 13 ((string*)userp)->append((char*)buffer, 0, size*nmemb); 14 return size*nmemb; 15 } 16 17 size_t WritePostHeaderResp(void *buffer, size_t size, size_t nmemb, void *userp) 18 { 19 ((string*)userp)->append((char*)buffer, 0, size*nmemb); 20 return size*nmemb; 21 } 22 23 /************************************ 24 @ Brief: POST請求 25 @ Author: woniu201 26 @ Created: 2018/10/15 27 @ Return: 28 ************************************/ 29 int HttpPost(char* url, char* body) 30 { 31 string respBodyData; 32 string respHeadData; 33 CURL* curl; 34 CURLcode res; 35 36 //設定頭 37 struct curl_slist *headers = NULL; 38 headers = curl_slist_append(headers, "Content-Type:application/json;charset=UTF-8"); 39 40 curl = curl_easy_init(); 41 if (curl == NULL) 42 { 43 return 1; 44 } 45 46 curl_easy_setopt(curl, CURLOPT_URL, url); 47 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body); 48 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); 49 50 curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, WritePostHeaderResp); 51 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WritePostBodyResp); 52 curl_easy_setopt(curl, CURLOPT_WRITEHEADER, &respHeadData); 53 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &respBodyData); 54 55 // curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 5000); //libcurl存在毫秒超時bug,如果裝置小於1000ms立即返回失敗 56 // curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 5000); //設定超時時間 57 58 bool bCA = FALSE; 59 if (!bCA) 60 { 61 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);//設定為不驗證證照和HOST 62 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, FALSE); 63 } 64 else 65 { 66 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, TRUE); 67 curl_easy_setopt(curl, CURLOPT_CAINFO, ""); 68 } 69 70 res = curl_easy_perform(curl); 71 if (res != CURLE_OK) 72 { 73 cout << curl_easy_strerror(res) << endl; 74 } 75 curl_slist_free_all(headers); 76 curl_easy_cleanup(curl); 77 78 cout << Utf8ToAscii(respHeadData) << endl; 79 cout << Utf8ToAscii(respBodyData) << endl; 80 81 return 0; 82 }
其他程式碼:
utils.cpp
1 /******************************************************** 2 Copyright (C), 2016-2018, 3 FileName: utils 4 Author: woniu201 5 Email: wangpengfei.201@163.com 6 Created: 2018/10/15 7 Description: ASSIC--UTF8互轉 8 ********************************************************/ 9 #include "main.h" 10 #include <string> 11 #include <Windows.h> 12 #include <wchar.h> 13 using namespace std; 14 15 wstring AsciiToUnicode(const string& str) { 16 // 預算-緩衝區中寬位元組的長度 17 int unicodeLen = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, nullptr, 0); 18 // 給指向緩衝區的指標變數分配記憶體 19 wchar_t *pUnicode = (wchar_t*)malloc(sizeof(wchar_t)*unicodeLen); 20 // 開始向緩衝區轉換位元組 21 MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, pUnicode, unicodeLen); 22 wstring ret_str = pUnicode; 23 free(pUnicode); 24 return ret_str; 25 } 26 string UnicodeToAscii(const wstring& wstr) { 27 // 預算-緩衝區中多位元組的長度 28 int ansiiLen = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr); 29 // 給指向緩衝區的指標變數分配記憶體 30 char *pAssii = (char*)malloc(sizeof(char)*ansiiLen); 31 // 開始向緩衝區轉換位元組 32 WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, pAssii, ansiiLen, nullptr, nullptr); 33 string ret_str = pAssii; 34 free(pAssii); 35 return ret_str; 36 } 37 38 wstring Utf8ToUnicode(const string& str) { 39 // 預算-緩衝區中寬位元組的長度 40 int unicodeLen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0); 41 // 給指向緩衝區的指標變數分配記憶體 42 wchar_t *pUnicode = (wchar_t*)malloc(sizeof(wchar_t)*unicodeLen); 43 // 開始向緩衝區轉換位元組 44 MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, pUnicode, unicodeLen); 45 wstring ret_str = pUnicode; 46 free(pUnicode); 47 return ret_str; 48 } 49 string UnicodeToUtf8(const wstring& wstr) { 50 // 預算-緩衝區中多位元組的長度 51 int ansiiLen = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr); 52 // 給指向緩衝區的指標變數分配記憶體 53 char *pAssii = (char*)malloc(sizeof(char)*ansiiLen); 54 // 開始向緩衝區轉換位元組 55 WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, pAssii, ansiiLen, nullptr, nullptr); 56 string ret_str = pAssii; 57 free(pAssii); 58 return ret_str; 59 } 60 61 /************************************ 62 @ Brief: ASSIC轉UTF8 63 @ Author: woniu201 64 @ Created: 2018/10/16 65 @ Return: 66 ************************************/ 67 string AsciiToUtf8(const string& str) { 68 return UnicodeToUtf8(AsciiToUnicode(str)); 69 } 70 71 /************************************ 72 @ Brief: UTF8轉ASSIC 73 @ Author: woniu201 74 @ Created: 2018/10/16 75 @ Return: 76 ************************************/ 77 string Utf8ToAscii(const string& str) { 78 return UnicodeToAscii(Utf8ToUnicode(str)); 79 }
1 #ifndef _MAIN_H 2 #define _MAIN_H 3 4 #include <iostream> 5 #include <string> 6 #include "include/curl.h" 7 8 using namespace std; 9 10 11 #pragma comment(lib, "ssleay32.lib") 12 #pragma comment(lib, "libcurl.lib") 13 14 string AsciiToUtf8(const string& str); 15 string Utf8ToAscii(const string& str); 16 17 int HttpGet(char* url); 18 int HttpPost(char* url, char* body); 19 int HttpDownload(char* url, char* filePath); 20 #endif
對應libcurl庫和標頭檔案下載地址(支援HTTPS):點選下載
掃碼關注公眾號
專注分享C/C++,C++(11,14,17),STL,Java,Spring,mybatis,mysql,redis,分散式,高併發,設計模式,爬蟲,docker,shell程式設計等相關技術,還有高薪網際網路職位內推,在這裡一起探討,一起學習,一起進步,同時不定期分享視訊書籍資源,充分利用碎片化時間,讓我們的技術之路更加有樂趣。