C++ WebServer / 01
项目总览:我为什么要写一个 C++ WebServer
为了系统学习 Linux 网络编程、I/O 多路复用、多线程并发和 HTTP 协议,我从零实现了一个 C++ WebServer。这个板块记录它从阻塞式 echo server 演进到 epoll + 线程池 HTTP 静态服务器的过程。
这一阶段要解决什么问题
入口篇要回答的不是“有哪些类和函数”,而是为什么要写这个项目。我的目标不是返回一个 Hello World,而是沿着真实后端服务器的核心链路,把 socket 监听、epoll 事件分发、非阻塞 I/O、用户态缓冲区、线程池、HTTP 解析、静态文件服务、日志、配置和压测串起来。
原来的实现有什么缺陷
如果只停留在简单 echo server,项目只能证明我知道 socket API 的调用顺序,但不能体现高并发服务器真正困难的地方:多个连接如何复用一个事件循环、半包和粘包如何处理、写不完时如何等待 EPOLLOUT、长连接如何复用、空闲连接如何清理。
我是怎么改的
从服务器提交记录看,项目演进非常清楚:v1.0 是单线程阻塞 echo server,v2.0 引入单线程 epoll,v3.0 加入 epoll + ThreadPool,v3.2 抽出 Connection 和用户态缓冲区,v3.4 切换到 ET,v4.0 实现 HTTP 请求解析和默认首页,v4.1 加入 O(1) TimerWheel,v5.0 到 v5.2 完善日志和异步日志,v5.5 加入命令行配置和优雅退出。
核心代码 / 关键逻辑
Client
↓
Listen Socket
↓
epoll event loop
↓
Connection Pool
↓
ThreadPool
↓
HTTP Parser
↓
Static File Response当前支持 epoll、非阻塞 I/O、ET 模式、EPOLLONESHOT、线程池、Connection 读写缓冲区、HTTP 请求解析、Keep-Alive、静态文件服务、日志模块、配置解析和 ApacheBench 压测。
踩坑记录
这个项目最容易踩的坑是“看起来能跑”和“状态正确”不是一回事。比如 ET 模式下一次 read 不读空会卡住,非阻塞 write 一次写不完必须保存进度,Keep-Alive 不能直接 close,线程池处理完成后还要回到主 Reactor 统一操作 fd。