C++中发送HTTP请求的方式

news2024/10/7 2:45:28

一,简介

        使用C++编程发送HTTP请求通常需要使用第三方的HTTP库或框架。在C++中,有几个受欢迎的HTTP库可供选择,例如Curl、Boost.Beast和cpp-httplib。另外,也可以自己实现socket来发送http请求

二、使用Curl库发送HTTP请求

1. 确认当前系统是什么系统

 查看版本信息   

cat /etc/os-release

2.linux环境中如何确认是否安装过libcurl

        1> 使用dpkg(适用于Debian/Ubuntu系统):

dpkg -l | grep libcurl

        2> 使用rpm(适用于Red Hat/CentOS系统):

rpm -qa | grep libcurl

        3>  使用yum(适用于CentOS/Red Hat系统,用于检查是否安装,不显示版本):

yum list installed | grep libcurl

        4> 使用apt-get(适用于Debian/Ubuntu系统,用于检查是否安装,不显示版本):

apt-get install libcurl

我使用的是yum方法

3.安装Curl库

        a> 对于Debian/Ubuntu系统:

sudo apt-get install libcurl4-openssl-dev

        b> 对于RHEL/CentOS系统:

sudo yum install libcurl-devel

        c> 对于macOS系统:

brew install curl

使用yum安装

4.编写Curl代码

编写一个C++代码示例来使用Curl库发送HTTP请求。将以下代码保存为.cpp文件

#include <iostream>
#include <curl/curl.h>
 
int main() 
{
    // 初始化Curl库
    curl_global_init(CURL_GLOBAL_ALL);
 
    // 创建Curl句柄
    CURL* curl = curl_easy_init();
    if (!curl) {
        std::cerr << "Failed to initialize Curl." << std::endl;
        return 1;
    }
 
    // 设置请求的URL
    const char* url = "https://www.test.com";
 
    // 设置Curl句柄的URL选项
    curl_easy_setopt(curl, CURLOPT_URL, url);
 
    // 发送GET请求
    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        std::cerr << "Failed to send HTTP request: " << curl_easy_strerror(res) << std::endl;
        curl_easy_cleanup(curl);
        curl_global_cleanup();
        return 1;
    }
 
    // 清理Curl句柄和Curl库
    curl_easy_cleanup(curl);
    curl_global_cleanup();
 
    return 0;
}

5.编译

g++ curl.cpp -lcurl -o example

        这里只是发送一个简单的GET请求到指定的URL,并打印任何响应数据。可以根据需要对代码进行修改和扩展,例如设置请求头、发送POST请求、处理响应数据等。

三,编写Boost.Beast代码

        这里暂时不做boost库安装的介绍

        简单的使用,如下:

#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <iostream>
 
namespace http = boost::beast::http;
 
int main() {
    // 创建Boost.Beast I/O上下文
    boost::asio::io_context ioc;
 
    // 创建TCP解析器
    boost::asio::ip::tcp::resolver resolver(ioc);
 
    // 解析主机名和端口
    boost::asio::ip::tcp::resolver::results_type endpoints =
        resolver.resolve("www.test.com", "https");
 
    // 创建SSL上下文
    boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
 
    // SSL连接
    boost::beast::ssl_stream<boost::asio::ip::tcp::socket> stream(ioc, ctx);
 
    // 连接到服务器
    boost::asio::connect(stream.next_layer(), endpoints.begin(), endpoints.end());
 
    // SSL握手
    stream.handshake(boost::asio::ssl::stream_base::client);
 
    // 创建HTTP请求
    http::request<http::string_body> req(http::verb::get, "/Login", 11);
    req.set(http::field::host, "www.test.com");
    req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);
 
    // 发送HTTP请求
    http::write(stream, req);
 
    // 接收HTTP响应
    boost::beast::flat_buffer buffer;
    http::response<http::dynamic_body> res;
    http::read(stream, buffer, res);
 
    // 打印响应状态码和响应体
    std::cout << "Response code: " << res.result_int() << std::endl;
    std::cout << "Response body: " << boost::beast::buffers_to_string(res.body().data()) << std::endl;
 
    // 关闭SSL连接
    boost::beast::error_code ec;
    stream.shutdown(ec);
 
    // 如果有错误,打印错误信息
    if (ec && ec != boost::asio::error::eof) {
        std::cerr << "Error: " << ec.message() << std::endl;
        return 1;
    }
 
    return 0;
}

编译:

g++ beast_example.cpp -o beast_example -lboost_system -lboost_filesystem -lboost_thread -lboost_iostreams -lssl -lcrypto

四,使用cpp-httplib库发送HTTP请求

下载cpp-httplib库源代码。要从cpp-httplib的GitHub仓库下载库的源代码:
源码库地址:https://github.com/yhirose/cpp-httplib

编写cpp-httplib代码。编写一个使用cpp-httplib库发送HTTP请求的示例代码:

#include <iostream>
#include <httplib.h>
 
int main() {
    // 创建httplib客户端
    httplib::Client client("www.test.com");
 
    // 发送GET请求
    auto response = client.Get("/Login");
 
    // 检查响应
    if (response && response->status == 200) {
        std::cout << "Response body: " << response->body << std::endl;
    } else {
        std::cerr << "Failed to send HTTP request." << std::endl;
        return 1;
    }
 
    return 0;
}

编译:

g++ httplib_example.cpp -std=c++11 -o httplib_example

五,自己实现socket发送 HTTP 请求

        通过使用C++中的套接字(Socket)来发送HTTP请求的方式不具备第三方库或框架那样的功能和性能。

        代码示例:

#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string>
 
int main() {
    // 创建套接字
    int socket_desc = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_desc == -1) {
        std::cerr << "Could not create socket." << std::endl;
        return 1;
    }
 
    // 设定服务器地址和端口
    std::string server = "192.168.1.101";
    int port = 80;
     
    // 解析服务器 IP 地址
    struct hostent* host = gethostbyname(server.c_str());
    if (host == nullptr) {
        std::cerr << "Could not resolve hostname." << std::endl;
        return 1;
    }
    struct in_addr address;
    memcpy(&address, host->h_addr_list[0], sizeof(struct in_addr));
 
    // 设置服务器地址结构
    struct sockaddr_in server_addr{};
    server_addr.sin_addr = address;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
 
    // 连接服务器
    if (connect(socket_desc, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        std::cerr << "Could not connect to server." << std::endl;
        return 1;
    }
 
    // 构建HTTP请求
    std::string request =
        "GET /endpoint HTTP/1.1\r\n"
        "Host: " + server + "\r\n"
        "User-Agent: C++ HTTP Client\r\n"
        "Connection: close\r\n\r\n";
 
    // 发送HTTP请求
    if (send(socket_desc, request.c_str(), request.length(), 0) < 0) {
        std::cerr << "Failed to send HTTP request." << std::endl;
        return 1;
    }
 
    // 接收并打印服务器响应
    std::string response;
    char buffer[4096];
    while (true) {
        memset(buffer, 0, sizeof(buffer));
        int bytes_received = recv(socket_desc, buffer, sizeof(buffer) - 1, 0);
        if (bytes_received <= 0) {
            break;
        }
        response += buffer;
    }
 
    std::cout << response << std::endl;
 
    // 关闭套接字
    close(socket_desc);
 
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1570884.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

day60 动态规划part17

这两题看了自己写的笔记还不懂的话&#xff0c;看看这个up的思路就行&#xff1a; https://space.bilibili.com/111062940/search/video?keyword%E5%9B%9E%E6%96%87 647. 回文子串 中等 提示 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回…

微带线特性阻抗快速计算---根据介质板参数和特性阻抗得到线宽(Matlab代码)

微带线特性阻抗快速计算—根据介质板参数和特性阻抗得到线宽&#xff08;Matlab代码&#xff09; 参考&#xff1a;https://blog.csdn.net/weixin_45811090/article/details/130045689 《射频电路理论与设计》第2版 黄玉兰著 《射频电路设计——理论与应用》第二版 Reinhold L…

STC89C51学习笔记(三)

STC89C51学习笔记&#xff08;三&#xff09; 综述&#xff1a;本文讲述了通过51单片机控制LED闪烁、流水灯、按键控制LED亮灭、按键控制LED实现二进制、按键控制LED左右移。 一、LED 1.LED闪烁 1&#xff09;原理 如果要实现LED闪烁&#xff0c;不可以直接先使LED亮&…

兼顾性能的数据倾斜处理方案

目录 前言 一、场景描述 二、常见的优化方法 2.1 Mapjoin 2.2 特殊值/空值打散 2.3 热点值打散&#xff0c;副表呈倍数扩散 2.4 热点数据单独处理/SkewJoin 2.5 方案总结 三、Distmapjoin 3.1 核心思路 3.2 代码实现 3.3 真实效果 四、方案总结 文章主要是介绍在支…

手把手教你从入门到精通C# MES通信

前言 我们在上位机软件开发的时候,经常需要与客户的MES系统进行通信,一般与MES系统通信需要实现的功能如下: 1、通过输入员工号来获取登录MES系统的权限 2、上传设备检测的OK/NG结果给MES系统; 3、上传设备生产过程中的异常信息给MES系统; 4、上传设备生产过程中的数据,…

(arxiv2401) CrossMAE

作者团队来自加州大学伯克利分校&#xff08;UC Berkeley&#xff09;和加州大学旧金山分校&#xff08;UCSF&#xff09;。论文主要探讨了在MAE的解码中&#xff0c;图像patch之间的依赖性&#xff0c;并提出了一种新的预训练框架 CrossMAE。 论文的主要贡献包括&#xff1a; …

【C++入门】关键字、命名空间以及输入输出

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

Ant Design Vue table固定列失效问题解决

问题描述&#xff1a;项目中封装好的公共table组件&#xff0c;基于Ant Design Vue table封装&#xff1b;使用中&#xff0c;用到了列固定&#xff0c;但是没生效&#xff0c;找了好久的原因。。。最后是因为外层容器标签导致&#xff1b; 解决方法&#xff1a;如果a-table组件…

Windows系统安装OpenSSH结合VS Code远程ssh连接Ubuntu【内网穿透】

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法|MySQL| ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-AwzyR2lkHKjD9HYl {font-family:"trebuchet ms",verdana,arial,sans-serif;f…

【吊打面试官系列】Redis篇 - Redis单进程单线程好处?

大家好&#xff0c;我是锋哥。今天分享关于 【Redis单进程单线程好处&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; Redis单进程单线程好处&#xff1f; 代码更清晰&#xff0c;处理逻辑更简单 不用去考虑各种锁的问题&#xff0c;不存在加锁释放锁操作&…

使用简单MLP实现0-9数字识别,数据集为MNIST

简介 需求&#xff1a; 基于pytorch实现简单MLP&#xff0c;完成数字识别&#xff0c;采用MNIST手写数字作为数据集&#xff0c;MNIST&#xff1a;有6万张训练图片&#xff0c;1万张测试图片训练结束后&#xff0c;随机取3张测试图片&#xff0c;展示模型的预测结果和真实图片…

策略模式图

策略模式 小小的图解 主要的三个角色 Strategy—抽象策略角色ConcreateStrategy—具体策略角色Context—上下文角色 封装了对具体策略的调用可以使用set的依赖注入也可以使用构造方法 核心是上下文角色 只要调用上下文角色就行&#xff0c;实现解耦 策略 工厂 将上下文角…

【java探索之旅】逻辑控制掌握 顺序结构 分支语句

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; Java编程秘籍 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一、逻辑控制的概念二、顺序结构三、分支结构3.1 if语句3.2 if习题巩固3.3 细节注意项…

TR3 - Transformer算法详解

目录 文本输入处理词向量位置向量 编码器 EncoderSelf-Attention多头注意力机制残差连接 解码器 Decoder线性层与Softmax损失函数总结与心得体会 这周来看一下Transformer是怎么将文本转换成向量&#xff0c;然后又输入到模型处理并得到最终的输出的。 文本输入处理 词向量 …

递归算法解读

递归&#xff08;Recursion&#xff09;是计算机科学中的一个重要概念&#xff0c;它指的是一个函数&#xff08;或过程&#xff09;在其定义中直接或间接地调用自身。递归函数通过把问题分解为更小的相似子问题来解决原问题&#xff0c;这些更小的子问题也使用相同的解决方案&…

2024-04-05 问AI: 介绍一下深度学习中的Leaky ReLU函数

文心一言 Leaky ReLU&#xff08;Leaky Rectified Linear Unit&#xff09;函数是深度学习领域中的一种激活函数&#xff0c;主要用于解决ReLU&#xff08;Rectified Linear Unit&#xff09;函数在负值区域为零的问题。ReLU函数在输入为正时保持原样&#xff0c;而在输入为负…

Navicat工具使用

Navicat的本质&#xff1a; 在创立连接时提前拥有了数据库用户名和密码 双击数据库时&#xff0c;相当于建立了一个链接关系 点击运行时&#xff0c;远程执行命令&#xff0c;就像在xshell上操作Linux服务器一样&#xff0c;将图像化操作转换成SQL语句去后台执行 一、打开Navi…

Python学习: 错误和异常

Python 语法错误 解析错误(Parsing Error)通常指的是程序无法正确地解析(识别、分析)所给定的代码,通常是由于代码中存在语法错误或者其他无法理解的结构导致的。这可能是由于缺少括号、缩进错误、未关闭的引号或其他括号等问题造成的。 语法错误(Syntax Error)是指程序…

CSS设置网页颜色

目录 前言&#xff1a; 1.颜色名字&#xff1a; 2.十六进制码&#xff1a; 3.RGB&#xff1a; 4.RGBA&#xff1a; 5.HSL&#xff1a; 1.hue&#xff1a; 2.saturation&#xff1a; 3.lightness&#xff1a; 6.HSLA&#xff1a; 前言&#xff1a; 我们在电脑显示器&…

【NLP练习】中文文本分类-Pytorch实现

中文文本分类-Pytorch实现 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、准备工作 1. 任务说明 本次使用Pytorch实现中文文本分类。主要代码与文本分类代码基本一致&#xff0c;不同的是本次任务使用…