一、Poco 库简介与优势

1.1 什么是 Poco?

Poco Libraries 是一套开源、跨平台、标准 C++ 编写的基础工具库,对标 Java 基础库、Boost 简化替代方案,封装了网络、文件、线程、日志、JSON、加密、HTTP 等高频能力,工业级稳定,广泛用于工控、嵌入式、后台服务、桌面工具开发。

1.2 Poco HTTP 模块核心优势

  • 纯 C++ 跨平台:一套代码全平台编译,无平台兼容成本

  • 零多余依赖:无需 Boost、无需 libcurl,自带完整 HTTP 栈

  • 客户端&服务端双支持:同时实现 HTTP 调用和 HTTP 服务

  • 支持 HTTPS/SSL:内置 OpenSSL 适配,开箱即用加密请求

  • 支持文件上传、表单提交、长连接、超时控制

  • MIT 开源协议:完全免费,可商用

二、Poco 环境搭建与编译

2.1 环境依赖

  • 编译器:GCC7+ / Clang / MSVC2017+

  • 编译工具:CMake / Make

  • 可选依赖:OpenSSL(如需 HTTPS 功能)

2.2 下载 Poco 源码

推荐拉取官方稳定版本:

# 下载源码
git clone https://github.com/pocoproject/poco.git
cd poco
mkdir build && cd build

2.3 CMake 编译命令(Linux/Mac)

# 编译完整模块(含HTTP、SSL、JSON、Net)
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j8
sudo make install

2.4 极简 CMake 项目配置

新建业务项目 CMakeLists.txt,适配所有 HTTP 示例:

cmake_minimum_required(VERSION 3.13)
project(PocoHttpDemo)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 查找Poco库
find_package(Poco REQUIRED Net Util JSON NetSSL)

# 引入头文件与库
include_directories(${Poco_INCLUDE_DIRS})
link_directories(${Poco_LIBRARY_DIRS})

# 可执行文件
add_executable(http_demo main.cpp)
target_link_libraries(http_demo 
    Poco::Net 
    Poco::Util 
    Poco::JSON 
    Poco::NetSSL
)

三、核心实战示例一:HTTP 客户端 GET 请求

实现最常用的 HTTP GET 请求、参数拼接、响应读取、超时控制,可直接调用第三方接口

#include <iostream>
#include <string>
// Poco HTTP核心头文件
#include <Poco/Net/HTTPClientSession.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/StreamCopier.h>
#include <Poco/URI.h>

using namespace Poco;
using namespace Poco::Net;

// HTTP GET 请求示例
void HttpGetDemo()
{
    try
    {
        // 1. 定义请求地址
        std::string url = "http://httpbin.org/get?name=Poco&age=20";
        URI uri(url);

        // 2. 创建HTTP会话
        HTTPClientSession session(uri.getHost(), uri.getPort());
        session.setTimeout(Poco::Timespan(5, 0)); // 5秒超时

        // 3. 构造GET请求
        HTTPRequest request(HTTPRequest::HTTP_GET, uri.getPathAndQuery(), HTTPRequest::HTTP_11);
        request.set("User-Agent", "Poco-C++-HttpClient");

        // 4. 发送请求、获取响应
        HTTPResponse response;
        std::ostream& out = session.sendRequest(request);
        std::istream& in = session.receiveResponse(response);

        // 5. 读取响应内容
        std::string resBody;
        StreamCopier::copyToString(in, resBody);

        // 输出结果
        std::cout << "响应状态码:" << response.getStatus() << std::endl;
        std::cout << "响应内容:\n" << resBody << std::endl;

        session.close();
    }
    catch (Poco::Exception& e)
    {
        std::cerr << "GET请求异常:" << e.what() << std::endl;
    }
}

int main()
{
    HttpGetDemo();
    return 0;
}

四、核心实战示例二:HTTP 客户端 POST JSON 请求

日常开发高频场景:POST 提交 JSON 数据,适配后端接口交互。

#include <iostream>
#include <string>
#include <Poco/Net/HTTPClientSession.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/StreamCopier.h>
#include <Poco/URI.h>
#include <Poco/JSON/Parser.h>

using namespace Poco;
using namespace Poco::Net;
using namespace Poco::JSON;

void HttpPostJsonDemo()
{
    try
    {
        std::string url = "http://httpbin.org/post";
        URI uri(url);

        HTTPClientSession session(uri.getHost(), uri.getPort());
        session.setTimeout(Poco::Timespan(5, 0));

        // 1. 构造POST JSON请求
        HTTPRequest request(HTTPRequest::HTTP_POST, uri.getPath(), HTTPRequest::HTTP_11);
        request.setContentType("application/json;charset=utf-8");
        request.set("User-Agent", "Poco-Post-Client");

        // 2. 构造JSON报文
        Parser parser;
        Dynamic::Var obj = parser.parse("{}");
        JSONObject::Ptr json = obj.extract<JSONObject::Ptr>();
        json->set("username", "CSDN-Poco");
        json->set("password", "123456");
        json->set("code", 200);

        std::string postBody = json->toString();
        request.setContentLength(postBody.length());

        // 3. 发送请求体
        std::ostream& out = session.sendRequest(request);
        out << postBody;

        // 4. 接收响应
        HTTPResponse response;
        std::istream& in = session.receiveResponse(response);
        std::string resBody;
        StreamCopier::copyToString(in, resBody);

        std::cout << "POST响应:\n" << resBody << std::endl;

        session.close();
    }
    catch (Poco::Exception& e)
    {
        std::cerr << "POST请求异常:" << e.what() << std::endl;
    }
}

int main()
{
    HttpPostJsonDemo();
    return 0;
}

五、进阶示例三:HTTP 表单文件上传

Poco 自带 HTMLForm,轻松实现表单参数+文件上传,无需手动拼接二进制流。

#include <iostream>
#include <Poco/Net/HTTPClientSession.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/Net/HTMLForm.h>
#include <Poco/StreamCopier.h>
#include <Poco/URI.h>

using namespace Poco;
using namespace Poco::Net;

void HttpUploadFileDemo()
{
    try
    {
        std::string url = "http://httpbin.org/post";
        URI uri(url);

        HTTPClientSession session(uri.getHost(), uri.getPort());
        session.setTimeout(Poco::Timespan(10, 0));

        HTTPRequest request(HTTPRequest::HTTP_POST, uri.getPath(), HTTPRequest::HTTP_11);

        // 构造表单
        HTMLForm form;
        form.set("desc", "Poco文件上传测试");
        // 上传本地文件(自行替换文件路径)
        form.addFile("file", "test.txt", "hello poco http lib");

        // 设置表单Content-Type
        form.prepareSend(request);

        // 发送表单数据
        std::ostream& out = session.sendRequest(request);
        form.write(out);

        // 接收响应
        HTTPResponse response;
        std::istream& in = session.receiveResponse(response);
        std::string resBody;
        StreamCopier::copyToString(in, resBody);

        std::cout << "文件上传响应:\n" << resBody << std::endl;

        session.close();
    }
    catch (Poco::Exception& e)
    {
        std::cerr << "文件上传异常:" << e.what() << std::endl;
    }
}

int main()
{
    HttpUploadFileDemo();
    return 0;
}

六、核心实战示例四:Poco HTTP 服务端(极简接口服务)

很多人只知道 Poco 做客户端,不知道 Poco 可以快速搭建轻量 HTTP 服务端,适合内嵌式接口服务。

#include <iostream>
#include <Poco/Net/HTTPServer.h>
#include <Poco/Net/HTTPRequestHandler.h>
#include <Poco/Net/HTTPRequestHandlerFactory.h>
#include <Poco/Net/HTTPServerParams.h>
#include <Poco/Net/HTTPServerRequest.h>
#include <Poco/Net/HTTPServerResponse.h>
#include <Poco/Net/ServerSocket.h>
#include <Poco/JSON/JSONObject.h>

using namespace Poco;
using namespace Poco::Net;
using namespace Poco::JSON;

// 自定义请求处理器
class MyRequestHandler : public HTTPRequestHandler
{
public:
    void handleRequest(HTTPServerRequest& req, HTTPServerResponse& resp) override
    {
        resp.setChunkedTransferEncoding(true);
        resp.setContentType("application/json;charset=utf-8");

        std::ostream& out = resp.send();

        // 简单路由
        if (req.getURI() == "/hello")
        {
            JSONObject json;
            json.set("code", 200);
            json.set("msg", "success");
            json.set("data", "Hello Poco HTTP Server!");
            out << json.toString();
        }
        else if (req.getURI() == "/api/info")
        {
            JSONObject json;
            json.set("code", 200);
            json.set("name", "Poco-C++-HTTP");
            json.set("author", "CSDN");
            out << json.toString();
        }
        else
        {
            out << R"({"code":404,"msg":"接口不存在"})";
        }

        out.flush();
    }
};

// 处理器工厂
class MyHandlerFactory : public HTTPRequestHandlerFactory
{
public:
    HTTPRequestHandler* createRequestHandler(const HTTPServerRequest&) override
    {
        return new MyRequestHandler();
    }
};

int main()
{
    try
    {
        // 监听8080端口
        ServerSocket socket(8080);
        HTTPServerParams* params = new HTTPServerParams();
        params->setKeepAlive(false);

        HTTPServer server(new MyHandlerFactory(), socket, params);
        server.start();
        std::cout << "Poco HTTP服务启动成功,监听端口:8080" << std::endl;

        // 阻塞等待
        getchar();
        server.stop();
    }
    catch (Poco::Exception& e)
    {
        std::cerr << "服务启动异常:" << e.what() << std::endl;
    }
    return 0;
}

服务端测试

启动程序后访问:

  • http://127.0.0.1:8080/hello

  • http://127.0.0.1:8080/api/info

正常返回标准 JSON 数据,极简 HTTP 接口服务搭建完成!

七、进阶示例五:HTTPS 加密请求

Poco 支持 HTTPS 开箱即用,只需替换 SSL 会话类,代码改动极小:

#include <iostream>
#include <Poco/Net/SecureStreamSocket.h>
#include <Poco/Net/SecureStreamSocketImpl.h>
#include <Poco/Net/HTTPSClientSession.h>
#include <Poco/Net/HTTPRequest.h>
#include <Poco/Net/HTTPResponse.h>
#include <Poco/StreamCopier.h>
#include <Poco/URI.h>

using namespace Poco;
using namespace Poco::Net;

void HttpsGetDemo()
{
    try
    {
        std::string url = "https://httpbin.org/get";
        URI uri(url);

        // 使用HTTPS客户端会话
        HTTPSClientSession session(uri.getHost(), uri.getPort());
        session.setTimeout(Poco::Timespan(5, 0));

        HTTPRequest request(HTTPRequest::HTTP_GET, uri.getPathAndQuery(), HTTPRequest::HTTP_11);
        HTTPResponse response;

        std::ostream& out = session.sendRequest(request);
        std::istream& in = session.receiveResponse(response);

        std::string res;
        StreamCopier::copyToString(in, res);
        std::cout << "HTTPS响应:\n" << res << std::endl;

        session.close();
    }
    catch (Poco::Exception& e)
    {
        std::cerr << "HTTPS请求异常:" << e.what() << std::endl;
    }
}

int main()
{
    HttpsGetDemo();
    return 0;
}

八、常见报错与解决方案

8.1 编译报错:undefined reference

原因:未链接 Net/JSON/NetSSL 模块

解决:CMake 中必须链接 Poco::Net Poco::JSON Poco::NetSSL

8.2 网络请求超时

解决:手动设置session.setTimeout(Timespan(5,0)) 延长超时时间

8.3 HTTPS 证书校验失败

解决:测试环境可关闭证书校验,生产环境配置合法证书链

九、总结

Poco 是 C++ 轻量网络开发的神器,相比 libcurl、Boost.Beast,它的优势是:API 简单、功能聚合、跨平台零适配、同时支持客户端+服务端。

本文覆盖了工业级最常用的 5 大场景:

  • HTTP GET 常规请求

  • HTTP POST JSON 交互

  • 表单文件上传

  • 自建 HTTP 接口服务端

  • HTTPS 加密网络请求

所有代码均可直接复制编译运行,可直接用于项目开发、工具开发、嵌入式 HTTP 服务场景。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐