[OK210開發(fā)板體驗]系統(tǒng)篇(3) 基于OK210的智能家居系統(tǒng)之后端設(shè)計CGI

原創(chuàng) 2015-12-24 14:30:00 [OK210開發(fā)板體驗]系統(tǒng)篇(3) 基于OK210的智能家居系統(tǒng)之后端設(shè)計CGI
前兩篇分別記錄了基于OK210智能家居系統(tǒng)的組成以及Boa服務(wù)器的搭建基于OK210的智能家居系統(tǒng)的前端設(shè)計,即成功搭建了服務(wù)器和前端顯示頁面,但他們都是獨立的個體,為了能夠動態(tài)的使兩者相互通信,就需要后端的支持,本節(jié)是后端設(shè)計的第一篇,主要引入CGI部分。具體包括:
CGI工作原理,介紹CGI與Web服務(wù)器的工作機制;
CGI通信方式,主要介紹CGI對應(yīng)表單Get和Post方法的數(shù)據(jù)交互;
CGI簡單示例,通過簡單的post和get方法,加深對CGI接口通信的理解
一、CGI工作原理
CGI是Common Gateway Interface(通用網(wǎng)關(guān)接口)的縮寫,它是一個Web服務(wù)器主機提供信息服務(wù)的標準接口。通過CGI接口,Web服務(wù)器就能夠獲取客戶端提交的信息,轉(zhuǎn)交給服務(wù)器端的CGI程序進行處理,最后返回結(jié)果給客戶端。
外部CGI程序與Web服務(wù)器進行通信、傳遞有關(guān)參數(shù)和處理結(jié)果是通過環(huán)境變量、命令行參數(shù)和標準輸入來進行的。服務(wù)器提供了客戶端(瀏覽器)與CGI擴展程序之間的信息交換的通道。CGI的標準輸入是服務(wù)器的標準輸出,而CGI的標準輸出是服務(wù)器的標準輸入??蛻舻恼埱笸ㄟ^服務(wù)器的標準輸出傳送給CGI的標準輸入,CGI對信息進行處理后,將結(jié)果發(fā)送到它的標準輸入,然后由服務(wù)器將處理結(jié)果發(fā)送給客戶端。
WEB服務(wù)器將根據(jù)CGI程序的類型決定數(shù)據(jù)向CGI程序的傳送方式,一般來講是通過標準輸入/輸出流和環(huán)境變量來與CGI程序間傳遞數(shù)據(jù),如下圖所示:
 

CGI程序通過標準輸入(STDIN)和標準輸出(STDOUT)來進行輸入輸出。此外CGI程序還通過環(huán)境變量來得到輸入,操作系統(tǒng)提供了許 多環(huán)境變量,它們定義了程序的執(zhí)行環(huán)境,應(yīng)用程序可以存取它們。Web服務(wù)器和CGI接口又另外設(shè)置了一些環(huán)境變量,用來向CGI程序傳遞一些重要的參數(shù)。CGI的GET方法還通過環(huán)境變量QUERY-STRING向CGI程序傳遞Form中的數(shù)據(jù)。 下面是一些常用的CGI環(huán)境變量:
 

二、 CGI通信方式

服務(wù)器程序可以通過三種途徑接收信息:環(huán)境變量、命令行和標準輸入。具體使用哪一種方法要由<FORM>標簽的METHOD屬性來決定。 在“METHOD=GET”時,向CGI程序傳遞表單編碼信息的正常做法是通過命令來進行的。大多數(shù)表單編碼信息都是通過QUERY_STRING的環(huán)境變量來傳遞的。如果“METHOD=POST”,表單信息將通過標準輸入來讀取。還有一種不使用表單就可以向CGI傳送信息的方法,那就是把信息直接追回在URL地址后面,信息和URL之間用問號(?)來分隔。
1POST方法
如果采用POST方法,那么客戶端來的用戶數(shù)據(jù)將存放在CGI進程的標準輸入中,同時將用戶數(shù)據(jù)的長度賦予環(huán)境變量中的CONTENT_LENGTH??蛻舳擞肞OST方式發(fā)送數(shù)據(jù)有一個相應(yīng)的MIME類型(通用Internet郵件擴充服務(wù):Multi-purpose Internet Mail Extensions)。目前,MIME類型一般是:application/x-wwww-form-urlencoded,該類型表示數(shù)據(jù)來自HTML表單。該類型記錄在環(huán)境變量CONTENT_TYPE中,CGI程序應(yīng)該檢查該變量的值。
2GET方法
在該方法下,CGI程序無法直接從服務(wù)器的標準輸入中獲取數(shù)據(jù),因為服務(wù)器把它從標準輸入接收到得數(shù)據(jù)編碼到環(huán)境變量QUERY_STRING(或PATH_INFO)。GET與POST的區(qū)別:采用GET方法提交HTML表單數(shù)據(jù)的時候,客戶機將把這些數(shù)據(jù)附加到由ACTION標記命名的URL的末尾,用一個包括把經(jīng)過URL編碼后的信息與CGI程序的名字分開:http://www.mycorp.com/hello.html?name=hgq$id=1,QUERY_STRING的值為name=hgq&id=1,有些程序員不愿意采用GET方法,因為在他們看來,把動態(tài)信息附加在URL的末尾有違URL的出發(fā)點:URL作為一種標準用語,一般是用作網(wǎng)絡(luò)資源的唯一定位標示。
環(huán)境變量是一個保存用戶信息的內(nèi)存區(qū)。當(dāng)客戶端的用戶通過瀏覽器發(fā)出CGI請求時,服務(wù)器就尋找本地的相應(yīng)CGI程序并執(zhí)行它。在執(zhí)行CGI程序的同時,服務(wù)器把該用戶的信息保存到環(huán)境變量里。接下來,CGI程序的執(zhí)行流程是這樣的:查詢與該CGI程序進程相應(yīng)的環(huán)境變量:第一步是request_method,如果是POST,就從環(huán)境變量的len,然后到該進程相應(yīng)的標準輸入取出len長的數(shù)據(jù)。如果是GET,則用戶數(shù)據(jù)就在環(huán)境變量的QUERY_STRING里。
3POSTGET的區(qū)別
 GET方式接收的數(shù)據(jù)是有長度限制,而用 POST方式接收的數(shù)據(jù)是沒有長度限制的。并且,以GET方式發(fā)送數(shù)據(jù),可以通過 URL的形式來發(fā)送,但 POST方式發(fā)送的數(shù)據(jù)必須要通過 Form才到發(fā)送。
三、 CGI簡單示例
該示例為CGI編程入門的最簡單示例:GET與POST示例,其中GET方法做一個加法運算,需要接收兩個參數(shù) ;POST方法做一個乘法運算,需要接收兩個參數(shù) 。將下面的get.c和post.c文件使用gcc編譯成對應(yīng)的cgi文件,放到boa.conf配置文件中ScriptAlias指定的目錄中;將cgi.html文件放到boa.conf配置文件中DocumentRoot指定的目錄中,即可進行測試。
其中代碼中的關(guān)鍵主語句,作如下說明:
(1) printf("Content-Type:text/html/n/n");
此行通過標準輸出將字符串″Contenttype:text/plain/n/n″傳送給Web服務(wù)器。它是一個MIME頭信息,它告訴Web服務(wù)器隨 后的輸出是以純ASCII文本的形式。請注意在這個頭信息中有兩個換行符,這是因為Web服務(wù)器需要在實際的文本信息開始之前先看見一個空行。
(2) data = getenv("QUERY_STRING");
CGI定義:當(dāng)GET方法提交的表單被發(fā)送到服務(wù)器斷后,表單中的數(shù)據(jù)被保存在服務(wù)器上一個叫做QUERY_STRING的環(huán)境變量中。這種表單的處理相對簡單,只要讀取環(huán)境變量就可以了。
(3) sscanf(data,"a=%[^&]&b=%s",a,b)!=2
這個是關(guān)于sscanf函數(shù)的使用問題,自己可以上網(wǎng)搜索一下,這里不再詳述!
(4)atoi(a)+atoi(b)
atoi函數(shù)的功能是將字符型成整型,只有轉(zhuǎn)換之后才可以進行加法運算!
(5) lenstr=getenv("CONTENT_LENGTH");
Web服務(wù)器在調(diào)用使用POST方法的CGI程序時設(shè)置此環(huán)境變量,它的文本值表示Web服務(wù)器傳送給CGI程序的輸入中的字符數(shù)目,因此需要使用函數(shù)atoi() 將此環(huán)境變量的值轉(zhuǎn)換成整數(shù),并賦給變量len(下面有定義)。
(6) fgets(poststr,len+1,stdin);
這個是關(guān)于fgets函數(shù)的使用問題,自己可以上網(wǎng)搜索一下,這里不再詳述!
(7)關(guān)于網(wǎng)頁制作的基礎(chǔ)入門知識,可查看http://www.w3school.com.cn/進行學(xué)習(xí)。
  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. }
復(fù)制代碼
  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. }
復(fù)制代碼
  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>
復(fù)制代碼

相關(guān)產(chǎn)品 >

  • OKMX6UL-C開發(fā)板

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

    了解詳情
    OKMX6UL-C開發(fā)板
  • OKMX6ULL-C開發(fā)板

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

推薦閱讀 換一批 換一批