源码分析之tinyhttpd(一)

tinyhttpd是一个十分简单的http多线程服务器,通过详细分析500行左右的代码,对http请求和响应有一个简单的理解。

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表示决定了未完成队列和已完成队列中连接数目之和的最大值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值