天天看點

詳談socket請求Web伺服器過程(轉)

最開始我們需要明白一件事情,因為這是這篇文章的前提:

HTTP協定隻是一個應用層協定,它底層是通過TCP進行傳輸資料的。是以,浏覽器通路Web伺服器的過程必須先有“連接配接建立”的發生。

而有人或許會問:衆所周知,HTTP協定有兩大特性,一個是“無連接配接”性,一個是“無狀态”性。這裡的“無連接配接”豈不是跟上面的說法有沖突?其實這裡并沒有沖突,隻是人們對“連接配接”這個詞的了解有差異。首先我們來看一下浏覽器向Web伺服器發出Http請求以及Web伺服器給浏覽器回複的過程:

1)浏覽器建立Socket,按給定IP(域名)和端口(預設為80)連接配接伺服器。比如使用類似Socket.Connect()、Socket.BeginConnect()等方法;

3)浏覽器等待伺服器處理并傳回資料;

4)Web伺服器端使用Socket.Accept()、Socket.BeginAccept()等方法偵聽到浏覽器的連接配接後,便開始接收浏覽器發送的資料。接收到請求資料後,依據HTTP協定規範解析資料,然後處理,最終将處理結果(如html文檔)發回給浏覽器,這裡可能用到類似Socket.Send()、Socket.BeginSend()等方法;

5)Web伺服器發送完處理結果後,關閉Socket;

6)浏覽器接收Web伺服器發回的資料(如html),将其顯示在浏覽器UI界面。關閉socket;

7)一次“浏覽器到Web伺服器”的http請求結束;

8)下一次浏覽器需要請求Web伺服器,跳轉到第1)步循環開始。

用圖表示以上過程:

詳談socket請求Web伺服器過程(轉)

圖1

如上圖1所示。浏覽器向Web伺服器發送http請求之前,需要先建立連接配接。沒錯,它們間建立連接配接的過程跟我們平時開發socket程式類似。由此可知,HTTP協定的“無連接配接”特性并不是指:浏覽器與Web伺服器進行資料交換時,不需要建立連接配接。那麼“無連接配接”特性到底指什麼呢?我們再看圖1會發現,浏覽器每次請求完畢後都會與伺服器處于“斷開”狀态,下一次請求時再重新與伺服器建立連接配接。HTTP的無連接配接特性恰恰就是指浏覽器的每次請求都必須重新與伺服器建立連接配接,正常情況下,浏覽器不會與Web伺服器保持長時間的連接配接狀态。現将HTTP協定的兩大特性歸結如下:

無連接配接:

伺服器與浏覽器之間的一次連接配接隻處理一個http請求,請求處理結束後,連接配接斷開。下一次請求再重建立立連接配接。

無狀态:

伺服器不會儲存浏覽器資訊。也就是說,在伺服器端,第一次http請求處理的結果不會保留到第二次請求。如果第二次請求處理時,需要用到第一次請求處理的結果,浏覽器在第二次請求時,必須将第一次處理結果重新傳回給Web伺服器(比如使用cookie)。

關于“協定”:

       這個話題有點大,不是我能掌控得了的。不過對于今天這篇文章,我還是盡最大可能說一點。計算機中協定範疇廣泛,單就網絡通信中的協定,就不計其數,OSI七層中每層都很多種協定。那麼協定到底本質上是個什麼東西呢?單就通信中的協定來講,協定的本質其實就是一種資料結構,類似代碼中的結構體,說得再底層一點,就是一個位元組流,規定好了第一個位元組代表什麼、第二個位元組代表什麼等等。

      協定的作用跟我們平時所說的“契約”、“約定”類似,一個團隊合作的任務,合作各方必須同時遵守事先的約定,最後工作才能正常進行下去。網絡通信中也一樣,通信雙方收/發資料時必須按照實作規定好了的結構去發送/接收,一方不遵守該規範,通信就不能成功。這裡說的結構規範其實就是“協定”。協定有以下作用:

1)既然是規範,那麼按照規範做事,自己做的别人更容易了解,便于交流;

2)将規範寫成文檔,提供給其他人,友善後期他人擴充。因為隻要知道了通信規範,那麼很容易就可以編寫出擴充子產品與原有系統協調工作。

3)計算機網絡通信中,有些因素決定了我們必須按照規定的格式收發資料,比如TCP通信中,由于資料是按照“流”式傳輸的,如果我們事先不定義資料傳輸規範,那麼很難判斷TCP傳輸的資料邊界。

就網絡通信協定來講,應用層協定與我們程式開發最為密切(至少對我們使用c#、java的人來講),其他向tcp、udp等傳輸層協定幾乎用不到。我們開發的通信程式,必須遵守實作定義好了的應用層協定,比如浏覽器和Web伺服器都遵守了HTTP應用層協定,隻有這樣,它們才能正常互動。倘若我們自己開發一個程式,正确地遵守了HTTP協定,那麼我們的程式也能夠像chrome、IE等浏覽器一樣,去通路Web伺服器。

     文章末尾有一個使用socket模拟浏覽器請求Web伺服器的demo,實作的功能我們完全可以使用類似WebClient、WebRequest等類型去實作。demo功能如下:

1)使用Socket連接配接Web伺服器(任意);

2)按照HTTP協定格式發送HTTP請求(使用Socket.Send方法);

3)按照HTTP協定格式解析Web伺服器傳回的資料(其實就顯示在了UI界面)

(開發這樣的程式需要我們充分熟悉socket程式設計、HTTP協定格式)

以下是發送HTTP請求的代碼:

詳談socket請求Web伺服器過程(轉)
詳談socket請求Web伺服器過程(轉)

主程式:

詳談socket請求Web伺服器過程(轉)
詳談socket請求Web伺服器過程(轉)
詳談socket請求Web伺服器過程(轉)

 Demo下載下傳:

<a href="http://www.cnblogs.com/visec479/p/3972728.html">http://www.cnblogs.com/visec479/p/3972728.html</a>