[OK210开发板体验]系统篇(3) 基于OK210的智能家居系统之后端设计CGI

前两篇分别记录了基于OK210智能家居系统的组成以及Boa服务器的搭建基于OK210的智能家居系统的前端设计,即成功搭建了服务器和前端显示页面,但他们都是独立的个体,为了能够动态的使两者相互通信,就需要后端的支持,本节是后端设计的第一篇,主要引入CGI部分。具体包括:
CGI工作原理,介绍CGI与Web服务器的工作机制;
CGI通信方式,主要介绍CGI对应表单Get和Post方法的数据交互;
CGI简单示例,通过简单的post和get方法,加深对CGI接口通信的理解
一、CGI工作原理
CGI是Common Gateway Interface(通用网关接口)的缩写,它是一个Web服务器主机提供信息服务的标准接口。通过CGI接口,Web服务器就能够获取客户端提交的信息,转交给服务器端的CGI程序进行处理,最后返回结果给客户端。
外部CGI程序与Web服务器进行通信、传递有关参数和处理结果是通过环境变量、命令行参数和标准输入来进行的。服务器提供了客户端(浏览器)与CGI扩展程序之间的信息交换的通道。CGI的标准输入是服务器的标准输出,而CGI的标准输出是服务器的标准输入。客户的请求通过服务器的标准输出传送给CGI的标准输入,CGI对信息进行处理后,将结果发送到它的标准输入,然后由服务器将处理结果发送给客户端。
WEB服务器将根据CGI程序的类型决定数据向CGI程序的传送方式,一般来讲是通过标准输入/输出流和环境变量来与CGI程序间传递数据,如下图所示:
 

CGI程序通过标准输入(STDIN)和标准输出(STDOUT)来进行输入输出。此外CGI程序还通过环境变量来得到输入,操作系统提供了许 多环境变量,它们定义了程序的执行环境,应用程序可以存取它们。Web服务器和CGI接口又另外设置了一些环境变量,用来向CGI程序传递一些重要的参数。CGI的GET方法还通过环境变量QUERY-STRING向CGI程序传递Form中的数据。 下面是一些常用的CGI环境变量:
 

二、 CGI通信方式

服务器程序可以通过三种途径接收信息:环境变量、命令行和标准输入。具体使用哪一种方法要由<FORM>标签的METHOD属性来决定。 在“METHOD=GET”时,向CGI程序传递表单编码信息的正常做法是通过命令来进行的。大多数表单编码信息都是通过QUERY_STRING的环境变量来传递的。如果“METHOD=POST”,表单信息将通过标准输入来读取。还有一种不使用表单就可以向CGI传送信息的方法,那就是把信息直接追回在URL地址后面,信息和URL之间用问号(?)来分隔。
1POST方法
如果采用POST方法,那么客户端来的用户数据将存放在CGI进程的标准输入中,同时将用户数据的长度赋予环境变量中的CONTENT_LENGTH。客户端用POST方式发送数据有一个相应的MIME类型(通用Internet邮件扩充服务:Multi-purpose Internet Mail Extensions)。目前,MIME类型一般是:application/x-wwww-form-urlencoded,该类型表示数据来自HTML表单。该类型记录在环境变量CONTENT_TYPE中,CGI程序应该检查该变量的值。
2GET方法
在该方法下,CGI程序无法直接从服务器的标准输入中获取数据,因为服务器把它从标准输入接收到得数据编码到环境变量QUERY_STRING(或PATH_INFO)。GET与POST的区别:采用GET方法提交HTML表单数据的时候,客户机将把这些数据附加到由ACTION标记命名的URL的末尾,用一个包括把经过URL编码后的信息与CGI程序的名字分开:http://www.mycorp.com/hello.html?name=hgq$id=1,QUERY_STRING的值为name=hgq&id=1,有些程序员不愿意采用GET方法,因为在他们看来,把动态信息附加在URL的末尾有违URL的出发点:URL作为一种标准用语,一般是用作网络资源的唯一定位标示。
环境变量是一个保存用户信息的内存区。当客户端的用户通过浏览器发出CGI请求时,服务器就寻找本地的相应CGI程序并执行它。在执行CGI程序的同时,服务器把该用户的信息保存到环境变量里。接下来,CGI程序的执行流程是这样的:查询与该CGI程序进程相应的环境变量:第一步是request_method,如果是POST,就从环境变量的len,然后到该进程相应的标准输入取出len长的数据。如果是GET,则用户数据就在环境变量的QUERY_STRING里。
3POSTGET的区别
 GET方式接收的数据是有长度限制,而用 POST方式接收的数据是没有长度限制的。并且,以GET方式发送数据,可以通过 URL的形式来发送,但 POST方式发送的数据必须要通过 Form才到发送。
三、 CGI简单示例
该示例为CGI编程入门的最简单示例:GET与POST示例,其中GET方法做一个加法运算,需要接收两个参数 ;POST方法做一个乘法运算,需要接收两个参数 。将下面的get.c和post.c文件使用gcc编译成对应的cgi文件,放到boa.conf配置文件中ScriptAlias指定的目录中;将cgi.html文件放到boa.conf配置文件中DocumentRoot指定的目录中,即可进行测试。
其中代码中的关键主语句,作如下说明:
(1) printf("Content-Type:text/html/n/n");
此行通过标准输出将字符串″Contenttype:text/plain/n/n″传送给Web服务器。它是一个MIME头信息,它告诉Web服务器随 后的输出是以纯ASCII文本的形式。请注意在这个头信息中有两个换行符,这是因为Web服务器需要在实际的文本信息开始之前先看见一个空行。
(2) data = getenv("QUERY_STRING");
CGI定义:当GET方法提交的表单被发送到服务器断后,表单中的数据被保存在服务器上一个叫做QUERY_STRING的环境变量中。这种表单的处理相对简单,只要读取环境变量就可以了。
(3) sscanf(data,"a=%[^&]&b=%s",a,b)!=2
这个是关于sscanf函数的使用问题,自己可以上网搜索一下,这里不再详述!
(4)atoi(a)+atoi(b)
atoi函数的功能是将字符型成整型,只有转换之后才可以进行加法运算!
(5) lenstr=getenv("CONTENT_LENGTH");
Web服务器在调用使用POST方法的CGI程序时设置此环境变量,它的文本值表示Web服务器传送给CGI程序的输入中的字符数目,因此需要使用函数atoi() 将此环境变量的值转换成整数,并赋给变量len(下面有定义)
(6) fgets(poststr,len+1,stdin);
这个是关于fgets函数的使用问题,自己可以上网搜索一下,这里不再详述!
(7)关于网页制作的基础入门知识,可查看http://www.w3school.com.cn/进行学习。
  1. //get.c
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. int main(void)
  5. {
  6.         char *data;
  7.         char a[10],b[10];
  8.         printf("Content-Type:text/html\n\n");
  9.         printf("<HTML>\n");
  10.         printf("<HEAD>\n<TITLE >Get Method</TITLE>\n</HEAD>\n");
  11.         printf("<BODY>\n");
  12.         printf("<div style=\"font-size:12px\">\n");
  13.         data = getenv("QUERY_STRING");
  14.         if(sscanf(data,"a=%[^&]&b=%s",a,b)!=2){
  15.                 printf("<DIV STYLE=\"COLOR:RED\">Error parameters should be entered!</DIV>\n");
  16.         }
  17.         else{
  18.                printf("<DIV STYLE=\"COLOR:GREEN; font-size:15px;font-weight:bold\">a + b = %d</DIV>\n",atoi(a)+atoi(b));
  19.         }
  20.         printf("<HR COLOR=\"blue\" align=\"left/" width=\"100\">");
  21.         printf("<input type=\"button\" value=\"Back CGI/" onclick=\"javascript:window.location='../cgi.html'/">");
  22.         printf("
  23. \n");
  24.         printf("</BODY>\n");
  25.         printf("</HTML>\n");
  26.         return 0;
  27. }
复制代码
  1. //post.c
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. int main(void){
  5.         int len;
  6.         char *lenstr,poststr[20];
  7.         char m[10],n[10];
  8.         printf("Content-Type:text/html\n\n");
  9.         printf("<HTML>\n");
  10.         printf("<HEAD>\n<TITLE >post Method</TITLE>\n</HEAD>\n");
  11.         printf("<BODY>/n");
  12.         printf("<div style= \"font-size:12px\">\n");
  13.         lenstr=getenv("CONTENT_LENGTH");
  14.         if(lenstr == NULL)
  15.                 printf("<DIV STYLE=\"COLOR:RED\">Error parameters should be entered!</DIV>\n");
  16.         else{
  17.                 len=atoi(lenstr);
  18.                 fgets(poststr,len+1,stdin);
  19.                 if(sscanf(poststr,"m=%[^&]&n=%s",m,n)!=2){
  20.                         printf("<DIV STYLE=\"COLOR:RED\">Error: Parameters are not right!</DIV>\n");
  21.                 }
  22.                 else{
  23.                        printf("<DIV STYLE=\"COLOR:GREEN; font-size:15px;font-weight:bold\">m * n = %d</DIV>\n",atoi(m)*atoi(n));
  24.                 }
  25.         }
  26.         printf("<HR COLOR=\"blue\" align=\"left\" width=\"100\">");
  27.         printf("<input type=\"button\" value=\"Back CGI\" onclick=\"javascript:window.location='../cgi.html'\">");
  28.         printf("\n");
  29.         printf("</BODY>\n");
  30.         printf("</HTML>\n");
  31.         fflush(stdout);
  32.         return 0;
  33. }
复制代码
  1. <!--
  2. cgi.html
  3. -->
  4. <html>
  5. <head>
  6. <title>CGI Testing</title>
  7. </head>
  8. <body>
  9. <table width="200" height="180" border="0" style="font-size:12px">
  10. <tr><td>
  11. <div style="font-weight:bold; font-size:15px">Method: GET
  12. <div>please input two number:<div>
  13. <form method="get" action="./cgi-bin/get">
  14. <input type="txt" size="3" name="a">+
  15. <input type="txt" size="3" name="b">=
  16. <input type="submit" value="sum">
  17. </form>
  18. </td></tr>
  19. <tr><td>
  20. <div style="font-weight:bold; font-size:15px">Method: POST
  21. <div>please input two number:<div>
  22. <form method="post" action="./cgi-bin/post">
  23. <input type="txt" size="3" name="m">*
  24. <input type="txt" size="3" name="n">=
  25. <input type="submit" value="resu">
  26. </form>
  27. </td></tr>
  28. <tr><td><inputtype="button" value="Back Home"onclick='javascript:window.location="./index.html"'></td></tr>
  29. </table>
  30. </body>
  31. </html>
复制代码