分享个简易 HTTP 服务器

2021-01-05 11:36:24 +08:00
 perapera

大家好,最近小弟在学习 Socket,受到 CapriccioC10k 启发,又刚好遇到 Zaver 作者写的这篇博文,就想着看看能不能仿照 Zaver 然后改用协程(?)为我自己的单核服务器写一个单线程的 HTTP 服务器程序来练练手,从汇编实现到直接用库都试了一下,后来发现如果限制在一个线程的话,协程的意义也不大,于是就直接放弃了使用协程的想法,只是把书上(主要是 Linux/UNIX 系统编程手册)推荐的一些调度方法实现了一下,希望能通过尽量减少 blocking 操作来达到差不多的效果,然后就有了这个非常基础、简单的服务器,cherry

其实如果说 HTTP 服务器实现的话,GitHub 上真是多如牛毛,cherry 也没什么太多值得分享的地方,按理说就该放在一边吃灰的,但我转念一想,正是因为 cherry 没有什么太高深的地方,是一个仅仅以书本知识为基础写出来的,刚刚好能运行的 HTTP 服务器,某些层面上来说,如果有谁也恰好在看 CS:APP,编程手册,UNIX 网络编程之类的书的话,cherry 如今正好就像是一个课后作业,于是就抱着「可能有人想看一下我的作业」的心态就在这里分享出来了,哈哈。日后的话,我可能更多地会把这个项目当成一个模板,所以也不会在 cherry 里添加太复杂的内容,只在原有的基础上实现一些比较容易的想法,比如换一下数据结构,支持一下配置文档或者 kqueue 之类,如果有兴趣(<del>找 bug</del>)的话可以移步 README ~

GitHub 地址: https://github.com/ahhzee/cherry

(以上是 ApacheBench 的分析结果)

3013 次点击
所在节点    程序员
6 条回复
vus520
2021-01-05 12:20:57 +08:00
已点
iplayio2019
2021-01-05 15:53:51 +08:00
用 PHP 也可以写一个 HTTP 服务器。
oxromantic
2021-01-05 16:58:15 +08:00
简单看了下代码,说下自己的看法吧

https://github.com/ahhzee/cherry/blob/master/src/http.c

1. request io 读出错就调用 exit,看起来只要有个请求数据不正常就会触发闪退,不知道我理解是否正确
2. http 协议还是优先实现 1.0 的好,毕竟简单
3. mime 有很多现有的映射规则,建议做成外部配置
4. 粗看现在的模型是如果一个网速极慢或者为 0 的客户端下载文件,那么在他下载完成之前,其他客户端都不会得到 cpu 时间,不知是否如此
perapera
2021-01-05 19:53:51 +08:00
@oxromantic

1: 谢谢指点!确实,请求处理部分真的十分粗陋,目前能处理的错误只有 EAGAIN,我自己也试过一两次因为读取错误而整个程序直接退出,加上我这一部分没用 perror,导致我连错误是什么都不知道,不过笼统改为无视这些错误意义好像也不大,改天应该会将这一部分代码重写一遍。

2 、3: 好建议,我会试一下

4: 个人理解不会,现在处理请求的流程主要是逐一从队列里拉取已有的连接描述符,再逐一读取该连接已有的请求并发送相应文件(这些地方倒是可能造成阻塞),并且 socket 全部都设为非阻塞,就 IO 方面好像没有哪个函数会受制于对方接收速度,但确实有漏发的可能,因为现在对于写操作 EAGAIN 的解决方法只是单纯无视而已 =_= 说到头来还是请求处理的问题……
cz5424
2021-01-06 06:57:54 +08:00
楼主代码里面的 jpeg 打错了
perapera
2021-01-06 09:24:32 +08:00
@cz5424 谢谢指正!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/741788

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX