C#中自己動手創建一個Web Server(非Socket實現)


目錄

  • 介紹
  • Web Server在Web架構系統中的作用
  • Web Server與Web網站程序的交互
  • HTTPListener與Socket兩種方式的差異
  • 附帶Demo源碼概述
  • Demo效果截圖
  • 總結

 

介紹

本篇文章主要介紹使用HTTPListener類型自己動手創建一個Web Server,創建的Web Server能夠接收來自瀏覽器端的HTTP請求,並且能夠傳遞給對應的Web站點進行處理,最后將處理結果(Html或者其他格式)返回給瀏覽器。

博主前面曾經介紹過使用Socket模擬Web Server的運行過程、Socket模擬瀏覽器發送HTTP請求過程。分別參見:

本篇文章並沒有使用Socket去實現,而是使用另外一種封裝程度更高、更抽象的System.Net.HTTPListener類型實現。

 

Web ServerWeb架構系統中的作用

Web Server在一個B/S架構系統中起到的作用不僅多而且相當重要,Web開發者大部分時候並不需要了解它的詳細工作機制。雖然不同的Web Server可能功能並不完全一樣,但是以下三個功能幾乎是所有Web Server必須具備的:

  • 接收來自瀏覽器端的HTTP請求
  • 將請求轉發給指定Web站點程序(后者由Web開發者編寫,負責處理請求)
  • 向瀏覽器發送請求處理結果

下圖顯示Web Server在整個Web架構系統中所處的重要位置:

如上圖,Web Server起到了一個“承上啟下”的作用(雖然並沒有“上下”之分),它負責連接用戶和Web站點。

我們可以看到,Web Server默認情況下需要與Web開發者編寫的Web網站程序“通信”(圖中假設三個網站均在一個Web Server上),那么這里怎么處理呢?實時上,任何Web開發者在使用某個平台開發Web程序時,必須遵守某些“規則”,比如使用到某些框架等。遵守了這些規則,開發出來的網站就可以放到Web Server上,這是不是有點像“程序擴展”的意思?

 

Web ServerWeb網站程序的交互

每個網站就像一個個“插件”,只要網站開發過程中遵循了Web Server提出的規則,那么該網站就可以“插”在Web Server上,我們便可以通過瀏覽器訪問網站。

理論上講,每個Web Server均是一個宿主,而每個網站均是一個插件(plug-in)。Web Server主要負責通訊等功能,網站程序主要負責數據處理。

至於“宿主”怎樣與“插件”通信,請參見博主前面的一篇文章“應用程序擴展”。

由於每個Web Server均能持續接收HTTP請求,因此每個Web Server中均應該存在一個類似下圖所示的循環結構:

如上圖,為了提高Web Server接收HTTP請求的效率,圖中虛線框一般采用異步處理,請求處理過程不會影響整個循環。

 

HTTPListenerSocket兩種方式的差異

事實上,HTTP協議是應用層協議。數據在傳輸層上依然是采用TCP進行傳輸的,因此,自己動手采用Socket方式完全能夠模擬出Web Server的工作過程(正如文章開頭講到的)。博主前面有一篇博客講述“使用Socket請求Web Server”,其實就是使用Socket來模擬瀏覽器的通訊行為。在.NET中的System.Net命名空間中,包含一些更高層次、更抽象的類型也可以完成對瀏覽器的模擬,如System.Net.HTTPWebRequest和System.Net.HTTPWebResponse等類型,至於它們和直接使用Socket有什么區別,請參見下表:

分類

Web Server端

瀏覽器端

優點

缺點

Socket方式

Socket.Accept

負責接收瀏覽器端的Socket連接請求

 

Socket.Receive

負責接收瀏覽器發送的數據

 

Socket.Send

負責向瀏覽器發送數據

Socket.Connect

負責向Web Server發送連接請求

 

Socket.Receive

負責接收Web Server發來的回復

 

Socket.Send

負責向Web Server發送請求

更底層,靈活性更強

更底層,需要充分了解HTTP協議、TCP/IP協議

System.Net命名空間中的類型

HTTPListener.GetContext

負責接收瀏覽器端的HTTP請求

 

HTTPListenerRequest

該類負責接收瀏覽器端的請求(Request)數據

 

HTTPListenerResponse

該類負責向瀏覽器發送回復(Response)數據

HTTPWebRequest

該類負責向Web Server發送HTTP請求

 

HTTPWebResponse

該類負責接收來自Web Server發來的回復

更高層級別的抽象,不需要過多的了解HTTP、TCP等通訊知識

更抽象,用法固定(不過需要的都已經包含)

可以看到,以上兩種方式最終達到的效果其實是一樣的。

注:請區分HTTPWebRequest與Asp.NET中的HTTPRequest。后者只能用在Asp.NET中,屬於Asp.NET中的核心對象。同理請區分HTTPWebResponse與Asp.NET中的HTTPResponse。它們的命名空間分別為:System.NET和System.Web

 

附帶Demo源碼概述

源碼包含三個項目,分別為:

  • HTTPServer:模擬的一個Web Server(不足70行代碼)
  • HTTPUtility:一個抽象層,專門為了Web Server與網站程序之間的交互。這里充分應用了“依賴倒置原則(DIP)”,目的就是降低Web Server與網站程序之間的耦合度。
  • MyWebsite:一個(模擬的)網站程序,需要依賴HTTPUtility。

如果將Demo中的三塊與現實一一類比,那么HTTPServer便是IIS/Apache,HTTPUtility便是我們開發Web程序時需要使用到的框架/原則,MyWebsite便是我們開發出來的Web網站程序。

將編譯之后的MyWebsite項目DLL文件拷貝到HTTPServer可執行程序同一目錄下的web文件夾中即可(類似一個網站發布的過程)。打開HTTPServer.exe文件運行,即可在瀏覽器中訪問MyWebsite網站。

源碼中注釋比較詳細,在此就不多說源碼的事情。

 

Demo效果截圖

 

 

總結

兩種方式實現的過程、代碼結構均類似。主要掌握兩點:

  • Web Server中的循環結構(泵),負責持續接收請求
  • Web Server與網站程序(Plug-in)之間的交互

作為一個Web開發者,了解這些幾乎用不到的知識也是必需的。

源碼下載:http://files.cnblogs.com/xiaozhi_5638/HTTP_Web_Server.rar

轉發請保留原文鏈接地址。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM