[OK210開發板體驗]系統篇(3) 基于OK210的智能家居系統之后端設計CGI

原創 2015-12-24 14:30:00 [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>
復制代碼

相關產品 >

  • OKMX6UL-C開發板

    飛凌嵌入式專注imx6系列imx6ul開發板、飛思卡爾imx6ul核心板等ARM嵌入式核心控制系統研發、設計和生產,i.mx6UL系列產品現已暢銷全國,作為恩智浦imx6ul,imx6ul開發板,i.mx6提供者,飛凌嵌入式提供基于iMX6 iMX6UL解決方案定制。

    了解詳情
    OKMX6UL-C開發板
  • OKMX6ULL-C開發板

    40*29mm,雙網雙CAN,8路串口| i.MX6ULL開發板是基于NXP i.MX6ULL設計開發的的一款Linux開發板 ,主頻800MHz,體積小,其核心板僅40*29mm,采用板對板連接器,適應場景豐富。 了解詳情
    OKMX6ULL-C開發板

推薦閱讀 換一批 換一批