C++ 语言发起 HTTP 代理请求代码示例

发布于 2026-02-07 | 作者: FreeProxy Team

在 C++ 项目中发起 HTTP 代理请求,最成熟的方案是使用 libcurl 的 easy 接口:CURLOPT_PROXY 一个选项就能让整个请求经代理服务器转发。libcurl 跨平台、久经生产环境验证,对 HTTP、HTTPS 与 SOCKS5 代理都有完善支持,是下载器、采集器与网络客户端的常见选择。本文从安装编译讲到完整示例,再逐条拆解错误码处理与认证细节,帮你避开 C++ 网络编程的常见陷阱。

环境准备与 libcurl 安装

libcurl 在各大平台都有现成的发行包。Ubuntu 与 Debian 执行 apt 安装开发包,macOS 使用 Homebrew,Windows 推荐通过 vcpkg 安装以自动处理头文件与库路径。CMake 工程则使用 find_package 引入,并把目标链接到可执行文件上。

  • Linux:sudo apt-get install libcurl4-openssl-dev,编译时追加 -lcurl。
  • Windows:vcpkg install curl:x64-windows,自动集成依赖与链接配置。
  • CMake:find_package(CURL REQUIRED) 并链接 CURL::libcurl 目标。

CURLOPT_PROXY 与相关选项详解

CURLOPT_PROXY 接受完整的代理 URL,协议前缀可以是 http://、https:// 或 socks5://;主机与端口也可以拆开,分别用 CURLOPT_PROXY 与 CURLOPT_PROXYPORT 指定。需要认证时用 CURLOPT_PROXYUSERPWD 传入「用户名:密码」格式的字符串,libcurl 会自动完成 Basic 认证协商。CURLOPT_WRITEFUNCTION 指定回调函数接收响应体;CURLOPT_FOLLOWLOCATION 让 libcurl 自动跟随 301、302 跳转;CURLOPT_CONNECTTIMEOUT 与 CURLOPT_TIMEOUT 分别限制与代理建连和整个请求的时长,单位都是秒,二者配合可以快速淘汰不稳定节点。

完整代码示例

下面的例子完成一次经代理的 GET 请求,包含响应接收、状态码读取与错误输出:

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

static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp)
{
    size_t total = size * nmemb;
    static_cast<std::string*>(userp)->append(static_cast<char*>(contents), total);
    return total;
}

int main()
{
    curl_global_init(CURL_GLOBAL_DEFAULT);

    CURL* curl = curl_easy_init();
    if (!curl) {
        std::cerr << "curl_easy_init 失败" << std::endl;
        return 1;
    }

    std::string response;
    curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/ip");
    curl_easy_setopt(curl, CURLOPT_PROXY, "http://127.0.0.1:8080");
    curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, "user:pass");
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);

    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        std::cerr << "请求失败: " << curl_easy_strerror(res) << std::endl;
    } else {
        long code = 0;
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
        std::cout << "状态码: " << code << std::endl;
        std::cout << response << std::endl;
    }

    curl_easy_cleanup(curl);
    curl_global_cleanup();
    return 0;
}

res 不等于 CURLE_OK 时,用 curl_easy_strerror 把错误码转成可读文本,方便写入日志。curl_easy_init 与 curl_easy_cleanup 必须成对出现;curl_global_init 不是线程安全的,应在程序启动阶段、单线程环境下调用一次。

HTTPS 与 SOCKS5 代理的支持

目标是 https:// 地址时,libcurl 会自动向 HTTP 代理发送 CONNECT 请求建立隧道,无需额外配置;也可以显式打开 CURLOPT_HTTPPROXYTUNNEL 表达意图。SOCKS5 代理把地址写成 socks5://host:port 即可,或用 CURLOPT_PROXYTYPE 指定 CURLPROXY_SOCKS5;如果希望域名解析也交给代理端执行,以规避本地 DNS 污染,请改用 CURLPROXY_SOCKS5_HOSTNAME 或 socks5h:// 前缀。证书校验默认开启,遇到自签证书应导入 CA 而不是关闭校验。

常见错误码与注意事项

  • CURLE_COULDNT_CONNECT(7):代理地址或端口不通,先用 telnet 或 nc 验证连通性。
  • CURLE_OPERATION_TIMEDOUT(28):连接或整体超时,区分两个超时选项分别调大。
  • CURLE_PEER_FAILED_VERIFICATION(60):证书校验失败,导入代理或站点的 CA 证书。
  • 响应 407:认证信息错误,或代理账号未授权当前出口 IP。

Article ID: 40

(本文仅供技术交流,请遵守法律法规)

返回知识库
广告区域 (Ad Space)