欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 文化 > TinyHttpd源码精读(二)

TinyHttpd源码精读(二)

2025/5/1 21:11:18 来源:https://blog.csdn.net/weixin_44331218/article/details/139457159  浏览:    关键词:TinyHttpd源码精读(二)

书接上文,我们在TinyHttpd源码精读(一)中简单的讲解了项目的运行和main函数以及accept_request函数的主体内容。基本上这个项目的主线思路就差不多一半了,接下来我们看看这个项目是如何显示静态网页和动态的网页的。

1.静态网页的展示(serve_file):

        在讲解代码之前我们先看看静态网页的内容:

       这个网页就htdocs/index.html文件中的内容,我们可以通过打印log来看文件的path是否正确:

        我们再结合之前的网页显示的错误的信息,我们发现只需要将要显示的网页的内容直接通过socket直接发送到socket段即可显示。所以我们显示静态的界面的思路就比较的清晰了,我们直接看代码:

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);
}

我们可以看到关于显示静态界面的代码就涉及到两个函数:headers(client, filename);cat(client, resource);我们一个一个的看,先看headers函数:

void headers(int client, const char *filename)
{char buf[1024];(void)filename;  /* could use filename to determine file type */strcpy(buf, "HTTP/1.0 200 OK\r\n");send(client, buf, strlen(buf), 0);strcpy(buf, SERVER_STRING);send(client, buf, strlen(buf), 0);sprintf(buf, "Content-Type: text/html\r\n");send(client, buf, strlen(buf), 0);strcpy(buf, "\r\n");send(client, buf, strlen(buf), 0);
}

我们可以看到这个函数就是发送一些网页的信息到客户端,咋一看并不是什么实质的信息。但是这个函数是非常重要的,它取决于我们的静态网页能否显示出来。这里就涉及到一个概念:请求头和响应头。

2.请求头和响应头:

       请求头和响应头是HTTP协议中用于描述HTTP事务具体操作参数的重要部分。在Web通信过程中,客户端向服务器发送请求,服务器根据请求返回相应的响应。在这个过程中,请求头和响应头起着至关重要的信息传递作用。它们不仅定义了请求和响应的基本信息,还包含了处理这些信息所需的额外数据。

从客户端到服务器的请求信息由以下几个关键部分组成:

  1. 请求行:包含请求方法(如GET、POST)、请求的URL以及协议版本号。

  2. 请求头:以键值对的形式存在,包含若干属性,例如Usertips Accept(可接受的内容类型)、Authorization(认证信息)、Cookie`(由服务器设置的Cookie)等,通过这些属性服务器可以获取客户端的信息。

  3. 请求体:在POST或PUT请求中出现,承载多个请求参数的数据,通常采用键值对形式编码。

相应地,服务器的响应也由几个核心部分组成:

  1. 响应行:包括协议版本、状态码及状态描述文本。

  2. 响应头:同样由多个属性组成,例如Server(服务器类型)、Set-Cookie(设置Cookie)、Location(重定向目标地址)等,告知客户端有关响应的额外信息。

  3. 响应体:即实际返回给客户端的“干货”,如HTML页面内容、图片数据等。

状态码是响应头中的一个重要元素,它以清晰的语言告诉客户端本次请求的处理结果。状态码分为五大类:

  • 1xx 表示信息性状态码,如100 Continue;
  • 2xx 表示成功状态码,如200 OK;
  • 3xx 表示重定向状态码,如301 Moved Permanently;
  • 4xx 表示客户端错误状态码,如404 Not Found;
  • 5xx 表示服务器错误状态码,如500 Internal Server Error。

总的来说,请求头和响应头在HTTP通信中扮演着极其重要的角色,它们不仅提供了关于请求和响应的基本信息,还包含了处理这些信息所必需的元数据。了解和掌握这些头部信息对于网络编程和Web开发来说是基础且关键的。通过合理配置和使用请求头与响应头,开发者能够更精确地控制HTTP请求和响应的行为,优化用户体验,并确保数据传输的安全性和效率。

        就这个项目来说就是对于客户端的一个GET方法的回应,让客户端准备好显示我们要展示的东西。

3.本地内容展示:

        我们在上一章的精读中已经是知道,如果我们向显示内容,直接把我们要显示的内容传递到客户端即可,同样的当我们需要显示一个本地的静态网页的时候,我们只需要将本地的文件读取出来然后通过socket通信传递到客户端即可。


void cat(int client, FILE *resource)
{//将文件的内容输出到clientchar buf[1024];//从resource指定的文件流中读取一行数据,知道遇到换行符,文件结束符,或者buf的长度。fgets(buf, sizeof(buf), resource);//feof用于检查文件流是否已经到达文件末尾。这段代码就是反复的读取数据,然后发送到client中.while (!feof(resource)){send(client, buf, strlen(buf), 0);fgets(buf, sizeof(buf), resource);}
}

从这个代码中我们可以看出来过程和我们刚刚的思路基本是一致的,根据path去读取本地的文件,然后一行一行的send到客户端即可。

那么至此,你已经学会了如何在网页上显示一个 本地的静态网页了。下一章我们来看如何根据静态网页的信息来显示新的内容。

        

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词