一个简单的 Web 服务器 [未完成]
最近学习C++,linux和网络编程,想做个小(mini)项目. 就去搜索引擎, 开源中国, Sourceforge上找http server的项目.
好吧,也去了知乎. 知乎上程序员氛围好, 有不少经验可以借鉴.
终极目标:自己实现(implement)一个WEB SERVER.
感想: 算法和数据结构还是很重要的...(一切的基础啊...悔不当初为什么不好好学,去acm也好...)
指导:Build a simple HTTP server in C (有不会的就问stackoverflow, 所以说如果有一天这网站挂了,网站管理员都不会修了,因为没有可以问啊)
资料:
0.RFC1945:Hypertext Transfer Protocol -- HTTP/1.0 (http协议版本1.0)
1.RFC2616: rfc2616 Hypertext Transfer Protocol -- HTTP/1.1 (讲HTTP协议,版本1.1,114页大小)
2.A Practical Guide to Writing Clients and Servers (15页打印纸的内容,略长略长,慢慢看)
比RFC容易看,快速过一遍.
3.RFC2396:
4.RFC2732:
5.RFC822: Standard for ARPA Internet Text Messages
6.RFC1521:MIME part I
前导知识 prerequisites:
0.网络知识 (看TCP/IP Illustrated)
1.网络编程 (可以看UNP, Unix Network Programming)
(或者更好入门的Beej's Guide to Network Programming)
2.系统API (看APUE, Advanced Programming in the UNIX Environment Third Edition)
(书厚不是问题,反正以后都要看,早点看得了)
找到几个轻量级的小项目:
1.nweb Tiny Webserver (谷歌搜出来的, 200行,静态网页,C,安全检查)
比较简单,如果有点网络编程的基础的话,就是刚学完网络编程就能写出来的程度.
用fork(),不用select(). 看完后可以用select做一次. 代码中用了signal(),inet_addr()这些不推荐的函数. 可以自己替代为sigaction()和inet_aton()
如何写一个daemon :Linux Daemon Writing HOWTO
我犯过的错误:
1. if(a=b)
2.accept()调用时没有初始化socklen_t addrlen = sizeof client_addr;
3.发送图片时没有写头部 Content-Type: image/jpg
4. 使用sprintf时没有使格式和参数一一对应,导致未定义的结果.
5. 调用select()时没有注意nfds要加1
6.如果要用ipv6,似乎不能用sa->ai_family = AF_UNSPEC;而只能用AF_INET6;不然问题提示"Connection refused"
7.getaddrinfo()返回0是成功. 非0为失败(而还是-1!!!!!!)
2.Tiny HTTPd (stackoverflow上有人推荐,500 行,C,支持CGI)
(CSDN上有人解析源码: 【源码剖析】tinyhttpd —— C 语言实现最简单的 HTTP 服务器 )
3.mongoose (知乎上一个问题下说到了)
4.lighthttpd (轻量级,高性能网站,安全、快速、兼容性好并且灵活的web server环境)
(ChinaUNIX 的 lighttpd-1.4.20源码分析 )
5.Zaver如何写一个Web服务器 github: (知乎上看到的, 高性能, http/1.1, 基本架构 : 非阻塞, event loop, 线程池)
6.Nginx (生产环境. 不知道为什么我会把这个放在这里,装饰下页面......应该不会去看的)
测试:
1. 压力测试
http_load
webbench
ab
还有一个问题,阅读别人的代码:
1.书:Code Reading
Further Study:
the c10k problem (10,000 connection)