tinyhttpd—4—cat,serve_file

    这一篇当中的两个函数也都是代码量很小,功能很简单的函数。

void cat(int client, FILE *resource)
{
	char buf[1024];

	fgets(buf, sizeof(buf), resource);
	while (!feof(resource))
	{
		send(client, buf, strlen(buf), 0);
		fgets(buf, sizeof(buf), resource);
	}
}

    这个函数的功能乍一看函数名好像是查看某个文件,其实不然,这个函数的功能是将服务器上的某个文件发送给客户端。首先将文件的内容读取到缓存中,然后将数据发送给客户端,不不停的循环直到文件的内容已经发送完毕。

void serve_file(int client, const char *filename)
{
	FILE *resource = NULL;
	int numchars = 1;
	char buf[1024];

	buf[0] = 'A'; buf[1] = '\0';
	while ((numchars > 0) && strcmp("\n", buf))  /* read & discard headers */
		numchars = get_line(client, buf, sizeof(buf));

	resource = fopen(filename, "r");
	if (resource == NULL)
		not_found(client);
	else
	{
		headers(client, filename);
		cat(client, resource);
	}
	fclose(resource);
}

    这个函数的功能就是给客户端发送一个常规文件,什么事常规文件呢,就是非CGI的,CGI到现在我也不知道是什么,等后面分析相关的函数我再去查阅资料补充到这个系列。抛开这里不说,往下看。当开始看到这个函数的时候纠结了一下午,没明白中间那一段初始化buf和循环的作用,首先说为什么需要这个循环,因为当调用这个函数的时候服务端已经从请求报文中读取除了状态行,剩下的还读,此时剩下的那些报文已经不需要了,所以我们读取出来直接扔掉就行。在补充下一下,这里其实还用到了get_line的一个特性,那就是当我们读取不到内容的时候我们让它返回一个字符串,这个字符串只包含了换行和'\0',所以我while的其中一个终止条件时判断是否等于'\n'。其次那么为什么buf要初始化成这样呢,因为有可能不初始化的buf里面可能就是一个换行符和'\0',所以为了避免这种特殊的情况,我们初始化一下,可以随便初始化,只要你避免开那个while的终止条件就行。

    剩下的功能就好说了,如果请求的资源不存在,我们给他一个报文告诉客户端,如果存在,我们给客户端返回一个包含资源的响应报文,这个响应报文由头部和报文主体组成,读到这里,终于意识到headers函数不仅仅是当客户端发送HEADERS请求的时候可以用,构造一个响应报文的时候也会经常用到,作者真的是考虑到代码的复用性了啊。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值