QHttp: 一个开源的轻量级、异步、高性能 HTTP 库

目录

1.简介

2.核心类架构

3.安装与集成

3.1.环境准备

3.2.编译

[3.3.集成到 CMake 项目](#3.3.集成到 CMake 项目)

4.完整使用示例

5.注意事项

6.适用场景


1.简介

QHttp 是一个第三方开源的轻量级、异步、高性能 HTTP 库 ,专为 Qt5/C++14 设计,同时提供服务器端客户端 功能。它并非 Qt 官方模块,而是由社区开发者 azadkuh 维护的独立项目(GitHub: https://github.com/azadkuh/qhttp),采用 MIT 许可协议。

注意区分 :不要与 Qt4 时代的 QtNetwork 模块中的QHttp类(已被QNetworkAccessManager取代)混淆,也不要与 Qt 6.4 + 官方的QHttpServer模块混淆Qt

核心优势:

特性 说明
异步非阻塞 基于 Qt 事件循环,单线程可处理数千并发连接,无阻塞调用
双端支持 同时提供 HTTP 服务器和客户端实现,可灵活切换使用
自动内存管理 连接、请求、响应对象在 socket 断开时自动删除,降低内存泄漏风险
高效 HTTP 解析 基于 Joyent 的 http-parser 库,快速解析 HTTP 请求 / 响应
轻量级 无额外依赖(仅 Qt5 和 C++14),编译后体积小,适合嵌入式场景
PIMPL 设计 私有实现分离,接口稳定,降低二进制兼容性风险
灵活配置 支持 TCP/Unix 套接字、自定义超时、请求大小限制等

2.核心类架构

服务器端类 功能
QHttpServer 核心服务器类,监听端口、接受连接、分发请求
QHttpConnection 单个客户端连接管理,处理底层 socket 通信
QHttpRequest HTTP 请求解析,包含方法、URL、头部、正文等信息
QHttpResponse HTTP 响应构建,设置状态码、头部、发送响应内容
客户端类 功能
QHttpClient 发送 HTTP 请求,支持 GET/POST/PUT/DELETE 等方法
QHttpRequest 构建请求,设置 URL、头部、请求体等
QHttpResponse 解析响应,获取状态码、头部、响应体等

3.安装与集成

3.1.环境准备

  • 依赖:Qt5.7+、C++14 编译器(GCC 5+/Clang 3.4+/MSVC 2015+)
  • 第三方依赖:http-parser(会自动下载)

3.2.编译

cpp 复制代码
# 1. 克隆仓库
git clone https://github.com/azadkuh/qhttp.git
cd qhttp

# 2. 更新依赖(自动下载http-parser),如果不能执行请自行下载
./update-dependencies.sh

#或
mkdir 3rdparty
cd  3rdparty
git clone https://github.com/nodejs/http-parser.git

# 3. 编译配置
qmake -r qhttp.pro  # 或 qmake6 适用于Qt6兼容版本
# 可选配置:禁用客户端功能(节省体积)
# qmake "DEFINES+=QHTTP_DISABLE_CLIENT" -r qhttp.pro

# 4. 编译安装
#windows:
nmake

#linux
make -j$(nproc)
sudo make install  # 安装到系统目录(可选)

编译完后,在xbin目录下生成了库和demo程序:

3.3.集成到 CMake 项目

cpp 复制代码
# CMakeLists.txt
find_package(Qt5 REQUIRED COMPONENTS Core Network)
add_subdirectory(path/to/qhttp)  # 或 find_package(qhttp REQUIRED)

add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE Qt5::Core Qt5::Network qhttp)

4.完整使用示例

1.服务器端示例:Hello World + REST API

cpp 复制代码
#include <QCoreApplication>
#include "qhttp/qhttpserver.hpp"
#include "qhttp/qhttprequest.hpp"
#include "qhttp/qhttpresponse.hpp"

using namespace qhttp::server;

int main(int argc, char *argv[]) {
    QCoreApplication app(argc, argv);
    QHttpServer server(&app);

    // 基础路由:GET /
    server.route("/", [](QHttpRequest *req, QHttpResponse *res) {
        res->setStatusCode(qhttp::ESTATUS_OK);
        res->addHeader("Content-Type", "text/plain; charset=utf-8");
        res->end("Hello World from QHttp Server!");
    });

    // REST API:GET /user/<name>
    server.route("/user/(.*)", [](QHttpRequest *req, QHttpResponse *res, const QStringList &captures) {
        QString name = captures[0];
        res->setStatusCode(qhttp::ESTATUS_OK);
        res->addHeader("Content-Type", "application/json");
        res->end(QString(R"({"message": "Hello, %1!"})").arg(name).toUtf8());
    });

    // POST请求处理:接收JSON数据
    server.route("/api/data", qhttp::EHTTP_POST, [](QHttpRequest *req, QHttpResponse *res) {
        // 读取请求体
        req->collectData();
        QObject::connect(req, &QHttpRequest::end, [req, res]() {
            QByteArray body = req->collectedData();
            qDebug() << "Received POST data:" << body;
            
            res->setStatusCode(qhttp::ESTATUS_OK);
            res->addHeader("Content-Type", "application/json");
            res->end(R"({"status": "success", "received_size": )" + 
                    QByteArray::number(body.size()) + "}");
        });
    });

    // 启动服务器
    quint16 port = 8080;
    if (!server.listen(QHostAddress::Any, port)) {
        qCritical() << "Failed to start server on port" << port;
        return 1;
    }

    qInfo() << "Server running on port" << port;
    return app.exec();
}

2.客户端示例:发送 GET/POST 请求

cpp 复制代码
#include <QCoreApplication>
#include "qhttp/qhttpclient.hpp"
#include "qhttp/qhttprequest.hpp"
#include "qhttp/qhttpresponse.hpp"

using namespace qhttp::client;

int main(int argc, char *argv[]) {
    QCoreApplication app(argc, argv);
    QHttpClient client(&app);

    // 发送GET请求
    client.request(qhttp::EHTTP_GET, "http://localhost:8080/user/QtDeveloper")
        .onResponse([](QHttpResponse *res) {
            qDebug() << "GET Status:" << res->statusCode();
            res->collectData();
            QObject::connect(res, &QHttpResponse::end, [&app, res]() {
                qDebug() << "GET Response:" << res->collectedData();
                // 发送POST请求
                QHttpClient client2(&app);
                client2.request(qhttp::EHTTP_POST, "http://localhost:8080/api/data")
                    .addHeader("Content-Type", "application/json")
                    .setData(R"({"name": "QHttp", "version": "3.1"})")
                    .onResponse([&app](QHttpResponse *res2) {
                        qDebug() << "POST Status:" << res2->statusCode();
                        res2->collectData();
                        QObject::connect(res2, &QHttpResponse::end, [&app, res2]() {
                            qDebug() << "POST Response:" << res2->collectedData();
                            app.quit();  // 退出应用
                        });
                    })
                    .exec();
            });
        })
        .exec();

    return app.exec();
}

5.注意事项

1.性能优化技巧

  • 连接复用 :服务器端启用setKeepAlive(true),支持 HTTP 长连接,减少握手开销
  • 请求限制 :使用setMaxRequestSize()防止大请求攻击,setTimeout()处理超时连接
  • 异步处理:复杂业务逻辑放入 Qt 线程池,避免阻塞事件循环
cpp 复制代码
// 性能优化配置示例
server.setKeepAlive(true, 30000);  // 长连接超时30秒
server.setMaxRequestSize(1024*1024);  // 限制请求体最大1MB
server.setTimeout(10000);  // 连接超时10秒

2.错误处理与日志记录

cpp 复制代码
// 错误处理示例
server.onError([](QHttpServer::Error error) {
    qCritical() << "Server error:" << static_cast<int>(error);
});

// 请求日志记录
server.beforeRouting([](QHttpRequest *req, QHttpResponse *res) {
    qInfo() << "Request:" << req->methodString() << req->url().toString();
    return true;  // 继续路由处理
});

3.部署为系统服务

结合 QtService 库将 QHttp 服务器部署为 Windows 服务或 Linux 守护进程:

cpp 复制代码
#include <QtService>
#include "qhttp/qhttpserver.hpp"

class HttpService : public QtService<QCoreApplication> {
public:
    HttpService(int argc, char **argv) 
        : QtService<QCoreApplication>(argc, argv, "QHttp Daemon") {}

protected:
    void start() override {
        QCoreApplication* app = application();
        _server = new qhttp::server::QHttpServer(app);
        
        // 配置服务器...
        _server->route("/", [](qhttp::server::QHttpRequest *req, qhttp::server::QHttpResponse *res) {
            res->end("Hello from QHttp Service!");
        });
        
        if (!_server->listen(QHostAddress::Any, 8080)) {
            qCritical() << "Failed to start service";
            stop();
        }
    }

private:
    qhttp::server::QHttpServer* _server;
};

QTSERVICE_MAIN(HttpService)

6.适用场景

推荐使用场景

  • Qt5 项目:需要嵌入式 HTTP 服务器 / 客户端,无法升级到 Qt6
  • 资源受限环境:追求轻量级、低内存占用,如嵌入式设备
  • 双端需求:同时需要 HTTP 服务器和客户端功能,减少依赖库数量
  • 自定义协议:需要深度控制 HTTP 协议细节,实现非标准扩展

不推荐使用场景

  • Qt6 项目 :优先选择官方QHttpServer模块,维护更有保障
  • WebSocket 需求:QHttp 不支持 WebSocket,需额外集成其他库
  • 复杂 Web 应用:需要完整 Web 框架功能(如模板引擎、会话管理)
相关推荐
小小de风呀1 小时前
de风——【从零开始学C++】(八):string的模拟实现
开发语言·c++
程序猿编码1 小时前
藏在TCP握手里的暗号:一种基于序列号触发的加密回连后门
linux·网络·网络协议·tcp/ip
minji...1 小时前
Linux 网络基础之传输层协议TCP(八)拥塞控制,延迟应答,捎带应答,TCP粘包问题,异常退出问题
linux·服务器·网络·网络协议·tcp/ip·http·智能路由器
宏笋1 小时前
QT 实现文件资源浏览器
qt
basketball6162 小时前
C++ 面向对象编程:思想、原则与实践
开发语言·c++
不是山谷.:.2 小时前
websocket的封装
开发语言·前端·网络·笔记·websocket·网络协议
故事和你912 小时前
洛谷-【图论2-2】最短路4
开发语言·数据结构·c++·算法·动态规划·图论
輕華2 小时前
YOLOv10轮毂缺陷检测(下)——模型推理与PyQt5可视化应用
开发语言·qt·yolo
kyle~2 小时前
机器人感知---工业相机硬触发、时间戳同步( PTP)与 ROS2 驱动时间戳设计
linux·c++·机器人·ros2