首页/新闻资讯/正文详情

从零复刻 TinyWebServer —— 环境准备与最小 TCP 服务端

发布时间:2026/9/27 6:18:29 来源:云帆数科 栏目:资讯中心
从零复刻 TinyWebServer —— 环境准备与最小 TCP 服务端
第 1 篇从零复刻 TinyWebServer —— 环境准备与最小 TCP 服务端原项目qinguoyi/TinyWebServer复刻仓库L2501031968/ccTinyWebServer完整 20 章教程仓库内docs/TinyWebServer-Recreation.md为什么写这个系列TinyWebServer 是一个很好的 Linux C 网络编程学习项目。它用相对精简的代码覆盖了 Web 服务器的主要模块线程池 epoll 事件循环 HTTP 状态机 定时器 日志系统 数据库连接池 Reactor / Proactor但直接读原项目源码对初学者有几个门槛模块多一开始不知道从哪里读起。代码之间耦合紧改一处可能编译不过。看懂某个模块不等于能自己写出来。所以这个系列不打算“讲一遍源码”而是从零复刻参考原项目在自己的目录里一步一步重新实现每一章完成一个能独立编译、运行和验证的小目标再进入下一章。原项目qinguoyi/TinyWebServer复刻仓库L2501031968/ccTinyWebServer本系列的目标不是逐行复制原项目而是理解每个模块解决什么问题 自己动手写出可运行的版本 用 curl、浏览器、Webbench 验证结果 记录编译错误、调试过程和理解复刻仓库里同时保留完整 20 章 Markdown 教程 每章对应的源码 Keil / Makefile 工程 测试脚本和压测结果如果你只想看完整版可以直接访问仓库的docs/TinyWebServer-Recreation.md。博客上的 6 篇是精华版覆盖最关键的几个模块。每章做什么系列的大致顺序是第 1 章 同步原语信号量、互斥锁、条件变量 第 2 章 最小 TCP 服务端socket、bind、listen、accept 第 3 章 非阻塞套接字与 epoll 事件循环 第 4 章 HTTP 请求解析状态机 第 5 章 静态文件服务 第 6 章 完整静态文件响应mmap writev 第 7 章 线程池与任务队列 第 8 章 定时器与连接超时 第 9 章 日志系统 第 10 章 LT 与 ET 触发模式 第 11 章 Reactor 与模拟 Proactor 第 12 章 MySQL 连接池 第 13 章 POST 表单解析与用户注册登录 第 14 章 浏览器界面与端到端测试 第 15 章 Cookie 与 Session扩展 第 16 章 原项目页面跳转与静态资源 第 17 章 原版 CGI 页面跳转与 MIME 类型 第 18 章 HTTP Range 分段传输 第 19 章 原项目 Config 与启动参数 第 20 章 原项目功能验收与 Webbench 压力测试TinyWebServer 从零复刻本笔记记录从零复刻 TinyWebServer 的过程。参考源码位于同工作区下的TinyWebServer复刻代码位于ccTinyWebServer。每个章节完成一个可以独立编译、运行和验证的小目标再进入下一章节。第 0 章 环境准备与项目启动项目/home/cc/TinyWebServer目的记录从跑通项目到理解核心模块的过程。创建时间2026-09-17当前阶段环境准备和启动流程整理0.1 学习目标先把 TinyWebServer 编译、启动、访问跑通。理解项目的目录结构。理解线程池、epoll、HTTP 状态机、定时器、日志、数据库连接池这些核心模块。在学习过程中持续完善这份博客文档。0.2 当前环境操作系统Ubuntu 25.10编译器g数据库MySQL 8.4.10项目路径/home/cc/TinyWebServer家目录/home/cc0.3 项目启动步骤0.3.1 安装依赖sudo apt update sudo apt install -y build-essential libmysqlclient-dev mysql-server0.3.2 启动 MySQLsudo systemctl enable --now mysql sudo systemctl status mysql如果systemctl不可用可以使用sudo service mysql start sudo service mysql status看到下面的信息说明 MySQL 已经启动Active: active (running) Status: Server is operational0.3.3 初始化数据库进入 MySQL 管理终端sudo mysql执行以下 SQLCREATE DATABASE IF NOT EXISTS qgydb DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci; CREATE USER IF NOT EXISTS webuserlocalhost IDENTIFIED BY webpass123; ALTER USER webuserlocalhost IDENTIFIED BY webpass123; GRANT ALL PRIVILEGES ON qgydb.* TO webuserlocalhost; FLUSH PRIVILEGES; USE qgydb; CREATE TABLE IF NOT EXISTS user( username varchar(50), passwd varchar(50) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; INSERT INTO user(username, passwd) VALUES(name, passwd); SELECT * FROM user; EXIT;当前配置数据库名qgydb 数据库用户webuser 数据库密码webpass123 测试用户name / passwd0.3.4 修改项目配置编辑main.cpp确认第 6 到第 8 行是string user webuser; string passwd webpass123; string databasename qgydb;0.3.5 编译项目cd /home/cc/TinyWebServer make server也可以使用项目自带脚本cd /home/cc/TinyWebServer sh ./build.sh编译成功后当前目录会出现server可执行文件。0.3.6 启动 Web 服务器cd /home/cc/TinyWebServer ./server -p 9006 -s 4 -t 4参数说明-p 9006 Web 服务端口 -s 4 数据库连接池中的连接数量 -t 4 线程池中的线程数量程序会一直停在前台运行。默认日志会写入当前目录下类似下面的文件YYYY_MM_DD_ServerLog0.3.7 浏览器访问打开浏览器访问http://127.0.0.1:9006/或者使用命令行检查curl -i http://127.0.0.1:9006/看到HTTP/1.1 200 OK和judge.html的内容就说明服务器已经跑通。0.4 已完成记录两张站点打开记录[x] 安装编译工具和 MySQL 依赖[x] 启动 MySQL 服务[x] 创建数据库qgydb[x] 创建用户表user[x] 修改main.cpp中的数据库配置[ ] 编译生成server[ ] 启动 Web 服务并访问首页0.5 下一步学习记录下一步可以按模块阅读代码并在每个模块下补充自己的理解lock 线程同步机制封装 threadpool 半同步/半反应堆线程池 http HTTP 请求解析与响应 timer 非活动连接定时器 log 同步/异步日志系统 CGImysql 数据库连接池 webserver 主循环、事件监听和事件处理0.6 学习备注这里可以继续记录编译错误、调试过程和自己的理解。第 1 章 工程骨架与线程同步原语1.1 本章目标本章完成复刻项目的第一个基础模块线程同步机制封装。具体目标如下建立与参考项目一致的目录结构。编写可用于 C11 项目的 Makefile。封装信号量、互斥锁和条件变量。使用多线程测试程序验证三个同步原语。本章暂时不实现 WebServer、HTTP、线程池、定时器、日志和数据库。1.2 为什么先实现同步原语线程池、日志系统和数据库连接池都不是单独存在的模块线程池需要互斥锁保护任务队列。线程池需要信号量通知工作线程。异步日志的阻塞队列需要互斥锁和条件变量。数据库连接池需要互斥锁和信号量管理空闲连接。因此先封装这些同步原语可以避免后续模块重复使用pthread_mutex_t、sem_t和pthread_cond_t的原始接口。参考项目对应实现位于TinyWebServer/lock/locker.h。1.3 建立工程目录进入复刻目录cd /home/cc/ccTinyWebServer创建后续开发需要的目录mkdir -p lock http timer threadpool log CGImysql root tests docs本章会使用其中两个目录ccTinyWebServer/ ├── docs/ │ └── TinyWebServer-Recreation.md ├── lock/ │ └── locker.h ├── tests/ │ └── test_locker.cpp └── makefile其他目录暂时保持为空等后续章节再逐步填充。1.4 编写 Makefile创建makefileCXX ? g CXXFLAGS ? -g -Wall -Wextra -stdc11 all: test_locker test_locker: tests/test_locker.cpp lock/locker.h $(CXX) -o test_locker tests/test_locker.cpp $(CXXFLAGS) -pthread clean: rm -f test_locker server .PHONY: all clean这里有几个关键点CXXFLAGS使用-stdc11因为封装代码使用了nullptr和 delete。-pthread同时负责链接 pthread 库并设置线程相关编译选项。test_locker同时依赖源文件和头文件头文件变化后会重新编译。编译命令前必须使用 Tab不能使用空格。1.5 封装信号量信号量由sem类封装底层接口是sem_init、sem_wait和sem_post。sem::wait()对应 P 操作信号量的值大于 0 时值减 1然后继续执行。信号量的值为 0 时调用线程进入阻塞状态。sem::post()对应 V 操作信号量的值加 1。如果有线程正在等待则唤醒其中一个线程。构造函数允许指定初始值默认值为 0class sem { public: explicit sem(unsigned int value 0) { if (sem_init(m_sem, 0, value) ! 0) throw std::exception(); } ~sem() { sem_destroy(m_sem); } sem(const sem ) delete; sem operator(const sem ) delete; bool wait() { return sem_wait(m_sem) 0; } bool post() { return sem_post(m_sem) 0; } private: sem_t m_sem; };sem_init的第二个参数0表示信号量只在当前进程的线程之间共享。复制构造和复制赋值被删除避免两个对象管理同一个sem_t从而在析构时重复调用sem_destroy。1.6 封装互斥锁互斥锁由locker类封装底层接口是pthread_mutex_init、pthread_mutex_lock和pthread_mutex_unlock。class locker { public: locker() { if (pthread_mutex_init(m_mutex, nullptr) ! 0) throw std::exception(); } ~locker() { pthread_mutex_destroy(m_mutex); } locker(const locker ) delete; locker operator(const locker ) delete; bool lock() { return pthread_mutex_lock

相关推荐

STM32参考方案资源地图:从官方到开源社区的高效检索指南
STM32参考方案资源地图:从官方到开源社区的高效检索指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 6:18:23

1个真实案例一文搞懂生成静态网站报价与防黑逻辑
1个真实案例一文搞懂生成静态网站报价与防黑逻辑

1个真实案例一文搞懂生成静态网站报价与防黑逻辑 网站被黑挂马不知道怎么办?别慌,这行干久了,这种噩梦场景见得太多。很多老板花大价钱做了动态站,结果后台一不留神被拖库,首页瞬间变成色情广告,域名直接被搜索引擎屏蔽,恢复起来费时费力还丢脸。其实… · 2026/9/27 6:18:23

STM32 HAL库DMA+IDLE+状态机实现SBUS协议解析
STM32 HAL库DMA+IDLE+状态机实现SBUS协议解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 6:18:23

创建与管理MySQL表
创建与管理MySQL表

数据库中的表是存储数据的核心部分,管理好表是数据库应用的基础。通过学习创建与管理表,可以更加有效地组织和管理数据。在编程的实际应用中,掌握如何创建、查看、修改和删除表,能够帮助更好地进行数据操作和维护。 本课程将介绍数据库表的基础概念、数据类型的选择与应用… · 2026/9/27 7:32:53

守护 Linux 内核的核心引擎:深入解读 BPF/eBPF 的自动化测试演进与实践
守护 Linux 内核的核心引擎:深入解读 BPF/eBPF 的自动化测试演进与实践

在过去十余年中,BPF(或称 eBPF)已经从最初简单的“伯克利包过滤器(Berkeley Packet Filter)”演变为 Linux 内核中最具革命性的内核技术之一。如今,BPF 触角延伸至网络加速、系统可观测性、安全策略等各个领… · 2026/9/27 7:32:47

τ--η 离散场 · 第一卷
τ--η 离散场 · 第一卷

局域离散精确结构 96 迹 / 10 原子值 / ⟨η⟩350233/762300 / 原始谱隙 1/φ2 / 直径 5 项目 内容 版本 v2.1(吸收卷二修复项) 验证状态 第 I 部分 6/6 精确通过(本环境复跑);谱隙/直径引自卷二 证据等级 定理级&… · 2026/9/27 7:32:47

NixOS 使用 Jottacloud Command-line Tool(jotta-cli / jottad)无头备份客户端配置指南
NixOS 使用 Jottacloud Command-line Tool(jotta-cli / jottad)无头备份客户端配置指南

包管理器操作系统 【免费下载链接】nixpkgs Nix Packages collection & NixOS 项目地址: https://gitcode.com/GitHub_Trending/ni/nixpkgs 点击查看 免费下载 Jottacloud Command-line Tool 是 Jottacloud 官方提供的无头(headless)命令… · 2026/9/27 7:32:47

数据库与MySQL关系型数据库
数据库与MySQL关系型数据库

数据库是现代应用程序的核心之一,无论是大型的企业系统还是小型的应用程序,数据的存储与管理都是至关重要的部分。数据库系统的发展经历了多个阶段,从早期的文件系统到如今的复杂数据库管理系统(DBMS)。其中,关系型数据库管理系统(RDBMS)是使用最为广泛的一种数据库管理… · 2026/9/27 7:32:29

潜伏14年的Linux内核漏洞CVE-2025-39964:一个普通账户如何击穿root防线,还能从Docker容器里“越狱“
潜伏14年的Linux内核漏洞CVE-2025-39964:一个普通账户如何击穿root防线,还能从Docker容器里“越狱“

你敢相信吗?就在你以为服务器固若金汤的时候,一个从2011年就悄悄躺进Linux内核的"老毛病",正等着任何一位本地用户伸手拿到root钥匙。更棘手的是,在那些跑满Docker容器的云主机上,这个编号为CVE-2025-39964的… · 2026/9/27 7:32:23

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码