《深入理解计算机系统》tiny服务器——1,深入理解计算机系统


  最近学习到了《深入理解计算机系统》的第11章网络编程,在最后一节是一个名为Tiny的小型web服务器的实现,源代码书中已经给出,这里就不再复制粘贴了。这篇小博客主要记录一下课后题10的解答。原题目为:
     写出CGI adder函数的HTML表单。你的表单应该包括两个文本框,用户将需要相加的两个数字填在这两个文本框中。你的表单应该使用GET方法请求内容。
     因为我以前没接触过HTML表单,先百度之,找到了w3school的HTML教材,看了一下表单的部分,写出了一个很简单的小表单,命名为index.html:

 1 <!DOCTYPE html>
 2 <html>
 3 <body>
 4 
 5 <p>
 6 please enter two numbers:<br>
 7 </p>
 8 
 9 <form action="/cgi-bin/adder">
10   The first number:
11   <input type="number" name="num1"> <br>
12   The second number:
13   <input type="number" name="num2"> <br>
14   <input type="submit" value="Submit">
15 </form>
16 
17 </body>
18 </html>

  这是输入localhost:8888之后浏览器显示的效果图。8888是我设置的tiny的端口,至于为什么没有后边的/index.html,是因为我在源代码中将index.html设为了主界面。

  我们可以随便输入两个数字,点击Submit按钮,结果肯定是不对的。。

  如上图所示,结果显示的是0。注意在该网页的地址栏处,我们看到"localhost:8888/cgi-bin/adder?num1=22&num2=22",看过tiny源码我们就会知道,adder.c所要分析的数据是在&符号两边的纯数字,也就是说,要想正确的被adder.c程序求和,地址栏应该显示"localhost:8888/cgi-bin/adder?22&22"才对。出现上图中的错误的原因就是,adder程序没有取得两个参数的数值大小。解决方法很简单,只需要在adder.c程序里把两个数字取出来就行了,整个adder.c代码如下所示:

 1 #include "net.h"
 2 
 3 int main(void)
 4 {
 5     char *buf, *p;
 6     char arg1[MAXLINE], arg2[MAXLINE], content[MAXLINE];
 7     char tmp[MAXLINE];
 8     int n1 = 0, n2 = 0;
 9 
10     if ( (buf = getenv("QUERY_STRING")) != NULL) {
11         p = strchr(buf, '&');
12         *p = '\0';
13 
14         strcpy(arg1, buf);
15         strcpy(arg2, p+1);
16 
17         //用来取出两个参数的代码
18         p = strchr(arg1, '=');
19         strcpy(arg1, p+1);
20         p = strchr(arg2, '=');
21         strcpy(arg2, p+1);
22 
23         n1 = atoi(arg1);
24         n2 = atoi(arg2);
25     }
26 
27     sprintf(content, "QUERY_STRING = %s", buf);
28     sprintf(content, "Welcome to add.com: ");
29     //sprintf(content, "arg1=%s, arg2=%s\n", arg1, arg2);  调试输出参数
30     sprintf(content, "%sThe Internet addition portal.\r\n<p>", content);
31     sprintf(content, "%sThe answer is: %d + %d = %d\r\n<p>",
32             content, n1, n2, n1 + n2);
33     sprintf(content, "%sThanks for visiting!\r\n", content);
34 
35     //generate the http response
36     printf("Connection: close\r\n");
37     printf("Content-length: %d\r\n", (int)strlen(content));
38     printf("Content-type: text/html\r\n\r\n");
39     printf("%s", content);
40     fflush(stdout);
41 
42     exit(0);
43 }

  重新编译adder.c之后,我们再次在浏览器输入网址:localhost:8888,输入两个数字,结果如图:

  至此,我们学习Tiny的第一阶段就算完成了,完成了课后题11.10的要求,能够处理来自浏览器的静态请求和动态请求。但是,由于我们的Tiny一次只能处理一个连接,效率太低了。下一节我们就要对Tiny进行一下改进,使其能够支持并发处理。

相关内容

    暂无相关文章