基于HTTP協(xié)議實現(xiàn)的小型web服務(wù)器的方法
我們先了解一下這個項目最終能達(dá)到的一個目標(biāo),然后以這個來進行項目的分析:
1、實現(xiàn)最基本的HTTP/1.0版本的web服務(wù)器,客戶端能夠使用GET、POST方法請求資源
2、服務(wù)器將客戶請求的資源以html頁面的形似呈現(xiàn),并能夠進行差錯處理(如:客戶請求的資源不存在時,服務(wù)器能夠返回一個404的頁面)
3、服務(wù)器能進行簡單的cgi運行。比如當(dāng)客戶在表單中輸入數(shù)據(jù)后,服務(wù)器能夠?qū)⑦\行結(jié)果返回個客戶
4、能夠通過頁面對數(shù)據(jù)庫進行操作,如增刪查改等操作
一、http服務(wù)器實現(xiàn)的基本框架
關(guān)于HTTP協(xié)議
即超文本傳輸協(xié)議,是互聯(lián)網(wǎng)上應(yīng)用最廣泛的網(wǎng)絡(luò)協(xié)議。它是應(yīng)用層的協(xié)議,底層是基于TCP通信的。HTTP協(xié)議的工作過程:客戶通過瀏覽器向服務(wù)器發(fā)送文檔請求,瀏覽器將請求的資源回應(yīng)給瀏覽器,然后關(guān)閉連接。即:連接->請求->響應(yīng)->關(guān)閉連接。
關(guān)于URL
即統(tǒng)一資源定位符,每個網(wǎng)頁都對應(yīng)一個URL地址(俗稱網(wǎng)址),具有全球唯一性。它包含的信息指出文件的位置以及瀏覽器應(yīng)該怎么處理它。 一個完整的URL包括協(xié)議類型、主機類型、路徑和文件名。
http協(xié)議的URL格式: http: //host[:port][abs_path] ,http表示使用http協(xié)議來進行資源定位;host是主機域名;port是端口號,一般有默認(rèn)的;abs_path代表資源的路徑。
這里我主要介紹項目中涉及的URL的兩種格式—URL帶參數(shù)和不帶參數(shù)的。
GET方法使用的是帶參數(shù)的URL,即傳遞的參數(shù)會使用?連接在資源路徑后邊;POST方法使用的是不帶參數(shù)的URL,它的參數(shù)是通過http請求報頭中的請求消息體傳遞給服務(wù)器的。
關(guān)于HTTP的請求與響應(yīng)格式
響應(yīng)報頭中的狀態(tài)碼和狀態(tài)碼描述,例如:當(dāng)請求的資源不存在時,會收到“404 NotFound”的頁面,404就是狀態(tài)碼,“NotFound”就是狀態(tài)碼描述,即請求的文件不存在。
二、服務(wù)器實現(xiàn)的基本思路
1、http協(xié)議是基于TCP通信的協(xié)議,因此,實現(xiàn)web服務(wù)器的第一步至少要能實現(xiàn)兩個主機不同進程之間的TCP通信。
2、接下來的部分就是比較主要的處理邏輯了,當(dāng)服務(wù)器收到請求后,首先應(yīng)該分析請求方法(因為web服務(wù)器是要支持cgi的,但請求方法不同處理cgi也不同,這里我們只處理GET和POST方法)。
3、當(dāng)方法確定后,應(yīng)該拿到請求的URL,這一步是為了我們后邊能處理GET和POST方法的cgi(GET和POST的參數(shù)位置不同,GET的參數(shù)在URL中,POST的參數(shù)在請求正文中)
4、判斷資源是否存在,如果存在,判斷這個資源是一個目錄、普通文件還是一個可執(zhí)行程序。之前幾步我們已經(jīng)提取到URL以及參數(shù)。GET方法:如果沒有參數(shù),就直接將請求的資源返回(即進入非cgi模式運行);否則,進入cgi模式內(nèi)部運行;只要是POST方法就需要支持cgi:直接進入cgi函數(shù)內(nèi)部運行。
非cgi模式:
進入非cgi模式時一定是GET方法且沒有參數(shù),此時進入echo_www()函數(shù)內(nèi)部即可,該函數(shù)會將所請求的資源以html的格式返回給瀏覽器。
cgi模式:
上述這張圖描述了運行cgi時的過程,首先服務(wù)器要從瀏覽器上讀取參數(shù),然后需要fork出一個子進程進行cgi部分的處理,父進程通過環(huán)境變量的方式將參數(shù)轉(zhuǎn)交給子進程,子進程運行完成后,將結(jié)果交給父進程,父進程再將數(shù)據(jù)輸出給瀏覽器。在這個過程中可以將父進程看作一個所謂的中間量,只進行了參數(shù)的轉(zhuǎn)交,因此可以將子進程的輸入輸出文件描述符進行重定向,即子進程直接與瀏覽器“聯(lián)系”。
下面總結(jié)出父子進程內(nèi)部各自需要干的事情:
三、錯誤處理
錯誤處理這部分的實現(xiàn)可以參考echo_www()函數(shù),但需要改變響應(yīng)的消息報頭的格式,即改變狀態(tài)碼,狀態(tài)碼描述,以及返回的頁面。例如當(dāng)請求的資源不存在時,服務(wù)器需要返回給瀏覽器一個默認(rèn)的404頁面,告訴客戶請求的資源不存在。效果如圖:
四、項目文件
目錄:
cgi:運行cgi部分的實現(xiàn)代碼
conf:配置文件,存放需要綁定的服務(wù)器的ip和port
log:shell的日志文件以及http錯誤處理的日志文件
lib:mysql需要的lib庫
sql_client:mysql部分的API及CGI實現(xiàn)
wwwroot:web服務(wù)器工作的根目錄,包含各種資源頁面(例如默認(rèn)的index.html頁面,差錯處理的404頁面),以及執(zhí)行cgi的可執(zhí)行程序
文件:
configure.sh:sheel腳本,運行該shell腳本后需要自動生成Makefile文件
http_ctl.sh:服務(wù)器控制腳本,需要實現(xiàn)服務(wù)器的啟動、暫停以及重新啟動
httpd.pid:與http_ctl.sh配合使用。如果把服務(wù)器變成守護進程在后臺運行,重新啟動時就需要檢測服務(wù)器是否啟動,該文件存放服務(wù)器啟動以后的進程id
httpd.h:服務(wù)器的方法聲明
httpd.c:方法實現(xiàn)
main.c:服務(wù)器的主邏輯
五、實現(xiàn)結(jié)果
請求資源存在:
運行cgi后:
六、源碼:
https://github.com/lybb/Linux/tree/master/httpd
附:
這里是我遇到的一些問題,粘出來,也可能是你遇到的問題:
1、本地環(huán)回測試ok,Linux下的瀏覽器測試也可以,但不能接外部的瀏覽器訪問(沒有設(shè)置橋接模式)嗯~要是在外部瀏覽器測試的話千萬別忘記關(guān)閉防火墻
2、服務(wù)器應(yīng)答時,沒有將html格式的頁面發(fā)送,而是將底層的實現(xiàn)代碼展示在瀏覽器,并且在調(diào)試時將本來要打印的調(diào)試信息會打印到網(wǎng)頁上(在回應(yīng)空行時將send期望發(fā)送的數(shù)值寫的太大,本來只需要發(fā)送兩個字節(jié)的內(nèi)容)
解決:先檢查代碼,思路正確,在容易出現(xiàn)問題的地方加入調(diào)試信息,最后將問題定位在echo_www()函數(shù)內(nèi)
3、不能顯示圖片(這個問題是沒有將所有發(fā)送的情況考慮完全,只考慮到目錄、可執(zhí)行程序,但沒有考慮到如果請求的是一個路徑明確的普通文件)
解決:測試請求一個路徑明確的test.html文件,加入調(diào)試信息 ,將問題定位在:如果請求的資源存在,應(yīng)該如何處理。對于普通文件,找到后并回顯給瀏覽器;如果是目錄,應(yīng)答的是默認(rèn)頁面;如果是可執(zhí)行程序,執(zhí)行后返回結(jié)果
4、能顯示圖片后,但顯示的不完整(原因:echo_www中,期望讀取一行信息的line值太小,不能存下一張圖片)
5、運行cgi模式時,每次提交數(shù)據(jù)并進行submit后都會自動出現(xiàn)提醒下載的頁面
原因:在響應(yīng)報頭中,將Content-Type中的”text”寫成”test”。而瀏覽器對于不能識別或解析的實體,都會提醒用戶下載。
到此這篇關(guān)于基于HTTP協(xié)議實現(xiàn)的小型web服務(wù)器的方法的文章就介紹到這了,更多相關(guān)HTTP小型web服務(wù)器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
多核心服務(wù)器和高主頻服務(wù)器怎么選?cpu主頻高和核心多哪個更好?
這篇文章主要介紹了多核心服務(wù)器和高主頻服務(wù)器怎么選?cpu主頻高和核心多哪個更好?,需要的朋友可以參考下2023-07-07github的使用_動力節(jié)點Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了github使用的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-08-08MongoDB學(xué)習(xí)筆記(一) MongoDB介紹與安裝方法
最近開始學(xué)習(xí)非關(guān)系型數(shù)據(jù)庫MongoDB,卻在博客園上找不到比較系統(tǒng)的教程,很多資料都要去查閱英文網(wǎng)站,效率比較低下。本人不才,借著自學(xué)的機會把心得體會都記錄下來,方便感興趣的童鞋分享討論2013-07-07Mac OSX下使用MAMP安裝配置PHP開發(fā)環(huán)境
本部分描述如何在 Mac 上安裝 MAMP。將通過一個操作安裝 Apache Web 服務(wù)器、MySQL 和phpMyAdmin,需要的朋友可以參考下2017-09-09搭建hMailServer服務(wù)實現(xiàn)遠(yuǎn)程發(fā)送郵件的圖文教程
hMailServer是一個郵件服務(wù)器,通過它我們可以搭建自己的郵件服務(wù),本文主要介紹了搭建hMailServer服務(wù)實現(xiàn)遠(yuǎn)程發(fā)送郵件的圖文教程,具有一定的參考價值,感興趣的可以了解一下2023-08-08用rsync實現(xiàn)windows與linux文件同步的方法
windows做為文件服務(wù)器,使用rsync的windows服務(wù)版本,然后配置好就可以了。需要的朋友可以參考下。2011-02-02