一直不是非常理解.NET中HttpWebRequest的KeepAlive屬性有何用處,看了這篇文章就清楚了!
http://www.cnblogs.com/lwzz/archive/2011/08/15/2139937.html
摘錄如下:
有人也許會問,Http不是基於TCP/IP的嗎?而這個是可以保持狀態的。怎么Http就是無狀態了的呢?搞清楚這個問題,對以后我們WCF中選擇協議也有幫助。
Http是屬於最高層的應用協議,基於TCP/IP,也就是說它在TCP/IP的基礎上引入了新的概念和規定。因此,無狀態是Http規定的,是為了適應Web的要求而規定的。Web應用經常面對大量的訪問,如果都保持TCP的連接狀態那么將會消耗大量的資源。就會演變成了類似“客戶端/服務端”一對一模型。因此,Http規定了它是無狀態的,也就是說,處理完一個請求並返回以后,服務器端就要直接關閉掉TCP連接,不管相同的客戶端是否再次發送請求。以這樣的形式來實現單向的Request/response模式的。
上面我說的是Http 1.0 的規定。用圖來表示就是:
注意,服務端關閉連接這個動作不可少。這樣才是無狀態。也就是說HTTP 1.0的協議的無狀態是由這4個步驟組成,缺一不可。一個連接請求就在一次處理后關閉。
看到這里如果對瀏覽器有些了解的人就會知道,其實這個模型並不高效。在當初網頁主要是HTML文本的時候還可以,但是現在一個的網頁里都包含了非常多的諸如img,javascript,css等元素,這使得瀏覽器在解析由服務器發回的HTML網頁以后,如果解析HTML時發現了上面這些元素的標簽,那么還要多次的發起連接請求。而每次建立連接請求都需要三次握手,比較耗資源。因此,HTTP 1.0對於現在的網頁來說並不很適合。
瀏覽器生成一個完整的頁面,一共發送了N+1條請求。1就是指返回的HTML網頁字符串,N是其中包含的資源,由瀏覽器解析HTML標簽后發出。
如圖:
這個問題應該怎么解決呢?要是能夠在一條已建立的連接上,多處理幾次資源請求就好了。也就是連接能夠復用,更直接了當的說就是當服務器處理完一條資源請求時,不要像1.0那樣馬上關閉連接,而是等一段時間。
持久連接
在1.0+(1.0的各種修正版本)以及1.1中,允許HTTP設備在事務處理結束以后仍然將TCP保持在打開的狀態,以便為未來的HTTP請求重用現存的連接。在事務處理結束以后仍然保持打開的連接我們就叫做“持久連接”,持久連接在1.0+和1.1中是通過不同方式確定的:
- HTTP 1.0中通過首部插入keep-alive信息表明是持久連接
- HTTP 1.1中默認是持久連接
下面來介紹一下這兩種方式
1.keep-alive
客戶端 :實現HTTP/1.0 keep-alive連接的客戶端可以通過包含connection:Keep-Alive首部請求將一條連接保持在打開狀態。
服務器端:如果服務器端願意將一條連接保持在打開狀態,那么就在響應頭部中同樣插入connection:Keep-Alive ,否則表達的意思就是我響應你這條信息后我就要把TCP連接給關閉掉。
HTTP 1.0 中keep-alive不是默認采用的,也就是說如果你不主動的往頭部加入這個信息,那么就意味着是一次HTTP請求就會打開關閉一次TCP連接。客戶端通過檢查服務器端的響應有沒有connection:Keep-Alive,就可以知道服務器發出響應以后是否會關閉連接了。
2.和keep-alive正好相反,在HTTP1.1中持久連接默認是激活的,除非你發送了Connection:close表明可以關閉連接。HTTP1.1客戶端假定在收到響應之后,除非響應中包含了Conncetion:close,否則HTTP/1.1的連接就仍然維持在打開的狀態。
因此,這時服務器對於關閉TCP連接就會采用兩種方式,一種是當收到瀏覽器發送的關閉連接請求后關閉該TCP請求(意味着瀏覽器已經把該網頁所需的請求資源已經拿完了,無需再從這條連接里獲取其他資源),另一種就是當經過一段時間后,就算瀏覽器沒有發送關閉連接的請求,服務端也會因為超時而自動關閉該條TCP連接。
因此我們知道為什么我們的HTTP請求中還包含了HTTP的版本信息,因為這會影響到雙發對於關閉請求的理解。
當然HTTP 1.1除了這條改進之外,還增加了諸如PUT,DELETE等動作。在接下來講REST的文章的時候會講到。