源码分析之tinyhttpd(一)
2015-03-16 19:56
260 查看
tinyhttpd是一个十分简单的http多线程服务器,通过详细分析500行左右的代码,对http请求和响应有一个简单的理解。
http://sourceforge.net/projects/tinyhttpd/
首先,从main函数开始:
3-8行:变量初始化工作
10行:startup函数,
传入参数:*port,由于main函数中port为0,未指定绑定端口号,需要系统分配。
4行:struct socketaddr_in,是一个表示使用地址族、端口和网络地址的结构体。
6行:初始化服务器socket。使用Internet协议族,protocol family Internet;SOCK_STREAM对应TCP协议,SOCK_DGRAM对应UDP协议,SOCK_RAW是面向底层协议的。
11行:htons(),将主机字节顺序转换为网络字节顺序。h,host;n,network;s,short(2Bytes);l:long(4Bytes)。另外还有htonl(),ntohs(),ntohl()函数。
12行:INADDR_ANY:0.0.0.0,表示所有地址,绑定监听本机的所有IP地址。
13行:进行绑定,httpd与name对应的地址端口绑定。
15-21行:由于*port=0,系统会自动分配一个端口,使用getsockname获取。注意:必须在bind成功后才能获取。
22行:开始监听,后一个参数5表示决定了未完成队列和已完成队列中连接数目之和的最大值。
http://sourceforge.net/projects/tinyhttpd/
首先,从main函数开始:
<pre name="code" class="cpp">int main(void) { int server_sock = -1; u_short port = 0; int client_sock = -1; struct sockaddr_in client_name; int client_name_len = sizeof(client_name); pthread_t newthread; server_sock = startup(&port); printf("httpd running on port %d\n", port); while (1) { client_sock = accept(server_sock, (struct sockaddr *)&client_name, &client_name_len); if (client_sock == -1) error_die("accept"); /* accept_request(client_sock); */ if (pthread_create(&newthread , NULL, accept_request, client_sock) != 0) perror("pthread_create"); } close(server_sock); return(0); }
3-8行:变量初始化工作
10行:startup函数,
int startup(u_short *port) { int httpd = 0; struct sockaddr_in name; httpd = socket(PF_INET, SOCK_STREAM, 0); if (httpd == -1) error_die("socket"); memset(&name, 0, sizeof(name)); name.sin_family = AF_INET; name.sin_port = htons(*port); name.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(httpd, (struct sockaddr *)&name, sizeof(name)) < 0) error_die("bind"); if (*port == 0) /* if dynamically allocating a port */ { int namelen = sizeof(name); if (getsockname(httpd, (struct sockaddr *)&name, &namelen) == -1) error_die("getsockname"); *port = ntohs(name.sin_port); } if (listen(httpd, 5) < 0) error_die("listen"); return(httpd); }
传入参数:*port,由于main函数中port为0,未指定绑定端口号,需要系统分配。
4行:struct socketaddr_in,是一个表示使用地址族、端口和网络地址的结构体。
struct sockaddr_in { short sin_family;/*Addressfamily一般来说AF_INET(地址族)PF_INET(协议族)*/ unsigned short sin_port;/*Portnumber(必须要采用网络数据格式,普通数字可以用htons()函数转换成网络数据格式的数字)*/ struct in_addr sin_addr;/*Internetaddress*/ unsigned char sin_zero[8];/*Samesizeasstructsockaddr没有实际意义,只是为了 跟SOCKADDR结构在内存中对齐*/ };
6行:初始化服务器socket。使用Internet协议族,protocol family Internet;SOCK_STREAM对应TCP协议,SOCK_DGRAM对应UDP协议,SOCK_RAW是面向底层协议的。
11行:htons(),将主机字节顺序转换为网络字节顺序。h,host;n,network;s,short(2Bytes);l:long(4Bytes)。另外还有htonl(),ntohs(),ntohl()函数。
12行:INADDR_ANY:0.0.0.0,表示所有地址,绑定监听本机的所有IP地址。
13行:进行绑定,httpd与name对应的地址端口绑定。
15-21行:由于*port=0,系统会自动分配一个端口,使用getsockname获取。注意:必须在bind成功后才能获取。
22行:开始监听,后一个参数5表示决定了未完成队列和已完成队列中连接数目之和的最大值。
相关文章推荐
- HTTP服务器的本质:tinyhttpd源码分析及拓展
- tinyhttpd源码分析
- tinyhttpd源码分析
- 源码分析之tinyhttpd-0.1
- TinyHTTPd源码分析
- TinyHTTPd--超轻量型Http Server源码分析
- 【源码剖析】tinyhttpd —— C 语言实现最简单的 HTTP 服务器
- tinyhttpd源码学习1
- tinyhttp源码分析
- http服务器雏形tinyhttpd源码
- Tinyxml解析过程源码分析
- mini-httpd源码分析-tdate_parse.h
- C++卷积神经网络实例:tiny_cnn代码详解(11)——层结构容器layers类源码分析
- mini_httpd源码分析
- Tinyhttpd源码剖析(二)
- Tinyhttpd源码解析
- mini-httpd源码分析-mini-httpd.c之外总结
- tinyhttpd源码学习1
- mini-httpd源码分析-match.h
- lighttpd高性能Web服务器源码分析?坑爹啊,原来是light httpd!-0 -