阅读源码:tinyhttpd

    最近学习C++服务器开发,看了一些书,但是效果并不是很可观,看过的东西大多很快就忘掉了,多线程、多进程、并发编程等等的概念搞的云里雾里,迷茫了一阵子后,得到启发,先着手于一边翻书一边阅读源码,然后再根据这些源码“造轮子”,书法里的临摹讲的也是这个道理。看过别的学习路线,笔者从tinyhttpd入手,在借助《apue》和《unix网络编程》两本书的帮助下,理解这短短的500行代码,并且做了详细的注释。注释过的源码笔者放在了github上,同为初学者的话可以一起探讨。
下面只简单的写了写工作流程。
    tinyhttpd注释版源码:https://github.com/Avin0323/tinyhttpd-Annotations
    工作流程:

  1. 启动服务器,可以指定端口号或者动态申请一个端口号,然后在该端口号绑定httpd服务并监听;
  2. accept返回一个http的请求时,创建一个线程运行 accept_request 函数。
  3. 分析http请求中的 方法method和 url。对于GET方法,如果有参数,则query_string 指针指向 url 中?后面的 GET 参数。
  4. 格式化url到path数组,表示浏览器请求的服务器文件路径,在tinyhttpd中服务器文件是在 htdocs文件夹下。当 url 以 / 结尾,或 url 是个目录,则默认在 path 中加上 index.html,表示访问主页。
  5. 如果文件路径合法,对于无参数的GET请求,直接输出服务器文件到浏览器,即用 HTTP格式写到套接字上,跳到10。其他情况则调用 excute_cgi 函数执行 cgi 脚本。
  6. 读取整个HTTP请求并丢弃,如果是 POST 则找出Content-Length。把 HTTP 200状态码写到套接字。
  7. 建立两个管道:cgi_input 和 cgi_output, 并 fork 一个进程。
  8. 在子进程中,把 STDOUT 重定向到 cgi_outputt 的写入端,把 STDIN 重定向到 cgi_input 的读取端,关闭 cgi_input 的写入端 和 cgi_output 的读取端,设置 request_method 的环境变量,GET 的话设置 query_string 的环境变量,POST 的话设置 content_length 的环境变量,这些环境变量都是为了给 cgi 脚本调用,接着用 execl 运行 cgi 程序。
  9. 在父进程中,关闭 cgi_input 的读取端 和 cgi_output 的写入端,如果 POST 的话,把 POST 数据写入 cgi_input,已被重定向到 STDIN,读取 cgi_output 的管道输出到客户端,该管道输入是 STDOUT。接着关闭所有管道,等待子进程结束。
  10. 关闭与浏览器的连接,完成了一次 HTTP 请求与回应,因为 HTTP 是无连接的。

你可能感兴趣的:(tinyhttpd)