Socket實現簡單Web伺服器

來源:互聯網
上載者:User

標籤:style   blog   http   color   使用   os   strong   資料   

      上一篇部落格中介紹了怎樣使用socket訪問web伺服器。關鍵有兩個:

1)熟悉Socket編程;

2)熟悉HTTP協議。

上一篇主要是通過socket來類比瀏覽器向(任何)Web伺服器發送(HTTP)請求,重點在瀏覽器端。本篇部落格則反過來講一下怎樣使用socket來實現Web伺服器,怎樣去接收、分析、處理最後回複來自瀏覽器的HTTP請求。

      HTTP協議是瀏覽器和Web伺服器都需要遵守的一種通訊規範,如果我們編寫一個程式,正確遵守了HTTP協議,那麼理論上講,這個程式可以具備瀏覽器、甚至Web伺服器的功能。

圖1

如1所示,Web伺服器和瀏覽器之間無論是發送資料還是接收(解析)資料均遵守了HTTP協議。可以很確定地講,只要我們充分熟悉HTTP協議結構,那麼無論瀏覽器的實現還是Web伺服器的實現,均只是“簡單的”Socket程式的開發過程,除此之外,無其它神秘高深的東西。而Socket程式開發,稍微知道一點socket的有關知識,均能寫得出一個大概demo。

      從系統架構來講,Web架構形式的系統均符合“生產者-消費者”模式(實質上,現實生活中大部分系統均屬於該模式)。瀏覽器端不斷產生資料(請求),而Web伺服器端不斷處理請求,長時間持續如此。

圖2

如2所示,圖中左邊部分為Web伺服器中的“泵”結構,所謂泵,就是指它能夠持續長時間迴圈運作。圖中右邊顯示“來自瀏覽器請求”部分即為“生產者”,生產者不斷髮出請求,由左邊(Web伺服器)不斷進行處理,最後回複給瀏覽器。注意圖2中顯示,Web伺服器中處理資料在迴圈體內部,換句話說,前一次HTTP請求處理結束之前,後一次HTTP請求不能開始,也就是每次請求處理均會阻塞迴圈的執行。這種串列處理資料的方式明顯效率不高,為瞭解決該問題,我們可以在接收到瀏覽器端的HTTP請求後,並不馬上在當前線程中進行處理,而是開闢獨立線程來處理請求(在.NET中可以使用非同步編程實現)。這樣一來,請求處理並不會阻塞當前迴圈過程,見3

圖3

如3所示,接收到請求後,開闢其它線程來處理,這種平行處理資料的方式不會影響後續請求處理。

      如果對Socket編程比較熟悉,以上所說的完全可以輕鬆實現(完全按照Socket編程去做)。現在痛點是,Web伺服器端怎樣解析來自瀏覽器的請求資料(一串字串文本),以及應該以怎樣的格式去回複瀏覽器?答案就是必須充分瞭解HTTP協議格式。上一篇部落格中已經提到過,有關HTTP協議格式請參見http://www.cnblogs.com/riky/archive/2007/04/09/705848.html。我們必須讀懂瀏覽器發送的請求資料,並按照正確格式發送回複。4顯示瀏覽器請求資料格式:

圖4

圖中紅色部分即為資料轉送方式(post或get)、請求路徑(url中不含主機地址部分)以及HTTP協議版本號碼。下面以“鍵:值”格式的文本均為瀏覽器發送給伺服器的一系列資料資訊(注意這些項可選),如果瀏覽器以post方式提交資料,那麼資料會緊跟在下面(圖中沒顯示)。Web伺服器讀懂瀏覽器發送的請求資料,並處理完畢後,必須按照圖5的格式將結果回複給瀏覽器:

圖5

如5所示,最上面的以“鍵:值”的格式文本是Web伺服器發送給瀏覽器的一些資料資訊(這些項部分可選),緊接著,下面便是需要發送給瀏覽器的HTML文檔(如果返回的是頁面)。瀏覽器必須讀懂Web伺服器發送的回複資料,然後進行渲染(顯示)。

圖6

圖6顯示了瀏覽器發起的一次HTTP請求,顯示展示了Web伺服器端處理該請求的過程。我們可以看到,Web伺服器在一次Socket串連過程中只處理一個HTTP請求。多次HTTP請求會伴隨著Socket不斷的串連與斷開。

      文章最後上傳一個使用Socket編寫的簡單Web伺服器,能夠實現以下功能:

1)運行Web伺服器後,可以綁定連接埠,接收來自任何瀏覽器的HTTP請求;

2)能夠顯示一個預設首頁,如index.html;

3)首頁提供“登入”功能,按照Post方式傳遞資料到處理頁面“login.zsp”(尾碼名可自訂);

4)Web伺服器端接收接收瀏覽器發送的資料,能夠解析(解析方式很隨意)出post傳遞的參數,並類比訪問資料庫檢查登入情況、類比耗時等待等;

5)Web伺服器產生登入成功後的靜態頁,回複給瀏覽器。頁面顯示登入名稱和目前時間。

整個demo完全就是一個Socket程式,只是增加了“HTTP協議”的環節,伺服器端無論是接收(解析)資料還是發送資料,均需要遵守HTTP協議。Web伺服器中最終的請求處理泵代碼如下:

 1         static Socket _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  //偵聽socket 2         static void Main(string[] args) 3         { 4             _socket.Bind(new IPEndPoint(IPAddress.Any, 8081)); 5             _socket.Listen(100); 6             _socket.BeginAccept(new AsyncCallback(OnAccept), _socket);  //開始接收來自瀏覽器的http請求(其實是socket串連請求) 7             Console.Read(); 8         } 9         static void OnAccept(IAsyncResult ar)10         {11             try12             {13                 Socket socket = ar.AsyncState as Socket;14                 Socket new_client = socket.EndAccept(ar);  //接收到來自瀏覽器的代理socket15                 //NO.1  平行處理http請求16                 socket.BeginAccept(new AsyncCallback(OnAccept), socket); //開始下一次http請求接收   (此行代碼放在NO.2處時,就是串列處理http請求,前一次處理過程會阻塞下一次請求處理)17 18                 byte[] recv_buffer = new byte[1024 * 640];19                 int real_recv = new_client.Receive(recv_buffer);  //接收瀏覽器的請求資料20                 string recv_request = Encoding.UTF8.GetString(recv_buffer, 0, real_recv);21                 Console.WriteLine(recv_request);  //將請求顯示到介面22 23                 Resolve(recv_request,new_client);  //解析、路由、處理24 25                 //NO.2  串列處理http請求26             }27             catch28             {29 30             }31         }
View Code

注意以上代碼中的NO.1和NO.2處,socket.BeginAccept()方法放在NO.1處時,伺服器端會平行處理請求,而放在NO.2處時,伺服器會串列處理請求。讀者可以每種方式都試一下,在串列處理請求時,請求處理過程會阻塞後續請求的處理(比如登入耗時10秒鐘,其它人無法訪問網站)。

以下是demo:

圖7:Web伺服器運行後,瀏覽器訪問首頁:

圖7

圖8:瀏覽器中首頁顯示(包含登入框):

圖8

圖9:使用者點擊“登入”按鈕,以Post方式提交資料,Web伺服器解析、處理,返回新頁面:

圖9

文章有點長,部分還失真了(部分圖以前整理的,沒有找到大圖,所以就湊合看:))

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.