1.引言
Server一般有兩種含義,一種是表示硬體,通常是指那些具有較高計算能力,能夠提供給多個用戶使用的計算機。另外一種含義是表示軟體程序,這種程序主要用來對外提供某些服務,比如郵件服務、資料庫服務、域名服務、網頁服務等。
本篇介紹的是軟體層面的Server,WebServer是指能夠供 Web 服務的 Server,它的主要功能是提供網上信息瀏覽服務。嵌入式WebServer,是在嵌入式系統上運行的,可以通過瀏覽器去訪問,對硬體要求會低一點。我們常用的家用路由器,就是一個典型的應用,通過Web介面直接進行訪問和配置設備,非常便利。
嵌入式WebServer有很多中,比如BOA、shttpd、lighttpd、goahead、appweb和apache等。本篇以thttpd()為例,來進行介紹。
2.環境介紹
2.1.硬體
NUC972開發板
2.2.軟體
1) Uboot繼續使用之前文章用的,無須改動。
2) Kernel在上一篇基礎上,無須改動。
3) Rootfs在上一篇用Buildroot生成的基礎上,需要做一定的改動,用來生成thttpd。
3.Buildroot配置
Buildroot里需要做一定的配置,用來支持thttpd,只需要把Target packages- Networking applications中的thttpd選中即可
之後保存,編譯即可。我們只需要用到下面兩個文件
/output/target/usr/sbin/thttpd
/output/build/thttpd-2.25b/contrib/redhat-rpm/thttpd.conf
我們只需要將上述生成的thttpd直接放到板子的/usr/sbin目錄里(注意要修改它的可執行權限)即可,將thttpd.conf放到/etc目錄中。
4.thttpd基礎功能
4.1 顯示靜態介面
開啟thttpd伺服器可以使用配置文件的方式,或者直接跟運行選項。我們以配置文件為例。
使用配置文件的方式如下:
使用 vi 打開 thttpd.conf 文件,並進行修改,我們將chroot注釋掉,同時將"user=httpd"改為"user=root"
dir=/home/httpd/html
#chroot
user=root# default = nobody
logfile=/var/log/thttpd.log
pidfile=/var/run/thttpd.pid
# This section _documents_ defaults in effect
# port=80
# nosymlink# default = !chroot
# novhost
# nocgipat
# nothrottles
# host=0.0.0.0
# charset=iso-8859-1
注意上述dir=/home/httpd/html 這個目錄是用來存放html文件的,所以我們需要新建這三個目錄
# cd /
# mkdir /home /home/httpd /home/httpd/html
切換到 /home/httpd/html 目錄下,並新建一個 index.html 文件,為什麼名字叫index,我也不清楚,猜測是webserver程序里指定的,因為我試了換成其他的名字是無法正常工作的。
# cd /home/httpd/html
# vi index.html
內容為:
<h1>Hello TopSemic Friends!</h1>
保存,退出。
之後啟動thttpd
# thttpd -D -C /etc/thttpd.conf &
最後就可以在訪問了,在瀏覽器中輸入192.168.0.100,顯示如下:
index.html 中的內容簡單介紹下,
<h1> …. </h1>,表示標題,<h1> 定義最大的標題。<h6> 定義最小的標題。
Html文件中的<h1> 含義可以參考:
參數具體含義可以在這裡查詢。
4.2 CGI示例
CGI是實現web交互的一個比較早的,支持任何語言。依賴於web伺服器使用。整體上的結構如圖所示:
CGI(公用網關接口)規定了Web伺服器調用其他可執行程序(CGI程序)的接口協議標準。Web伺服器通過調用CGI程序實現和Web瀏覽器的交互,也就是CGI程序接受Web瀏覽器發送給Web伺服器的信息進行處理,將響應結果再回送給Web伺服器及Web瀏覽器。CGI程序一般完成Web網頁中表單(Form)數據的處理、資料庫查詢和實現與傳統應用系統的集成等工作。CGI程序可以用任何程序設計語言編寫,如Shell腳本語言、Perl、Fortran、Pascal、C語言等。但是用C語言編寫的CGI程序具有執行速度快、安全性高(因為C語言程序是編譯執行且不可被修改)等特點。
CGI接口標準包括標準輸入、環境變量、標準輸出三部分。
CGI文件並不要求是以.cgi或.CGI為後綴的文件,只要生成它的.c文件按照下面的格式來就行了。例如test.c
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
printf("Content-type:text/html\n\n");
printf("<html>\n");
printf("<head><title>An html page from a cgi</title></head>\n");
printf("<body>\n");
printf("<h1>TopSemic CGI Example</h1>\n");
printf("</body>\n");
printf("</html>\n");
fflush(stdout);
return 0;
}
它是以printf("Content-type:text/html\n\n");開始,這是必須的。然後前後分別以printf("<html>\n");和printf("</html>\n");作為開始和結束,中間可嵌入我們自己處理的代碼。
然後arm-linux-gcc test.c -o test.cgi就行了,如果編出來的test沒有可執行權限,需要執行chmod +x test.cgi,然後將此文件放到伺服器的根目錄,如前面例子所示的/home/httpd/html/目錄。
另外需要在上面的配置文件基礎上,加上一句cgipat=test.cgi,重啟啟動thttpd。
dir=/home/httpd/html
#chroot
user=root# default = nobody
logfile=/var/log/thttpd.log
pidfile=/var/run/thttpd.pid
cgipat=test.cgi
這樣就可以在瀏覽器中訪問了,格式為 IP/test.cgi,如"192.168.0.100/test.cgi"。訪問這個文件的效果如下圖所示
備註:
如果無法訪問,可能需要清除瀏覽器cookie/緩存
4.3 CGI與按鈕結合
前面介紹訪問CGI文件可以通過[IP]/[CGI文件名]這種格式來實現,如果我們在主頁(index.html)上點擊某個按鈕,它能從192.168.0.100跳轉到192.168.0.100/test.cgi,即可把按鈕與用C語言生成的CGI文件貫通起來。實現這一點的關鍵在於html中form表單中的action。如下例所示,action="test"
<html>
<head>
<title>Test Page</title>
</head>
<body style="margin-left:480px">
<h1>Test Button</h1>
<form enctype="application/x-www-form-urlencoded" action="test.cgi" method="post">
<input type="submit" value="Query">
</form>
</body>
</html>
在此頁面中,有一個名為Query的按鍵,點擊下它,頁面就會從192.168.50.10跳轉到192.168.50.10/test.cgi,並在thttpd伺服器的根目錄找名為test的文件,查看它是否為cgi文件,如果是cgi文件,即執行它。
5.控制LED燈
我們要實現的功能是:
點擊ON按鈕點亮LED,點擊OFF按鈕關閉LED,具體實現方法如下:
1) 建立index.html文件
<html>
<head>
<title>Test Page</title>
</head>
<body style="margin-left:480px">
<h2>TopSemic LED Example</h2>
LED D3:<br>
<form enctype="application/x-www-form-urlencoded" action="led-on.cgi" method="post">
<input type="submit" value="ON">
</form>
<form enctype="application/x-www-form-urlencoded" action="led-off.cgi" method="post">
<input type="submit" value="OFF">
</form>
</body>
</html>
2)修改配置文件
cgipat=led-on.cgi|led-off.cgi
3) cgi文件
led-on.c,交叉編譯生成led-on.cgi
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
// Operation of LED D2
#define EXPORT_GPIO "echo 37 > /sys/class/gpio/export"
#define GPIO_OUTPUT "echo out > /sys/class/gpio/gpio37/direction"
#define TURNON_LED "echo 0 > /sys/class/gpio/gpio37/value"
#define TURNOFF_LED "echo 1 > /sys/class/gpio/gpio37/value"
void InitLED()
{
system(EXPORT_GPIO);
system(GPIO_OUTPUT);
}
void TurnOnLED()
{
system(TURNON_LED);
}
void TurnOffLED()
{
system(TURNOFF_LED);
}
int main(void)
{
printf("Content-type:text/html\n\n");
printf("<html>\n");
InitLED();
TurnOnLED();
printf("</body>\n");
printf("</html>\n");
return 0;
}
將上述main()函數裡TurnOnLED()改為TurnOffLED()另存為led-off.c,交叉編譯生成led-off.cgi. 注意一定要修改led-on.cgi和led-off.cgi的可執行權限。
4)重新啟動thttpd,
這樣就可以通過訪問192.168.0.100控制LED燈亮滅了。
但是有個小問題,就是點擊ON/OFF按鈕時會進入到對應cgi介面,還得返回到主頁面才能進行其他操作,這個目前還不知道怎麼解決。
6.控制LED燈改進
針對上一節點擊ON/OFF按鈕時會進入到對應cgi介面,還得返回到主頁面才能進行其他操作的問題,在文章發布後得到一個熱心朋友的幫助,得到了解決。
只需要對index.html做下改進,
<html>
<head>
<title>Test Page</title>
</head>
<script type="text/javascript">
function led_on() {
var xhr = new XMLHttpRequest();
xhr.open("POST", "led-on.cgi");
xhr.send();
}
function led_off() {
var xhr = new XMLHttpRequest();
xhr.open("POST", "led-off.cgi");
xhr.send();
}
</script>
<body style="margin-left:480px">
<h2>TopSemic LED Example</h2>
LED D3:<br>
<button type="button" onclick="led_on()">ON</button>
<button type="button" onclick="led_off()">OFF</button>
</body>
</html>
對上述代碼做個解釋:
前半段是在 HTML 頁面中插入了一段 JavaScript,
<script type="text/javascript">
……
</script>
JavaScript中定義兩個函數,JavaScript 函數通過 function 關鍵詞進行定義,其後是函數名和括號 (),由函數執行的代碼被放置在花括號中:{}
function name(參數 1, 參數 2, 參數 3) {
要執行的代碼
}
XMLHttpRequest 對象用於在後台與伺服器交換數據。
XMLHttpRequest 對象是開發者的夢想,因為您能夠:
--在不重新加載頁面的情況下更新網頁
--在頁面已加載後從伺服器請求數據
--在頁面已加載後從伺服器接收數據
--在後台向伺服器發送數據
所有現代的瀏覽器都支持 XMLHttpRequest 對象。
XMLHttpRequest.open() 方法初始化一個請求。
XMLHttpRequest.send() 方法用於發送 HTTP 請求。如果是異步請求(默認為異步請求),則此方法會在請求發送後立即返回。
7.參考資料
1)blog.csdn.net/xygl2009/article/details/41971441
2)blog.csdn.net/sinat_28309919/article/details/77509781
3 ) blog.csdn.net/qq_695538007/article/details/9153187
8.結束語
本篇為大家介紹了Linux下Webserver的使用,歡迎大家多交流