contributed by 傅鈺融、王紹華、陳博聖、黃靜清
原始程式碼: oiz5201618/kernelhttp
當 kernelhttp 已正確啟動,可透過網頁瀏覽器存取該伺服器資源,畫面如下:
gives the address in network byte order
change host byte order to network byte order
Network byte order 其實就是 Big-Endian,因為這個順序與網路類型順序一樣。而 Host Byte Order 指電腦硬體架構所依循的 byte order ,所以會依 CPU 而有所不同。
因此在使用 socket 時,必須注意自己電腦的 IP 跟想要聆聽的 port 必須再同樣的 byte order 之下,也就是 Network Byte Order
參考以下得知背景知識: (均有解說錄影)
這個程式架構是利用 server.c (透過 port 8888) 來聆聽 clients 的 request,當接收到後便將 request 轉發 (forward) 給 url.py (透過 port 9999),當 url.py 處理完並回傳給 server.c ,server.c 在將 response 回應給 clients。
在整體而言,這樣實作的效能是受到質疑的,當我透過 TCP/IP 接收到要求時,再次利用 TCP/IP 來進行「電腦內部的資料交換」,連線的成本是相當高的!(在效能分析可看出其中差異),也因此我們將實作修改成不透過外部,而是在內部處理 request 並回傳 response 給 clients。
修改過程中,我們也將探討 Linux 核心原始碼 workqueue 如何實作。
User space 透過系統呼叫 socket( ) 的實作:
在這個架構中,需要資料複製的成本。
Kernel web server 透過模組直接掛載在 kernel space 之中:
server.c
server.c 是用來定義 server.ko 這個模組行為的實作,因此先要有 Linux 核心模組的認知
參見鳥哥解說
server.c
中在工作排程方面是透過 Linux 核心中 workqueue.h 提供的 API 來實作;連線方面則是透過 net.h 提供的 API 來建立 socket
url.py
url.py
是用來處理 request 並產生相對應的 response,為了能提供適當(符合 request )的 response,裡面定義了一系列的函數去解析及處理 http request 。
產生 response 的方法則是呼叫另一個 python script dealdir
在 current/working directory 中尋找相對應的檔案(html、jpg)作為 response。
由於 server.ko
與 url.py
透過 TCP/IP 連線做為 Linux 核心和 user-space 間的訊息交換機制(listen for server's connection),所以url.py
本身也是個 web server。
server_npy.c
在 server_npy
版本中,我們將 python 處理的部份抽離架構,但這樣我們還要補上處理 request 的部份。
這個部份我們首先使用與 server-framework 相同的處理方式,收到 request 後我們將固定的 response (http header及hello world)回應給 client,如下所示:
另一種處理方式則是觀察 url.py
回傳的 responses ,然後寫死在模組裡要給 client 回應的緩衝區內,這樣也能呈現出上面測試的結果。
可在上圖發現原本架構是讓 clients 透過 port:8888與 server 進行連線,但在處理 requests 上,模組額外建立連線(連線到本機位址的 port:9999)與 url.py
來進行溝通,但額外建立連線是有成本的,因此我們試著將架構修改。
reactor 會再執行一次 srv_cycle_core 時,確認狀態後一次關閉。也因此當有任務完全後,卻要等待其他任務完成才能再次獲得新的 reactor,也因此只要在任務執行結束後將 reactor 做關閉,就可以更加的有效率!
khttpd
的核心內部的 web 伺服器 (in-kernel httpd)。當時 Linux 的效能不夠好,且無法有效利用 SMP 的優勢、thread 的實現還是很拙劣 (不是 NPTL),很多方面沒有達到 POSIX 的高效能指標,因此當時的開發者就鑽進瞭解決性能瓶頸的牛角尖上O(1)
scheduler 和後續的 CFS),又像是 linux-2.6.17 中的 splice 和 tee 系統呼叫,都讓 khttpd
沒有存在的必要