HTTP клиент на C++: делаем запросы правильно от А до Я

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

HTTP клиент на C++: делаем запросы правильно от А до Я

В современном мире разработки программного обеспечения умение взаимодействовать с удаленными серверами через HTTP — это базовый навык. Будь то загрузка данных с API, отправка форм или работа с веб-сервисами, C++ предоставляет несколько мощных инструментов для создания HTTP-клиентов. В этой статье мы разберем, как правильно делать HTTP-запросы на C++, рассмотрим популярные библиотеки и напишем рабочие примеры кода.

Почему C++ для HTTP-запросов?

C++ не имеет встроенной поддержки HTTP в стандартной библиотеке, в отличие от Python или JavaScript. Однако это не проблема: существуют проверенные временем библиотеки, которые позволяют легко и эффективно отправлять запросы. Основные варианты:

  • libcurl (cURL) — самая популярная кроссплатформенная библиотека.
  • Boost.Beast — современная библиотека на основе Boost.Asio.
  • WinHTTP — встроенное решение для Windows.
  • Qt Network — для проектов на Qt.

В этой статье мы сосредоточимся на первых двух, так как они наиболее универсальны и подходят для большинства задач.

1. HTTP-клиент с использованием libcurl

libcurl — это проверенная годами библиотека, которая поддерживает HTTP, HTTPS, FTP и множество других протоколов. Она проста в использовании и отлично документирована.

Установка libcurl

Для Linux (Ubuntu/Debian):

sudo apt-get install libcurl4-openssl-dev

Для Windows можно скачать предварительно собранные бинарные файлы с официального сайта curl.se или использовать vcpkg:

vcpkg install curl

Простой GET-запрос

Напишем базовый пример получения данных с сервера:

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

// Функция обратного вызова для записи данных
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* output) {
    size_t totalSize = size * nmemb;
    output->append((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);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); // Отключаем проверку SSL для теста

    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        std::cerr << "Ошибка запроса: " << curl_easy_strerror(res) << std::endl;
    } else {
        std::cout << "Ответ сервера:\n" << response << std::endl;
    }

    curl_easy_cleanup(curl);
    return 0;
}

Компилировать нужно с флагом -lcurl:

g++ -o http_client http_client.cpp -lcurl

POST-запрос с отправкой JSON

Теперь добавим отправку данных:

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

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);
    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::cout << "POST ответ:\n" << response << std::endl;
    }

    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    return 0;
}

2. HTTP-клиент с использованием Boost.Beast

Boost.Beast — это мощная библиотека для работы с HTTP и WebSocket на основе Boost.Asio. Она дает полный контроль над процессом и идеально подходит для асинхронных приложений.

Установка Boost

На Linux:

sudo apt-get install libboost-all-dev

На Windows через vcpkg:

vcpkg install boost-beast

Синхронный GET-запрос

#include <iostream>
#include <string>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>

namespace beast = boost::beast;
namespace http = beast::http;
namespace net = boost::asio;
using tcp = net::ip::tcp;

int main() {
    try {
        net::io_context ioc;
        tcp::resolver resolver(ioc);
        beast::tcp_stream stream(ioc);

        // Разрешаем домен и устанавливаем соединение
        auto const results = resolver.resolve("jsonplaceholder.typicode.com", "80");
        stream.connect(results);

        // Формируем GET-запрос
        http::request<http::string_body> req{http::verb::get, "/posts/1", 11};
        req.set(http::field::host, "jsonplaceholder.typicode.com");
        req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);

        // Отправляем запрос
        http::write(stream, req);

        // Получаем ответ
        beast::flat_buffer buffer;
        http::response<http::dynamic_body> res;
        http::read(stream, buffer, res);

        // Выводим результат
        std::cout << "Статус: " << res.result_int() << std::endl                

Блоги

Рекомендаций по книгам