通過wireshark抓包來講解HTTP中Connection: keep-alive頭部的作用
今天週末時間,有空給大家講解一個小知識點,即HTTP的keep-alive頭部。我使用wireshark來抓取網路包來在實戰中講解。希望能讓大家更容易、更直觀的理解!
HTTP中keep-alive頭部的作用是為保持TCP連線,這樣可以複用TCP連線不需要為每個HTTP請求都建立一個單獨的TCP連線。這樣既可以節省作業系統資源,也能夠保持HTTP請求的高效性。
我們通過wireshark抓的包來分析一下:
下面的例子中128.14.154.105是HTTP伺服器,192.168.1.6是客戶端。
當伺服器處理完一個HTTP請求時,會主動發起斷開連線,如下圖所示(四次揮手):
當伺服器最後傳送一個ACK包後進入TIME_WAIT狀態,此狀態將會持續2MSL(Maximum Segment Lifetime),一個MSL一般為2分鐘,所以TIME_WAIT一般持續4分鐘。在此期間還是可以接受客戶端的資料的。
此時客戶端為了複用TCP連線,將會發送一個心跳包(keep-alive)來保持連線。
上面的例子中,共傳送了2次心跳包。如果在此期間還沒有新的HTTP請求那麼伺服器會再次主動斷開。
此後,客戶端不會再發送心跳包了。
在最後給大家說下,為什麼主動發起斷開連線的一方在傳送最後一個ACK包後需要進入TIME_WAIT狀態2MSL。
1)我們先假設傳送完最後一個ACK包後直接斷開的話,如果由於某種原因對端沒有收到的話,對端會再次傳送一個FIN包(TCP的重傳機制),由於此時另一端已經關閉了對應的socket,所以TCP協議棧會
傳送一個RST包。這個包表示的是一種錯誤。(比如,請求的TCP連線的埠沒有在監聽狀態下),那麼TCP連線就是因錯誤而被迫斷開,所以TCP中工作沒有正常完成。
2)第二個原因是讓老的重複包在網路中消失,解釋一下這句話的意思:如果我們的TCP斷開之後,立馬有一個新的TCP連線和之前的連線的IP和埠都一樣的話,那麼殘留在網路中的包到達後會被誤解為是新的
連線中的包。這樣就會出現問題。如果我們使用了TIME_WAIT,在這個狀態下是不允許建立新的IP和埠都一樣的TCP連線的,而且它會維持2MSL時間, 這足夠讓網路中的舊包消失掉。
最後歡迎大家評論指正!^_^