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

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

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

推薦閱讀 換一批 換一批