当前位置: 首页 > news >正文

LibCpr: Windows环境下实现一个C++版本的Http客户端

        近日,出于工作需要,需要实现一个C++版本的Http客户端。对比后,发现调用LibCpr库接口比较简洁、好用,以下是Windows环境下实现一个C++版本的Http客户端程序,已在本机验证可用。

C++代码:

#include <iostream>
#include <string>
#include <cpr/cpr.h>
#include <stdexcept>
#include <string_view>
#include <sstream>
#include <ctime>
#include <vector>
#include <optional>
#include <iomanip>using namespace std;// HTTP服务连接器类 (使用cpr::Session优化连接)
class HttpServiceConnector
{
public:explicit HttpServiceConnector(string_view baseUrl): base_url_(baseUrl){// 初始化会话session_.SetHeader(cpr::Header{ {"User-Agent", "C++ HTTP Client"} });session_.SetTimeout(cpr::Timeout{ 10000 });}// 向服务写入数据bool WriteData(string_view endpoint, string_view data){try{session_.SetUrl(cpr::Url{ BuildUrl(endpoint) });session_.SetHeader(cpr::Header{ {"Content-Type", "text/plain"} });session_.SetBody(cpr::Body{ data.data() });cpr::Response response = session_.Post();return HandleResponse(response, "写入");}catch (const exception& e){cerr << "写入异常: " << e.what() << "\n";return false;}}// 从服务查询数据optional<string> QueryData(string_view endpoint, const vector<pair<string, string>>& params = {}){try{// 构建查询参数cpr::Parameters cpr_params;for (const auto& [key, value] : params){cpr_params.Add({ key, value });}session_.SetUrl(cpr::Url{ BuildUrl(endpoint) });session_.SetParameters(cpr_params);cpr::Response response = session_.Get();if (HandleResponse(response, "查询")){return response.text;}return nullopt;}catch (const exception& e){cerr << "查询异常: " << e.what() << "\n";return nullopt;}}private:string base_url_;  // 服务基础URLcpr::Session session_;  // 复用HTTP会话// 构建完整URL (更健壮的实现)string BuildUrl(string_view endpoint) const{string url = base_url_;// 移除base_url末尾的斜杠if (!url.empty() && url.back() == '/') {url.pop_back();}// 添加endpoint前的斜杠if (!endpoint.empty()) {if (endpoint.front() != '/') {url += '/';}url += endpoint;}return url;}// 处理HTTP响应bool HandleResponse(const cpr::Response& response, string_view operation){if (response.error){cerr << operation << "错误: " << response.error.message << "\n";return false;}if (response.status_code >= 200 && response.status_code < 300){cout << operation << "成功! 状态码: " << response.status_code << "\n";return true;}cerr << operation << "失败! 状态码: " << response.status_code<< "\n错误信息: " << response.text << "\n";return false;}
};// 获取当前时间的 ISO 8601 格式字符串 (跨平台实现)
string GetCurrentTimestamp()
{time_t now = time(nullptr);tm timeInfo;// 跨平台UTC时间处理
#if defined(_WIN32)gmtime_s(&timeInfo, &now);
#elsegmtime_r(&now, &timeInfo);
#endifostringstream oss;oss << put_time(&timeInfo, "%Y-%m-%dT%H:%M:%SZ");return oss.str();
}// 传感器数据结构
struct SensorData
{string device_id = "sensor-001";string timestamp = GetCurrentTimestamp();vector<tuple<string, double, string>> readings = {{"temperature", 23.5, "°C"},{"humidity", 45.2, "%"},{"pressure", 1013.25, "hPa"}};pair<double, double> location = { 34.0522, -118.2437 };// 转换为字符串表示string ToString() const{ostringstream data;data << "Device: " << device_id << "\n"<< "Timestamp: " << timestamp << "\n";for (const auto& [name, value, unit] : readings) {data << name << ": " << value << unit << "\n";}data << "Location: " << location.first << ", " << location.second;return data.str();}
};int main() {// 配置服务端地址constexpr string_view base_url = "http://172.35.120.208:9521/HttpServerService";HttpServiceConnector httpClient(base_url);// 创建传感器数据SensorData sensor;const string sensorData = sensor.ToString();cout << "准备发送的数据:\n" << sensorData << "\n\n";// 写入数据bool writeSuccess = true;/* writeSuccess = httpClient.WriteData("post", sensorData);cout << "\n写入结果: " << (writeSuccess ? "成功" : "失败") << endl;*/// 查询数据cout << "\n查询最新数据...\n";vector<pair<string, string>> queryParams = {{"deviceId", sensor.device_id},{"type", "all"}};if (auto result = httpClient.QueryData("Query", queryParams)){cout << "\n查询结果:\n" << *result << "\n";}else{cout << "查询失败\n";}return writeSuccess ? EXIT_SUCCESS : EXIT_FAILURE;
}

运行结果图:

http://www.lqws.cn/news/449713.html

相关文章:

  • Spring Cloud 服务调用详解:Ribbon 负载均衡与 Feign 声明式接口调用
  • 【MATLAB代码】制导方法介绍与例程——追踪法,适用于二维平面,目标是移动的|附完整源代码
  • C++基础算法————并查集
  • 【Dify精讲】第14章:部署架构与DevOps实践【知识卡片】
  • 虹科案例 | 欣旺达如何实现动力电池测试的长期稳定性+自动化?
  • 【NLP入门系列三】NLP文本嵌入(以Embedding和EmbeddingBag为例)
  • 高效获取速卖通商品实时数据:API 接口开发与接入全流程
  • ReAct
  • 【二进制安全作业】250617课上作业4 - start
  • Linux (2)
  • 【stm32】标准库学习——I2C
  • 指标解读——113页企业信息化成熟度评估指标【附全文阅读】
  • 算法第38天|322.零钱兑换\139. 单词拆分
  • C语言:二分搜索函数
  • 【Java学习笔记】线程基础
  • 【RTSP从零实践】2、使用RTP协议封装并传输H264
  • JetBrains IDE v2025.1 升级,AI 智能+语言支持齐飞
  • Maven 之工程化开发核心指南:插件配置、pom 文件与依赖管理
  • GreatSQL加入openKylin社区,共推开源生态建设
  • keep-alive缓存文章列表案例完整代码(Vue3)
  • Symbol.iterator 详解
  • 《被讨厌的勇气》详细概述
  • 【大数据】java API 进行集群间distCP 报错unresolvedAddressException
  • vue3打包后,图片丢失
  • 【unity游戏开发——热更新】什么是Unity热更新
  • 【精选】基于SpringBoot的宠物互助服务小程序平台开发 微信小程序宠物互助系统 宠物互助小程序平台设计与实现 支持救助发布+领养申请+交流互动功能
  • 无人机不再“盲飞”!用Python搞定实时目标识别与跟踪
  • 【Linux驱动开发 ---- 4.2_平台设备(Platform Devices)概述】
  • 1.容器技术与docker环境部署
  • phpstudy无法启动mysql,一启动就关闭,完美解决