码迷,mamicode.com
首页 > Web开发 > 详细

Tinyhttpd阅读笔记

时间:2016-05-07 22:19:01      阅读:399      评论:0      收藏:0      [点我收藏+]

标签:

1、简介

tinyhttpd是一个开源的超轻量型Http Server,阅读其源码,可以对http协议,微型服务器有进一步的了解。

源码链接

参考博客:tinyhttpd源码分析

2、笔记

------------------------------------------------------2016年5月7日21:31:35----------------------------------------------------

函数原型目录,列举出整个项目所要用到的所有函数原型

 1 void accept_request(void *);
 2 void bad_request(int);
 3 void cat(int, FILE *);
 4 void cannot_execute(int);
 5 void error_die(const char *);
 6 void execute_cgi(int, const char *, const char *, const char *);
 7 int get_line(int, char *, int);
 8 void headers(int, const char *);
 9 void not_found(int);
10 void serve_file(int, const char *);
11 int startup(u_short *);
12 void unimplemented(int);

每个函数的作用在项目的readme文件中有简单的描述:

函数 描述
accept_request 处理从套接字上监听到的一个 HTTP 请求,在这里可以很大一部分地体现服务器处理请求流程
bad_request 返回给客户端这是个错误请求,HTTP 状态吗 400 BAD REQUEST
cat 读取服务器上某个文件写到 socket 套接字
cannot_execute 主要处理发生在执行 cgi 程序时出现的错误
error_die 把错误信息写到 perror 并退出
execute_cgi 运行 cgi 程序的处理,也是个主要函数
get_line 读取套接字的一行,把回车换行等情况都统一为换行符结束
headers 把 HTTP 响应的头部写到套接字
not_found 主要处理找不到请求的文件时的情况
sever_file 调用 cat 把服务器文件返回给浏览器
startup 初始化 httpd 服务,包括建立套接字,绑定端口,进行监听等
unimplemented 返回给浏览器表明收到的 HTTP 请求所用的 method 不被支持

建议的源码阅读顺序:

main--->startup--->accept_request--->execute_cgi

按照这个顺序理清整个服务器工作流程。

 

main函数

 1 int main(void)
 2 {
 3     int server_sock = -1;
 4     u_short port = 4000;
 5     int client_sock = -1;
 6     struct sockaddr_in client_name;
 7     socklen_t  client_name_len = sizeof(client_name);
 8     pthread_t newthread;
 9 
10     server_sock = startup(&port);
11     printf("httpd running on port %d\n", port);
12 
13     while (1)
14     {
15         client_sock = accept(server_sock,
16                 (struct sockaddr *)&client_name,
17                 &client_name_len);
18         if (client_sock == -1)
19             error_die("accept");
20         /* accept_request(client_sock); */
21         if (pthread_create(&newthread , NULL, (void *)accept_request, (void *)&client_sock) != 0)
22             perror("pthread_create");
23     }
24 
25     close(server_sock);
26 
27     return(0);
28 }

第3-7行是socket相关变量定义,有关socket的详细介绍可以上网查阅相关资料或者查看书籍《Unix网络编程》;

第10行调用startup函数,有关该函数的内容后续简要解释;

第13-23行,监听客户端向服务端发来的请求连接,当接收一个连接之后,创建一个线程执行相应的请求,线程入口函数是accept_request,另外有关Linux中pthread_create的使用需要注意一些细节问题。

第25行关闭服务端的套接字。

 

startup函数

 函数参数是一个端口号,用于创建对应端口号的tcp套接字

 1 int startup(u_short *port)
 2 {
 3     int httpd = 0;
 4     struct sockaddr_in name;
 5 
 6     httpd = socket(PF_INET, SOCK_STREAM, 0);
 7     if (httpd == -1)
 8         error_die("socket");
 9     memset(&name, 0, sizeof(name));
10     name.sin_family = AF_INET;
11     name.sin_port = htons(*port);
12     name.sin_addr.s_addr = htonl(INADDR_ANY);
13     if (bind(httpd, (struct sockaddr *)&name, sizeof(name)) < 0)
14         error_die("bind");
15     if (*port == 0)  /* if dynamically allocating a port */
16     {
17         socklen_t namelen = sizeof(name);
18         if (getsockname(httpd, (struct sockaddr *)&name, &namelen) == -1)
19             error_die("getsockname");
20         *port = ntohs(name.sin_port);
21     }
22     if (listen(httpd, 5) < 0)
23         error_die("listen");
24     return(httpd);
25 }

第6行创建一个socket套接字,由于其参数是SOCK_STREAM,因此创建的是tcp套接字;

第7-8行,如果套接字创建不成功,则调用封装好的错误处理函数error_die,该函数比较简单,就是打印错误信息并结束整个程序。

第13-23则是创建socket服务端的基本流程,先是bind操作,接下来listen操作;

Tinyhttpd阅读笔记

标签:

原文地址:http://www.cnblogs.com/LCCRNblog/p/5469266.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!