C++ 实现基于 JSON 与 HTTP 协议的 Web 服务器
引言
在之前的网络编程学习中,我们深入探讨了序列化与反序列化的概念。对于 TCP 通信双方而言,由于 TCP 是面向字节流的,直接发送结构体内存往往会导致字节序和内存对齐问题。因此,我们需要借助序列化将结构化数据转换为连续的字节流。
文本序列化(如 JSON)直观、可读性高,便于调试;而二进制序列化(如 Protobuf)体积更小但难以阅读。在实际开发中,成熟的第三方库能极大简化工作。本文将首先讲解 JSON 的基本使用与原理,随后结合 HTTP 协议,用 C++ 从零实现一个支持计算功能的 Web 服务器。
JSON 基础与原理
JSON(JavaScript Object Notation)是一种轻量级的文本数据交换格式。它源于 JavaScript,但已被多种语言广泛支持。JSON 本质上是一个符合特定规范的字符串,支持对象、数组、字符串、数字、布尔值和空值等类型。
基本数据类型
| JSON 类型 | C++ 对应类型 | 描述 |
|---|---|---|
| Number | int, double | 不区分整数和浮点数 |
| Boolean | bool | true / false |
| String | std::string | 双引号包围,支持转义 |
| Null | nullptr | 表示空值 |
对象与数组
对象用大括号 {} 包裹键值对,数组使用中括号 [] 包裹元素。例如:
{"age":20,"sex":"girl"}
[100,"bob",{"id":1234}]
虽然理论上可以手动拼接字符串,但处理嵌套结构和转义字符较为繁琐。引入第三方库(如 nlohmann/json)或自行封装类可以更方便地操作数据结构。
核心实现思路
以自定义的 json 类为例,其内部通常维护一个类型标签和一个联合体(union)来存储实际数据。联合体允许同一块内存根据类型存储不同内容(如整数直接存值,复杂类型存指针),从而节省空间。
构造函数会根据初始化列表的类型决定创建对象还是数组。访问器重载了 operator[],支持通过字符串键访问对象或通过索引访问数组。若访问不存在的数据,会自动创建相应类型的默认对象。
HTTP 协议详解
HTTP 是基于 TCP 的应用层协议,定义了客户端与服务端交互的规则。理解 HTTP 报文结构是实现 Web 服务器的关键。
URL 与域名解析
URL(统一资源定位符)包含协议、域名、端口、路径等信息。浏览器输入网址后,需先进行域名解析(DNS),将域名转换为 IP 地址才能建立连接。这个过程涉及本地缓存、Hosts 文件以及 DNS 服务器的迭代查询。


