客戶端與伺服器之間資料的傳送和返回的過程當中需要建立乙個叫tcp connection的東西;
由於tcp不存在連線的概念,只存在請求和響應,請求和響應都是資料報,它們之間都是經過由tcp建立的乙個從客戶端發起,伺服器接收的類似連線的通道,這個連線可以一直保持,http請求是在這個連線的基礎上傳送的;
在乙個tcp連線上是可以傳送多個http請求的,不同的版本這個模式不一樣。
在http/1.0中這個tcp連線是在http請求建立的時候同步建立的,http請求傳送到伺服器端,伺服器端響應了之後,這個tcp連線就關閉了;
http/1.1中可以以某種方式宣告這個連線一直保持,乙個請求傳輸完之後,另乙個請求可以接著傳輸。這樣的好處是:在建立乙個tcp連線的過程中需要「三次握手」的消耗,「三次握手」代表有三次網路傳輸。
如果tcp連線保持,第二個請求傳送就沒有這「三次握手」的消耗。http/2中同乙個tcp連線裡還可以併發地傳輸http請求。
tcp報文格式簡介
其中比較重要的字段有:
(1)序號(sequence number):seq序號,佔32位,用來標識從tcp源端向目的端傳送的位元組流,發起方傳送資料時對此進行標記。
(2)確認號(acknowledgement number):ack序號,佔32位,只有ack標誌位為1時,確認序號欄位才有效,ack=seq+1。
(3)標誌位(flags):共6個,即urg、ack、psh、rst、syn、fin等。具體含義如下:
urg:緊急指標(urgent pointer)有效。ack:確認序號有效。psh:接收方應該盡快將這個報文交給應用層。rst:重置連線。syn:發起乙個新連線。fin:釋放乙個連線。
需要注意的是:
不要將確認序號ack與標誌位中的ack搞混了。確認方ack=發起方seq+1,兩端配對。
tcp的三次握手(three-way handshake)
1.」三次握手」的詳解
所謂的三次握手即tcp連線的建立。這個連線必須是一方主動開啟,另一方被動開啟的。以下為客戶端主動發起連線的**:
握手之前主動開啟連線的客戶端結束closed階段,被動開啟的伺服器端也結束closed階段,並進入listen階段。隨後開始「三次握手」:
(1)首先客戶端向伺服器端傳送一段tcp報文,其中:
標記位為syn,表示「請求建立新連線」;序號為seq=x(x一般為1);隨後客戶端進入syn-sent階段。(2)伺服器端接收到來自客戶端的tcp報文之後,結束listen階段。並返回一段tcp報文,其中:
標誌位為syn和ack,表示「確認客戶端的報文seq序號有效,伺服器能正常接收客戶端傳送的資料,並同意建立新連線」(即告訴客戶端,伺服器收到了你的資料);序號為seq=y;確認號為ack=x+1,表示收到客戶端的序號seq並將其值加1作為自己確認號ack的值;隨後伺服器端進入syn-rcvd階段。(3)客戶端接收到來自伺服器端的確認收到資料的tcp報文之後,明確了從客戶端到伺服器的資料傳輸是正常的,結束syn-sent階段。並返回最後一段tcp報文。其中:
標誌位為ack,表示「確認收到伺服器端同意連線的訊號」(即告訴伺服器,我知道你收到我發的資料了);序號為seq=x+1,表示收到伺服器端的確認號ack,並將其值作為自己的序號值;確認號為ack=y+1,表示收到伺服器端序號seq,並將其值加1作為自己的確認號ack的值;隨後客戶端進入established階段。伺服器收到來自客戶端的「確認收到伺服器資料」的tcp報文之後,明確了從伺服器到客戶端的資料傳輸是正常的。結束syn-sent階段,進入established階段。
在客戶端與伺服器端傳輸的tcp報文中,雙方的確認號ack和序號seq的值,都是在彼此ack和seq值的基礎上進行計算的,這樣做保證了tcp報文傳輸的連貫性。一旦出現某一方發出的tcp報文丟失,便無法繼續"握手",以此確保了"三次握手"的順利完成。
此後客戶端和伺服器端進行正常的資料傳輸。這就是「三次握手」的過程。
2.「三次握手」的動態過程
3.「三次握手」的通俗理解
舉個栗子:把客戶端比作男孩,伺服器比作女孩。用他們的交往來說明「三次握手」過程:
(1)男孩喜歡女孩,於是寫了一封信告訴女孩:我愛你,請和我交往吧!;寫完信之後,男孩焦急地等待,因為不知道信能否順利傳達給女孩。
(2)女孩收到男孩的情書後,心花怒放,原來我們是兩情相悅呀!於是給男孩寫了一封回信:我收到你的情書了,也明白了你的心意,其實,我也喜歡你!我願意和你交往!;
寫完信之後,女孩也焦急地等待,因為不知道回信能否能順利傳達給男孩。
(3)男孩收到回信之後很開心,因為發出的情書女孩收到了,並且從回信中知道了女孩喜歡自己,並且願意和自己交往。然後男孩又寫了一封信告訴女孩:你的心意和信我都收到了,謝謝你,還有我愛你!
女孩收到男孩的回信之後,也很開心,因為發出的情書男孩收到了。由此男孩女孩雙方都知道了彼此的心意,之後就快樂地交流起來了~~
這就是通俗版的「三次握手」,期間一共往來了三封信也就是「三次握手」,以此確認兩個方向上的資料傳輸通道是否正常。
4.為什麼要進行第三次握手?
為了防止伺服器端開啟一些無用的連線增加伺服器開銷以及防止已失效的連線請求報文段突然又傳送到了服務端,因而產生錯誤。
由於網路傳輸是有延時的(要通過網路光纖和各種中間**伺服器),在傳輸的過程中,比如客戶端發起了syn=1建立連線的請求(第一次握手)。
如果伺服器端就直接建立了這個連線並返回包含syn、ack和seq等內容的資料報給客戶端,這個資料報因為網路傳輸的原因丟失了,丟失之後客戶端就一直沒有接收到伺服器返回的資料報。
客戶端可能設定了乙個超時時間,時間到了就關閉了連線建立的請求。再重新發出建立連線的請求,而伺服器端是不知道的,如果沒有第三次握手告訴伺服器端客戶端收的到伺服器端傳輸的資料的話,
伺服器端是不知道客戶端有沒有接收到伺服器端返回的資訊的。
這個過程可理解為:
這樣沒有給伺服器端乙個建立還是關閉連線埠的請求,伺服器端的埠就一直開著,等到客戶端因超時重新發出請求時,伺服器就會重新開啟乙個埠連線。那麼伺服器端上沒有接收到請求資料的上乙個埠就一直開著,長此以往,這樣的埠多了,就會造成伺服器端開銷的嚴重浪費。
還有一種情況是已經失效的客戶端發出的請求資訊,由於某種原因傳輸到了伺服器端,伺服器端以為是客戶端發出的有效請求,接收後產生錯誤。
所以我們需要「第三次握手」來確認這個過程,讓客戶端和伺服器端能夠及時地察覺到因為網路等一些問題導致的連線建立失敗,這樣伺服器端的埠就可以關閉了不用一直等待。
也可以這樣理解:「第三次握手」是客戶端向伺服器端傳送資料,這個資料就是要告訴伺服器,客戶端有沒有收到伺服器「第二次握手」時傳過去的資料。若傳送的這個資料是「收到了」的資訊,接收後伺服器就正常建立tcp連線,否則建立tcp連線失敗,伺服器關閉連線埠。由此減少伺服器開銷和接收到失效請求發生的錯誤。
5.抓包驗證
下面是用抓包工具抓到的一些資料報,可用來分析tcp的三次握手:
圖中顯示的就是完整的tcp連線的」三次握手」過程。在52528 -> 80中,52528是本地(客戶端)埠,80是伺服器的埠。80埠和52528埠之間的三次來回就是"三次握手"過程。
注意到」第一次握手」客戶端傳送的tcp報文中以[syn]作為標誌位,並且客戶端序號seq=0;
接下來」第二次握手」伺服器返回的tcp報文中以[syn,ack]作為標誌位;並且伺服器端序號seq=0;確認號ack=1(「第一次握手」中客戶端序號seq的值+1);
最後」第三次握手」客戶端再向伺服器端傳送的tcp報文中以[ack]作為標誌位;
其中客戶端序號seq=1(「第二次握手」中伺服器端確認號ack的值);確認號ack=1(「第二次握手」中伺服器端序號seq的值+1)。
這就完成了」三次握手」的過程,符合前面分析的結果。
總結1.客戶端傳送請求到服務端,服務端知道客戶端傳送正常,自己接受正常
ack=1 seq=x
2.伺服器發給客戶端,客戶端知道自己傳送接受正常,服務端傳送接受正常。
ack=1 ack=x+1 syn=1 seq=y
3.客戶端發給服務端,服務端知道客戶端髮型接受正常,自己傳送接受正常
seq=x+1 ack=1 ack=y+1
計算機網路(四),TCP三次握手
1.三次握手詳情 2.為什麼需要三次握手才能建立連線 3.首次握手的隱患 syn超時的問題 4.建立連線之後,client出現故障 1 一開始,客戶端和伺服器端都處於關閉狀態 closed 然後開啟服務,服務端這個時候處於監聽狀態 listen 2 客戶端傳送乙個連線請求報文,裡面syn等於1,se...
計算機網路 三次握手
假設a為客戶端,b為服務端。首先b處於listen 監聽 狀態,等待客戶的連線請求。a向b傳送連線請求報文,syn 1,ack 0 選擇乙個初始的序號x b收到連線請求,如果同意建立連線,則向a傳送連線確認報文,syn 1,ack 1 確認號為1,同時也選擇乙個初始的序號y。a收到b的連線確認序號後...
計算機網路 26 TCP三次握手
三次握手 three way handshake 其實就是指建立乙個tcp連線時,需要客戶端和伺服器總共傳送3個包。進行三次握手的主要作用就是為了確認雙方的接收能力和傳送能力是否正常 指定自己的初始化序列號為後面的可靠性傳送做準備。實質上其實就是連線伺服器指定埠,建立tcp連線,並同步連線雙方的序列...