`

琐碎的学习——tinyhttpd简易WEB服务器

 
阅读更多

tinyhttpd是一个超轻量型Http Server,使用C语言开发,全部代码只有502行。

我从sourceforge上下载后编译不通过,提示找不到libsocket,发现去掉对libsocket的依赖也没问题

httpd: httpd.c
	gcc -g -W -Wall -lsocket -lpthread -o httpd httpd.c
#改为
httpd: httpd.c
	gcc -g -W -Wall -lpthread -o httpd httpd.c

 执行cgi的函数中也有错误

#273行
   execl(path, path, NULL);
#改为
   execl(path, query_string, NULL);

 编译运行./httpd就可以把web服务运行起来了。浏览器打开http://127.0.0.1:8080/访问

 下面学习几段源代码

1,main函数初始化套接口监听并接收连接,针对每个连接开启线程去处理

int main(void)
{
 int server_sock = -1;
 u_short port = 8080;
 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);
}

2,accept_request函数解析客户端请求,判断是请求静态文件还是cgi代码(通过请求类型以及参数来判定),如果是静态文件则将文件输出给前端,如果是cgi则进入cgi处理函数

3,execute_cgi函数负责将请求传递给cgi程序处理,服务器与cgi之间通过管道pip通信,首先初始化两个管道,并创建子进程去执行cgi函数

 if (pipe(cgi_output) < 0) {
  cannot_execute(client);
  return;
 }
 if (pipe(cgi_input) < 0) {
  cannot_execute(client);
  return;
 }

 if ( (pid = fork()) < 0 ) {
  cannot_execute(client);
  return;
 }

 子进程中,用刚才初始化的管道替换掉标准输入标准输出,将请求参数加到环境变量中,调用execl执行cgi程序获得输出。

if (pid == 0)  /* child: CGI script */
 {
  char meth_env[255];
  char query_env[255];
  char length_env[255];

  dup2(cgi_output[1], 1);
  dup2(cgi_input[0], 0);
  close(cgi_output[0]);
  close(cgi_input[1]);
  sprintf(meth_env, "REQUEST_METHOD=%s", method);
  putenv(meth_env);
  if (strcasecmp(method, "GET") == 0) {
   sprintf(query_env, "QUERY_STRING=%s", query_string);
   putenv(query_env);
  }
  else {   /* POST */
   sprintf(length_env, "CONTENT_LENGTH=%d", content_length);
   putenv(length_env);
  }
  execl(path, query_string, NULL);
  exit(0);
 }

 服务器"线程"继续将post的请求头发送给子进程(cgi程序),然后获取cgi程序的标准输出作为响应内容发送给客户端。

else {    /* parent */
  close(cgi_output[1]);
  close(cgi_input[0]);
  if (strcasecmp(method, "POST") == 0)
   for (i = 0; i < content_length; i++) {
    recv(client, &c, 1, 0);
    write(cgi_input[1], &c, 1);
   }
  while (read(cgi_output[0], &c, 1) > 0)
   send(client, &c, 1, 0);

  close(cgi_output[0]);
  close(cgi_input[1]);
  waitpid(pid, &status, 0);
 }

 502行代码都比较精炼,服务器在完成一些web功能外还处理了一些异常情况,500状态码cgi执行出错,404找不到文件错误之类的,开始以为putenv函数会设置个全局变量,当多用户访问的时候会互相影响,后来测试了一下发现设置的变量是互相隔离的,这些代码值得学习。

分享到:
评论

相关推荐

    巧设阶梯任务 促进深度学习——以“二氧化碳与碱溶液反应”为例.pdf

    尤其是在初中化学教学中,由于化学知识点多且琐碎,教师在日常教学中应促进深度学习,加强新旧知识的联系与应用,关注高阶思维的发展。 文章以“二氧化碳与碱溶液反应”为例,通过设置探究型学习任务“如何使塑料瓶...

    “核心问题”视域下促进学生深度学习的策略——以初中数学教学实践为例.pdf

    核心素养视域下“深度学习”的课堂教学策略探析——以人教版“分数乘分数”教学为例[J]. 科教导刊 ( 电子版 ),2019(6). 综上所述,以“核心问题”为导向的初中数学教学策略,通过创设问题情境,构建知识网络,促进...

    WEB程序员简易开发工具包

    【标题】"WEB程序员简易开发工具包"是一个专门为WEB开发者设计的实用资源集合,它包含了在日常编程过程中可能需要的一些基础工具。这个工具包旨在简化开发流程,提高工作效率。 【描述】开发人员在构建WEB应用时,...

    让深度学习走进小学数学课堂 ——核心素养下小学数学教学的一点感悟.pdf

    【深度学习在小学数学教学中的应用】 深度学习是一种教育理念,强调在教师的指导下,学生全身心投入,围绕富有挑战性的学习主题进行探究,从而体验成功并实现个人发展。在小学数学教学中引入深度学习,有助于培养...

    z10:Web服务器z10

    Web服务器扩建Buildout安装必要的工具以在特定domU上运行Web服务器。 只是加强建设并运行virtualenv .bin/pip install zc.buildout# Fix missing openssl header filesenv LDFLAGS="-L$(brew --prefix openssl)/lib...

    让阅读张开腾飞的翅膀——小学语文阅读教学中的深度学习策略.pdf

    【深度学习在小学语文阅读教学中的应用】 小学语文阅读教学是培养学生基本素质和全面能力提升的重要环节,尤其在新课程改革背景下,阅读教学的质量直接影响到语文教学质量与学生的学习效果。然而,当前的教学现状中...

    C++学习的琐碎点

    在深入探讨C++学习过程中的琐碎点与注意点时,我们首先应当明确,C++是一种功能强大且灵活的编程语言,它结合了C语言的高效性和面向对象编程的特性,广泛应用于系统软件、游戏开发、高性能计算等领域。然而,正是...

    WEB考勤系统实施方案

    实施WEB考勤系统,需要注意的几点包括:确保网络的稳定性和安全性、服务器的处理能力以及系统数据的备份和恢复等。此外,用户培训也是确保系统顺利运行的重要环节。在正式投入使用前,需要对员工进行充分的操作培训...

    Matlab系列--记录一些琐碎的matlab机器学习程序.zip

    Matlab系列--记录一些琐碎的matlab机器学习程序

    班级管理——班务通

    在教育领域,特别是针对基础教育阶段,班主任的工作往往琐碎且繁杂,涉及到学生信息、成绩、日常管理等多方面的内容。随着信息技术的发展,越来越多的软件工具被开发出来,旨在帮助班主任简化工作流程,提高管理效率...

    最好的CHM制作工具 琐碎打包1.8.1

    "最好的CHM制作工具 琐碎打包1.8.1"是一款专用于创建CHM文件的软件,据描述,该工具在众多CHM制作工具中脱颖而出,因其易用性而受到青睐。 CHM制作工具的核心功能通常包括以下几点: 1. **HTML编辑**:用户可以...

    超级记忆力——图像记忆法

    这种方法不仅适用于日常生活的琐碎记忆,如电话号码、日期,还能在学习复杂概念、公式或诗歌时发挥重要作用。 #### 记忆原理概说 图像记忆的核心在于创建两个或多个图像之间的联系,通过构建动态、富有色彩和声音...

    琐碎打包工具 V1.81

    如果你有许多小的文档、编程用的源代码、小图片等等琐碎的东西,弃之可惜,长期放在各个文件夹里又显零乱,偶而要用找起来也麻烦,琐碎打包工具可以帮助你将这些琐碎打包成一个chm文件,还可以加上说明页,既有目录...

    web简单小工具

    使用"Web简单小工具"可以显著提升Web开发的效率,让开发者更专注于创意和功能实现,而不是琐碎的测量和调试工作。对于新手和经验丰富的开发者来说,都是一个值得拥有的利器。在不断更新迭代的过程中,这样的工具往往...

    从碎片化学习走向深度学习.pdf

    这种学习方式可以帮助学习者将琐碎的时间高效利用起来,让学习成为休闲与自我调整的好方式。 知识点二:碎片化学习的优点 碎片化学习可以让学习内容变得目不暇接,学习形式变得自由灵活,学习者可以随时随地学习,...

    EasyUI_功能强大的web前端JS框架

    EasyUI 是一个基于JavaScript的优秀前端UI框架,专为web开发者设计,旨在简化网页应用程序的构建过程,提高开发效率。...通过学习和掌握EasyUI,开发者可以大大提高工作效率,创造出更加吸引人的web应用程序。

    Python-LinuxGSM一个命令行工具用于快速简单地部署和管理专用游戏服务器

    通过使用LinuxGSM,无论是个人玩家还是服务器提供商,都可以更高效地管理和维护他们的游戏服务器,从而将更多的精力投入到游戏中,而不是服务器的琐碎事务上。随着持续的开发和社区支持,LinuxGSM不断进化,以适应新...

    gsoap-2.7(soap接口生成)

    生成的服务器端代码可以运行在各种Web服务器上,如Apache、IIS等,接收并处理来自客户端的SOAP请求。 至于"vs"标签,通常指的是Visual Studio,这是一个广泛使用的C++开发环境。gSOAP提供了对Visual Studio的良好...

    作文指导:听听——的声音.ppt

    这篇“作文指导:听听——的声音.ppt”主要探讨了如何通过写作来捕捉和描绘声音,以此传达深层含义和情感。以下是其中的关键知识点: 1. **审题技巧**: - "听听"强调了对声音的细腻观察和深入理解,意味着作文...

    新官上任——新任经理人工作指南新官上任——新任经理人工作指南新官上任——新任经理人工作指南新官上任——新任经理人工作指南新官上任——新任经理人工作指南

    新任经理人需要学会如何高效安排日程,区分任务的紧急性和重要性,确保关键任务得到及时处理,同时避免陷入琐碎事务的泥潭。 ### 7. 情绪管理与压力调节 作为经理人,情绪稳定和良好的心理素质是必备条件。面对...

Global site tag (gtag.js) - Google Analytics