喊了几天学习Web开发,为了毕业论文,今晚上计划也是看看CSS呢,但是实在是没忍住,读了下经典的tinyhttp的源代码,这款代码还是颇有名气的,网上这么评论的:
tinyhttpd是一个超轻量型Http Server,使用C语言开发,全部代码只有500、600行,附带一个简单的Client,可以通过阅读这段代码理解一个Http Server的本质。
其实,代码颇简单,适合刚学习Web Server的童鞋学习,因为我之前写过CGI Server,所以,我还是认为此代码写的一般,并且我在Ubuntu下编译遇到了不少错误,我都懒得写详细分析了,所以随便写下吧,后面的Github地址里有详细的分析。
源码下载地址:http://sourceforge.net/projects/tinyhttpd/
make编译后会有不少错误和警告,我这里说下怎么改正错误:
Makefile文件里的:gcc -W -Wall -lsocket -lpthread -o httpd httpd.c ,修改为:
gcc -W -Wall -o httpd httpd.c -lpthread481行的 int client_name_len 改为 socklen_t client_name_len
436行 改动与上面相似,改为socklen_t类型即可。
34行改为void *accept_request(void *); 所以下面的实现也要修改下:
1 | void *accept_request(void* client1) |
之后再make,程序就OK了。
简单说下程序的逻辑吧:
一个无限循环,一个请求,创建一个线程,之后线程处理函数处理每个请求,然后解析HTTP请求,然后做一些判断处理,之后判断文件是否可执行,不可执行,打开文件,输出给客户端(浏览器)呗,可执行就创建管道,父子进程通信。
整个流程就这么简单,程序主要处理2种HTTP请求方式:GET和POST,懒得说了,上传两张图片,自己分析吧,图片原始出处不清楚,电脑里存了好久了,。
GET:
POST:
其实这个源码里有一个地方比较难懂,就是那个解析HTTP每一行的那个get_line函数里的recv的MSG_PEEK参数,详细解释可以参考此链接。
1 | // 读取socket,判断换行,CRLF标志,之后以"\n"换行,并在字符串后添加'\0' |
这代码,没啥写头,很多功能都没实现,请求只实现了GET和POST,Header里只用了第一行,CGI里全局变量只定义了几个,并且我验证程序,发现CGI功能好像是有些问题的,但是因为我CGI水平比较水,懒得检测原因了,总体来说,程序比我之前的那个CGI Server要简单些,功能要稍微弱些吧。
下面放出我Github里的详细中文注释,欢迎指正,谢谢: