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:
- /********************************************************
- Copyright (C), 2016-2018,
- FileName: Get
- Author: woniu201
- Email: wangpengfei.201@163.com
- Created: 2018/10/15
- Description: 实现 HTTP/HTTPS GET 请求
- ********************************************************/
- #include "main.h"
- size_t WriteGetResp(void *buffer, size_t size, size_t nmemb, void *userp)
- {
- ((string*)userp)->append((char*)buffer, 0, size*nmemb);
- return size*nmemb;
- }
- /************************************
- @ Brief: GET 请求
- @ Author: woniu201
- @ Created: 2018/10/15
- @ Return:
- ************************************/
- int HttpGet(char* url)
- {
- string respData;
- CURL* curl;
- CURLcode res;
- curl = curl_easy_init();
- if (curl == NULL)
- {
- return 1;
- }
- curl_easy_setopt(curl, CURLOPT_URL, url);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteGetResp);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, &respData);
- // curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 5000); //libcurl 存在毫秒超时 bug, 如果设备小于 1000ms 立即返回失败
- // curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 5000); // 设置超时时间
- bool bCA = FALSE;
- if (!bCA)
- {
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);// 设定为不验证证书和 HOST
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, FALSE);
- }
- else
- {
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, TRUE);
- curl_easy_setopt(curl, CURLOPT_CAINFO, "");
- }
- res = curl_easy_perform(curl);
- if (res != CURLE_OK)
- {
- cout <<curl_easy_strerror(res) << endl;
- }
- curl_easy_cleanup(curl);
- cout << Utf8ToAscii(respData) << endl;
- return 0;
- }
实现 HTTP/POST:
- /********************************************************
- Copyright (C), 2016-2018,
- FileName: Post
- Author: woniu201
- Email: wangpengfei.201@163.com
- Created: 2018/10/15
- Description: 实现 HTTP/HTTPS POST 请求
- ********************************************************/
- #include "main.h"
- size_t WritePostBodyResp(void *buffer, size_t size, size_t nmemb, void *userp)
- {
- ((string*)userp)->append((char*)buffer, 0, size*nmemb);
- return size*nmemb;
- }
- size_t WritePostHeaderResp(void *buffer, size_t size, size_t nmemb, void *userp)
- {
- ((string*)userp)->append((char*)buffer, 0, size*nmemb);
- return size*nmemb;
- }
- /************************************
- @ Brief: POST 请求
- @ Author: woniu201
- @ Created: 2018/10/15
- @ Return:
- ************************************/
- int HttpPost(char* url, char* body)
- {
- string respBodyData;
- string respHeadData;
- CURL* curl;
- CURLcode res;
- // 设置头
- struct curl_slist *headers = NULL;
- headers = curl_slist_append(headers, "Content-Type:application/json;charset=UTF-8");
- curl = curl_easy_init();
- if (curl == NULL)
- {
- return 1;
- }
- curl_easy_setopt(curl, CURLOPT_URL, url);
- curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body);
- curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
- curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, WritePostHeaderResp);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WritePostBodyResp);
- curl_easy_setopt(curl, CURLOPT_WRITEHEADER, &respHeadData);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, &respBodyData);
- // curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 5000); //libcurl 存在毫秒超时 bug, 如果设备小于 1000ms 立即返回失败
- // curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 5000); // 设置超时时间
- bool bCA = FALSE;
- if (!bCA)
- {
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);// 设定为不验证证书和 HOST
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, FALSE);
- }
- else
- {
- curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, TRUE);
- curl_easy_setopt(curl, CURLOPT_CAINFO, "");
- }
- res = curl_easy_perform(curl);
- if (res != CURLE_OK)
- {
- cout <<curl_easy_strerror(res) << endl;
- }
- curl_slist_free_all(headers);
- curl_easy_cleanup(curl);
- cout << Utf8ToAscii(respHeadData) << endl;
- cout << Utf8ToAscii(respBodyData) << endl;
- return 0;
- }
其他代码:
- /********************************************************
- Copyright (C), 2016-2018,
- FileName: utils
- Author: woniu201
- Email: wangpengfei.201@163.com
- Created: 2018/10/15
- Description: ASSIC--UTF8 互转
- ********************************************************/
- #include "main.h"
- #include <string>
- #include <Windows.h>
- #include <wchar.h>
- using namespace std;
- wstring AsciiToUnicode(const string& str) {
- // 预算 - 缓冲区中宽字节的长度
- int unicodeLen = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, nullptr, 0);
- // 给指向缓冲区的指针变量分配内存
- wchar_t *pUnicode = (wchar_t*)malloc(sizeof(wchar_t)*unicodeLen);
- // 开始向缓冲区转换字节
- MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, pUnicode, unicodeLen);
- wstring ret_str = pUnicode;
- free(pUnicode);
- return ret_str;
- }
- string UnicodeToAscii(const wstring& wstr) {
- // 预算 - 缓冲区中多字节的长度
- int ansiiLen = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);
- // 给指向缓冲区的指针变量分配内存
- char *pAssii = (char*)malloc(sizeof(char)*ansiiLen);
- // 开始向缓冲区转换字节
- WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, pAssii, ansiiLen, nullptr, nullptr);
- string ret_str = pAssii;
- free(pAssii);
- return ret_str;
- }
- wstring Utf8ToUnicode(const string& str) {
- // 预算 - 缓冲区中宽字节的长度
- int unicodeLen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0);
- // 给指向缓冲区的指针变量分配内存
- wchar_t *pUnicode = (wchar_t*)malloc(sizeof(wchar_t)*unicodeLen);
- // 开始向缓冲区转换字节
- MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, pUnicode, unicodeLen);
- wstring ret_str = pUnicode;
- free(pUnicode);
- return ret_str;
- }
- string UnicodeToUtf8(const wstring& wstr) {
- // 预算 - 缓冲区中多字节的长度
- int ansiiLen = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);
- // 给指向缓冲区的指针变量分配内存
- char *pAssii = (char*)malloc(sizeof(char)*ansiiLen);
- // 开始向缓冲区转换字节
- WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, pAssii, ansiiLen, nullptr, nullptr);
- string ret_str = pAssii;
- free(pAssii);
- return ret_str;
- }
- /************************************
- @ Brief: ASSIC 转 UTF8
- @ Author: woniu201
- @ Created: 2018/10/16
- @ Return:
- ************************************/
- string AsciiToUtf8(const string& str) {
- return UnicodeToUtf8(AsciiToUnicode(str));
- }
- /************************************
- @ Brief: UTF8 转 ASSIC
- @ Author: woniu201
- @ Created: 2018/10/16
- @ Return:
- ************************************/
- string Utf8ToAscii(const string& str) {
- return UnicodeToAscii(Utf8ToUnicode(str));
- }
- #ifndef _MAIN_H
- #define _MAIN_H
- #include <iostream>
- #include <string>
- #include "include/curl.h"
- using namespace std;
- #pragma comment(lib, "ssleay32.lib")
- #pragma comment(lib, "libcurl.lib")
- string AsciiToUtf8(const string& str);
- string Utf8ToAscii(const string& str);
- int HttpGet(char* url);
- int HttpPost(char* url, char* body);
- int HttpDownload(char* url, char* filePath);
- #endif
对应 libcurl 库和头文件下载地址 (支持 HTTPS): 点击下载
来源: https://www.cnblogs.com/woniu201/p/9798278.html