在嵌入式設備的管理與交互中,基于Web方式的應用成為目前的主流,這種程序結構也就是大家非常熟悉的B/S結構,即在嵌入式設備上運行一個支持腳本或CGI功能的Web服務器,能夠生成動態頁面,在用戶端只需要通過Web瀏覽器就可以對嵌入式設備進行管理和監控,非常方便實用。本文主要介紹BOA服務器和CGI的工作原理。
一、BOA服務器
1.嵌入式WEB服務器常見的有lighttpd、shttpd、thttpd、boa、mathopd、minihttpd、appweb、goahead等,本文主要介紹BOA服務器。
它是一個非常小巧的服務器,執行代碼大約60KB左右,是一個運行于unix或linux下的,支持CGI的、適合于嵌入式系統的單任務的http服務器,源代碼開放、性能高。由于它是一個單任務的web服務器,只能一次完成用戶的請求,而不會fork出新的進程來處理并發的鏈接請求。但是BOA支持CGI,能夠為CGI程序fork出一個進程來執行相應的客戶請求。它的主要功能是在互聯嵌入式設備之間進行信息交互,達到通過網絡對嵌入式設備進行監控,并將反饋信息自動上傳給主控設備的目的。它是基于HTTP超文本傳輸協議的,Web網頁是Web服務基本的傳輸單元。嵌入式Web服務的工作基于客戶機/服務器計算模型,由Web瀏覽器(客戶機)和Web服務器(服務器)構成,也即著名的B/S結構。運行于客戶端的瀏覽器首先要與嵌入式Web服務器BOA端建立連接,打開一個套接字虛擬文件,此文件建立標志著SOCKET連接建立成功然后客戶端瀏覽器通過套接字SOCKET以GET或者POST參數傳遞方式向Web服務器提交請求,Web瀏覽器提交請求后,通過HTTP協議傳送給Web服務器。Web服務器接到請求后,根據請求的不同進行事務處理,返回HTML文件或者通過CGI調用外部應用程序,返回處理結果。服務器通過CGI與外部應用程序和腳本之間進行交互,根據客戶端瀏覽器在請求時所采用的方法,服務器會搜集客戶所提供的信息,并將該部分信息發送給指定的CGI擴展程序,CGI擴展程序進行信息處理并將結果返回給服務器,然后服務器對信息進行分析,并將結果發送回客戶端在瀏覽器上顯示出來。
2.服務器客戶端之間的通信,是客戶端的瀏覽器和服務器端的http服務器之間的HTTP通信,我們只需要知道瀏覽器請求執行服務器上哪個CGI程序就可以了,其他不必深究細節,以為這些過程不需要程序員去操作。服務器和CGI程序之間的通信才是我們關注的。
一般情況下,服務器和CGI程序之間是通過標準輸入輸出來進行傳遞的,而這個過程需要環境變量的協作方可實現。
(1)服務器將URL指向一個應用程序
(2)服務器為應用程序執行做準備
(3)應用程序執行,讀取標準輸入輸出和有關環境變量
(4)應用程序進行標準輸出
注:對于Windows系統而言,還可以通過profile文件進行數據傳輸
更通俗點講,網頁里面有個變量(環境變量),變量里面有個值, 通過某種方式把這個值傳到 cgi 程序中, cgi 程序中提取這個變量的值,根據這個值做出相應的處理;那么這個變量是怎么在從網頁傳到 cgi 程序的呢?
3.在HTML中,當客戶填寫了表單,并按下了發送(submit)按鈕后,表單的內容被發送到了服務器端,一般的,這時就需要有一個服務器端腳本來對表單的內容進行一些處理,或者是把它們保存起來,或者是按內容進行一些查詢,或者是一些別的什么。沒有了 CGI,WEB 的世界就完全失去了它的交互性,所有的信息都變成單向的了,而不能夠有任何的反饋。這里就要說到表單了:
表單是html中
這個標簽的翻譯,在網頁中主要負責數據采集功能。
一個表單有三個基本組成部分:表單標簽:這里面包含了處理表單數據所用CGI程序的URL以及數據提交到服務器的方法。 表單域:包含了文本框、密碼框、隱藏域、多行文本框、復選框、單選框、下拉選擇框和文件上傳框等。 表單按鈕:包括提交按鈕、復位按鈕和一般按鈕;用于將數據傳送到服務器上的CGI腳本或者取消輸入,還可以用表單按鈕來控制其他定義了處理腳本的處理工作。這些東西只要打開 dreamweaver 隨便建個 html 就可以看到它的表單元素; 當你打開一個網頁的時候,你輸入的文字或者做出的選擇,類似等等要提交信息的地方基本上都是屬于表單元素; 這些表單元素(表單項)都必須放在表單內, 而整個表單在網頁是看不到的,你可以理解它為一個容器,里面裝著你要發給服務器的東西。
由于 HTML 只能顯示靜態網頁,無法和服務器活動數據進行交互,所以要通過表單與服務器互動; 就跟你去銀行辦業務,人家要你在表上填一堆東西,然后把表提交給業務員,那個表就是表單, 網站表單類似這種包含了許多用戶填寫的信息,提交給服務器,服務器獲取填寫的信息后執行相應操作。
圖為html文件中的一個代碼段,這就是表單的提交過程
這里的“submit”即為表單內容,里面的數據會被提交到指定 URL(這個 url 可以是服務器上的一個 cgi程序,此處即為login.cgi)。
URL:統一資源定位符(Uniform Resource Locator,URL)是對可以從互聯網上得到的資源的位置和訪問方法的一種簡潔的表示,是互聯網上標準資源的地址。互聯網上的每個文件都有一個唯一的URL,它包含的信息指出文件的位置以及瀏覽器應該怎么處理它。
4.在此處也簡單的提一下網頁
網頁是一個純文本文件,是向瀏覽者傳遞信息的載體,以超文本和超媒體為技術,采用HTML、CSS、XML等語言來描述組成頁面的各種元素,包括文字、圖像、音樂等,并通過客戶端瀏覽器進行解析,從而向瀏覽器呈現網頁的各種內容。做好的網頁放在BOA服務器的WWW文件里,客戶端瀏覽器對哪個網頁有請求服務器就把哪個頁面發送給瀏覽器。
二、CGI
CGI即通用網關接口(Common Gateway Interface),是一個 Web 服務器主機提供信息服務的標準接口。通過CGI 接口,Web 服務器就能夠獲取客戶端提交的信息,轉交給服務端的CGI 程序進行處理,后返回結果給客戶端。組成 CGI 通信系統的是兩部分:一部分是 html 頁面,就是在用戶端瀏覽器上顯示的頁面。另一部分則是運行在服務器上的 Cgi 程序。它們之間的通訊方式如下圖:
客戶端(網頁)發送表單信息給服務器,服務器去調用CGI,CGI通過服務器將反饋信息發給客戶端,客戶端瀏覽器對信息進行解析并顯示。
CGI程序被用來解釋處理來自表單的輸入信息,并在服務器產生相應的處理,或將相應的信息反饋給瀏覽器。CGI使網頁不再是靜態的,而是具有交互功能。到時做好的 cgi 程序放在服務器 www/cgi-bin 里面,cgi 程序不能跳出 www文件夾取其他文件夾的資源。
對于 CGI 程序來說,它繼承了系統的環境變量。CGI 環境變量在 CGI 程序啟動時初始化,在結束時銷毀。當一個 CGI 程序不是被 web服務器調用時,它的環境變量幾乎是系統環境變量的復制。當這個 CGI 程序被 web服務器調用時,它的環境變量就會多了以下關于 web服務器、客戶端、CGI 傳輸過程等項目。
有了表單,知道表單項中有個按鈕點一下就可以提交表單了, 那么這個表單是怎么提交到服務器上面的?
上面那個代碼段中 method 中的 get 和 post 就是提交表單的兩種方式;
GET: 對于那些使用了屬性“METHOD=GET”的表單(或者沒有 METHOD 屬性,這時候 GET 是其缺省值),CGI 定義為:當表單被發送到服務器斷后,表單中的數據被保存在服務器上一個叫做 QUERY_STRING 的環境變量中。這種表單的處理相對簡單,只要讀取環境變量就可以了。
POST:對于 POST 類型的表單,其內容被送到 CGI 程序的標準輸入(在 C 語言中是stdin),而被傳送的長度被放在環境變量 CONTENT_LENGTH 中。因而我們要做的就是,在標準輸入中讀入 CONTENT_LENGTH 長度的字符串。從標準輸入讀入數據聽起來似乎要比從環境變量中讀數據來的要容易一些,其實則不然,有一些細節地方要注意,這在下面的程序中可以看到。特別要注意的一點就是:CGI 程序和一般的程序有所不同,一般的程序在讀完了一個文件流的內容之后,會得到一個EOF標志。但在 CGI 程序的表單處理過程中,EOF 是永遠不會出現的,所以千萬不要讀多于 CONTENT_LENGTH 長度的字符,否這會有什么后果,誰也不知道。
兩種表單提交方式之間的區別:
以GET方式接收的數據是有長度限制,而用POST 方式接收的數據是沒有長度限制的。并且,以GET方式發送數據,可以通過URL的形式來發送,但POST方式發送數據必須要通過Form才到發送。