C++ HTTP客户端:从零开始正确发起请求

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

HTTP 客户端在 C++ 中:从 A 到 Z 正确发起请求

在现代编程世界中,通过 HTTP 协议与远程服务器交互是一项基本任务。无论是从 API 获取数据、发送表单还是下载文件——掌握 HTTP 请求的处理能力对每位 C++ 开发者来说都是必要的。在本文中,我们将详细讲解如何在 C++ 中创建一个完整的 HTTP 客户端,介绍流行的库和最佳实践。

为什么需要 C++ 的 HTTP 客户端?

与内置 HTTP 库的语言(如 Python、JavaScript)不同,C++ 的标准库中没有用于处理 HTTP 的标准工具。但这并不是问题,因为有多个经过时间考验的强大解决方案:

  • libcurl — 最流行且功能强大的 URL 处理库
  • cpprestsdk (Casablanca) — 微软开发的现代异步库
  • Boost.Beast — 基于 Boost.Asio 的低级处理库

在本文中,我们将重点介绍 libcurl 和 cpprestsdk,因为它们是最常用的解决方案。

libcurl 基础

libcurl 是一个经过时间考验的库,支持多种协议,包括 HTTP/1.1、HTTP/2、FTP 等。它用 C 语言编写,但拥有出色的 C++ 绑定。

安装 libcurl

安装 libcurl 取决于您的操作系统:

# Ubuntu/Debian
sudo apt-get install libcurl4-openssl-dev

# macOS (通过 Homebrew)
brew install curl

# Windows (通过 vcpkg)
vcpkg install curl

使用 libcurl 发送简单的 GET 请求

我们从基本示例开始——发送 GET 请求并获取响应:

#include <iostream>
#include <curl/curl.h>
#include <string>

// 用于写入数据的回调函数
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;
}

int main() {
    CURL* curl = curl_easy_init();
    if (!curl) {
        std::cerr << "CURL 初始化错误" << std::endl;
        return 1;
    }

    std::string response;
    
    curl_easy_setopt(curl, CURLOPT_URL, "https://jsonplaceholder.typicode.com/posts/1");
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
    
    CURLcode res = curl_easy_perform(curl);
    
    if (res != CURLE_OK) {
        std::cerr << "请求错误: " << curl_easy_strerror(res) << std::endl;
    } else {
        std::cout << "服务器响应:" << std::endl;
        std::cout << response << std::endl;
    }
    
    curl_easy_cleanup(curl);
    return 0;
}

发送带数据的 POST 请求

POST 请求用于向服务器发送数据。我们来看一个包含 JSON 数据的示例:

#include <iostream>
#include <curl/curl.h>
#include <string>

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;
}

int main() {
    CURL* curl = curl_easy_init();
    if (!curl) return 1;

    std::string response;
    std::string jsonData = R"({"title": "foo", "body": "bar", "userId": 1})";
    
    struct curl_slist* headers = nullptr;
    headers = curl_slist_append(headers, "Content-Type: application/json");
    
    curl_easy_setopt(curl, CURLOPT_URL, "https://jsonplaceholder.typicode.com/posts");
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, jsonData.c_str());
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    cur                

博客

书籍推荐