跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
C++算法

C++ 手写 JSON 与 HTTP Web 服务器实战

基于 C++ 深入讲解 JSON 序列化原理及 HTTP 协议规范,结合 Socket 编程与线程池技术,从零实现一个支持计算功能的 Web 服务器。内容涵盖请求报文解析、静态资源处理、动态业务逻辑映射及响应构建,适合希望掌握底层网络通信机制的开发者参考。

GopherDev发布于 2026/3/21更新于 2026/5/13 浏览
C++ 手写 JSON 与 HTTP Web 服务器实战

前置知识

在深入本文之前,建议熟悉序列化与反序列化的基本概念。对于基于 TCP 协议通信的双方,由于 TCP 是面向字节流的,发送数据前通常需要定义结构化的数据容器。直接传递内存字节会引发字节序和内存对齐问题,因此需要借助序列化将结构化数据转换为连续的字节流。

JSON 基础与使用

JSON(JavaScript Object Notation)是一种轻量级、基于文本的数据交换格式。它源于 JavaScript,但已广泛应用于多种编程语言。JSON 本质上是符合特定规范的字符串,支持对象、数组、字符串、数字、布尔值和 null 等类型。

在实际开发中,我们通常使用成熟的第三方库来处理 JSON。C++ 中常用的 json.hpp(即 nlohmann/json)提供了丰富的接口。它通过一个类对象映射并承载解析后的 JSON 数据,大大简化了处理流程。

初始化与操作

json 类的定义位于 nlohmann 命名空间内。创建对象主要有两种方式:

  1. 列表初始化:利用 C++11 特性,直接传递键值对或元素。
#include "json.hpp"
using json = nlohmann::json;

int main() {
    // 对象初始化
    json j = {{"name", "WZ"}, {"age", 20}};
    
    // 数组初始化
    json arr = {1, 2, 3};
    return 0;
}
  1. 赋值运算符:更符合 C++ 标准库容器的使用习惯。
json j;
j["name"] = "wz";
j["age"] = 20;
序列化与反序列化

dump() 成员函数用于序列化,返回 std::string。不传参数时生成紧凑格式;传入整数参数则进行格式化缩进。网络传输中通常建议使用紧凑格式以减少体积。

反序列化使用静态成员函数 parse()。为了处理转义字符繁琐的问题,C++11 引入了原始字符串字面量 R"()" 语法,方便构造 JSON 字符串。

std::string s = R"({"name":"WZ","age":18})";
json j = json::parse(s);
原理剖析

json.hpp 内部维护一个 json 类,包含类型变量与联合体形式的值变量。联合体设计使得同一时刻只能表示一种数据类型。构造函数根据输入决定类型标签,并在堆上分配相应的存储空间(如 或 )。 重载实现了灵活的访问逻辑,若当前为空对象,会自动转为对应类型并初始化。

std::map
std::vector
operator[]

HTTP 协议详解

HTTP 作为应用层协议,定义了客户端与服务端交互的规则。其核心在于请求与响应报文的格式约束。

URL 与域名

URL(Uniform Resource Locator)统一资源定位符由协议、域名、端口、路径等组成。域名通过 DNS 解析为 IP 地址,这是通信的前提。DNS 查询过程涉及本地缓存、hosts 文件及根域名服务器的迭代查询。

请求报文

HTTP 请求报文由请求行、请求头、空行和可选的请求正文组成。

  • 请求行:包含方法(GET/POST)、URL 和协议版本。
  • 请求头:键值对形式,包含 Host、User-Agent、Content-Type 等信息。
  • 正文:GET 请求通常无正文,POST 请求携带表单数据。

常见的请求方法包括 GET(获取资源)、POST(提交数据)、PUT(更新)、DELETE(删除)等。实际开发中 GET 和 POST 最为常用。

响应报文

响应报文结构与请求报文对称,包含响应行、响应头、空行和响应正文。

  • 响应行:协议版本、状态码(2xx 成功,4xx 客户端错误,5xx 服务器错误)和描述。
  • 响应头:包含 Content-Type、Content-Length 及 Set-Cookie 等字段。
  • Set-Cookie:用于在无状态的 HTTP 协议上维持会话状态。

Web 服务器实现

基于上述理论,我们可以使用 C++ 实现一个简易的 Web 服务器。整体框架遵循固定模式:创建监听套接字、绑定 IP 端口、进入监听状态。

架构设计

我们将服务器抽象为 Httpserver 类,底层封装 sock 类管理 Socket 生命周期。采用线程池处理并发连接,避免频繁创建销毁线程的开销。

class sock {
public:
    int socketfd = -1;
    ~sock() { if (socketfd >= 0) ::close(socketfd); }
    void socket();
    void bind(std::string ip, uint16_t port);
    void listen();
    int accept(struct sockaddr_in* client, socklen_t* clientlen);
    // ... 其他方法
private:
    int socketfd;
};
请求解析

TCP 是面向字节流的,读取时需依据 HTTP 格式判断边界。请求头结束标志为连续的两个 CRLF(\r\n\r\n)。对于 POST 请求,需根据 Content-Length 头部读取完整的请求正文。

bool Get_HttpRequest(size_t socketfd, Http_Request& hr) {
    std::string data;
    char buffer[BUFFER_SIZE];
    while (true) {
        ssize_t read_bytes = recv(socketfd, buffer, BUFFER_SIZE - 1, 0);
        if (read_bytes <= 0) return false;
        data.append(buffer, read_bytes);
        if (data.find("\r\n\r\n") != std::string::npos) break;
    }
    // 进一步解析请求行和请求头...
    return hr.Deserialization(data);
}
业务处理

服务器根据请求方法分发任务:

  • GET 请求:优先尝试静态资源映射。根据 URL 拼接服务器根目录路径,读取文件内容并构建 200 OK 响应。若文件不存在,返回 404 页面。
  • POST 请求:触发动态业务逻辑。本例中实现了一个计算器功能,解析请求体中的键值对(a, b, op),执行计算后返回结果 HTML。
void run() {
    Http_Request hr;
    bool get_result = Get_HttpRequest(socketfd, hr);
    if (!get_result) { close(socketfd); return; }

    std::string res;
    if (hr.method == "GET") {
        res = Http_Get_Handler(hr);
    } else if (hr.method == "POST") {
        res = Http_Post_Handler(hr);
    } else {
        close(socketfd); return;
    }

    send(socketfd, res.c_str(), res.size(), 0);
    close(socketfd);
}
主函数入口

程序启动时检查命令行参数获取端口号,初始化并启动服务器。

int main(int argc, char* argv[]) {
    if (argc != 2) { /* usage */ exit(-1); }
    uint16_t port = std::stoi(argv[1]);
    Httpserver hs(_default, port);
    hs.init();
    hs.start();
    return 0;
}

总结

通过本文,我们深入探讨了 JSON 序列化原理及 HTTP 协议规范,并结合 Socket 编程与线程池技术,从零实现了一个支持计算功能的 Web 服务器。内容涵盖请求报文解析、静态资源处理、动态业务逻辑映射及响应构建,适合希望掌握底层网络通信机制的开发者参考。

目录

  1. 前置知识
  2. JSON 基础与使用
  3. 初始化与操作
  4. 序列化与反序列化
  5. 原理剖析
  6. HTTP 协议详解
  7. URL 与域名
  8. 请求报文
  9. 响应报文
  10. Web 服务器实现
  11. 架构设计
  12. 请求解析
  13. 业务处理
  14. 主函数入口
  15. 总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • GPT-5.5 超高智商模型1元抵1刀ChatGPT中转购买
  • 代充Chatgpt Plus/pro 帐号了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 光伏产品缺陷检测 AI 深度学习算法技术方案
  • Python Selenium 与 Chrome WebDriver 深度配置实战
  • 无人机路径规划核心算法解析与实战应用
  • Windows 下安装 OpenClaw 并接入飞书机器人指南
  • C++ 性能优化:提升代码执行效率的核心技巧
  • 插入排序原理及 Java 实现详解
  • ToClaw 桌面 AI 助手:自动化任务与远程操作实战指南
  • 多平台热点内容自动化总结工作流实战
  • 9 款降低 AIGC 检测率的论文辅助工具推荐
  • AI 辅助前端开发:掌握三大设计技能独立完成产品全流程
  • 操作系统智能助手 OS Copilot 新功能测评
  • whisper.cpp ggml-large-v3.bin 模型参数文件下载
  • 在 OpenClaw 中安装百度网页搜索技能
  • PostgreSQL 18 Docker 环境搭建与部署实战
  • FPGA 商用级 ISP:动态坏点校正(DPCC)的滑窗架构与并行判决实现
  • Java 面试题及答案汇总(基础、容器、多线程等)
  • Windows 下配置 Claude Code 依赖 Git Bash 环境
  • QtConcurrent 与 QFutureWatcher 实现高效异步计算
  • 深度可分离卷积基础原理与架构解析
  • 鸿蒙电商购物车实战:用户管理、商品列表与购物车功能实现

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online