C++ 手写 HTTP 服务器:从请求解析到响应构建
TCP 是面向字节流的通信方式,本身不具备消息边界。要实现完整的网络通信,必须设计应用层协议来界定数据范围。虽然我们可以自定义协议,但为了效率与兼容性,直接使用成熟的现成协议更为明智,HTTP(超文本传输协议)就是其中之一。
常见应用层协议概览
| 协议名称 | 默认端口 | 说明 |
|---|---|---|
| HTTP | 80 | 网页访问(明文) |
| HTTPS | 443 | 加密网页 |
| FTP | 21/20 | 文件传输 |
| DNS | 53 | 域名解析 |
| SSH | 22 | 安全远程登录 |
URL 与域名解析
当我们通过浏览器输入 https://www.baidu.com/ 时,本质上并不是直接访问这个字符串,而是需要先将域名解析为对应的 IP 地址。
具体流程如下:
- 客户端发起请求:向本地 DNS 服务器发送解析请求。
- 层级查询:若本地无缓存,依次向根域名、顶级域名、权威域名服务器查询。
- 返回结果:最终获取 IP 地址并返回给客户端。
拿到 IP 后,客户端通过 IP 地址 + 端口号 建立连接。使用 HTTPS 协议时,默认端口为 443,浏览器会自动补全,因此地址栏中不显示端口号。IP 负责定位主机,端口负责定位服务,二者缺一不可。
HTTP 协议结构
HTTP 通信本质是在 TCP 之上,按照固定格式传输的'结构化字符串'。一次完整的交互包含请求报文和响应报文。
请求报文结构
- 请求行:包含请求方法(GET/POST)、资源路径及 HTTP 版本。
- 请求报头:多行 key:value 形式,携带额外信息(如 Host、Content-Type),以
\r\n分隔。 - 空行:标识报头结束。
- 请求正文:可选,POST 请求通常在此携带表单或 JSON 数据。
响应报文结构
- 状态行:包含 HTTP 版本、状态码(如 200 OK)及描述。
- 响应报头:说明返回数据的类型、长度等元数据。
- 空行:分隔元数据与内容。
- 响应正文:客户端真正关心的部分,如 HTML 页面或 JSON 数据。
实现一个简易 HTTP 服务器
我们的目标是启动一个服务器,在浏览器输入 http://ip:port/ 即可访问自定义网页。
核心流程
HTTP 服务器底层仍是 TCP 服务器,关键在于增加了一层协议解析逻辑:


