在使用TCP協議進行資料的傳輸之前,客戶端與服務器端需要建立TCP Connection,即建立連接,之后兩端才能進行資料的傳輸,
下面堆TCP連接“三次握手”的程序進行說明,
1、相關概念
首先,我們需要了解TCP資料報的首部的結構(TCP資料報包括首部以及資料報部分),如下圖:

其中需要注意的欄位有:
(1)序號(sequence number):seq序號,占32位4個位元組,從TCP源端向目的端發送的位元組流資料,發起方發送資料報文時對每一個位元組進行編號標記,每一個位元組都會有一個編號(0 到 232-1),給報文每個位元組編上序號后,需要給報文指派一個序號seq,報文資料段的第一個位元組的編號值,就是這段報文TCP首部序號seq的值,
(2)確認號(acknowledgement number):ack序號,占32位4個位元組,表示期待收到對方下一個報文段的序號,那么第一次收到的報文段最后一個位元組的編號+1即為確認號,比如第一段報文seq=1(報文第一個位元組編號1),報文長度是100,即報文最后一個位元組編號為100,確認端接收到發起端發送的報文后,回傳給發起端的回應TCP報文中,ACK=1,ack=101,表示發起端發送的1-100編號的位元組資料已經收到,希望發起端下一個報文從101編號的位元組開始發送,
注意,只有TCP報文的ACK標志位為1時,這個報文中的確認序號欄位才有效,
(3)標志位(Flags):TCP標志物有6位,具體如下圖

i)確認ACK:占1位,僅當ACK=1時,確認號欄位才有效;ACK=0時,確認號無效 ,
ii)同步SYN:用于建立連接的同步標記,當SYN=1,ACK=0時表示這是一個連接請求報文段,若同意連接,則在回應報文段中使得SYN=1,ACK=1,因此,SYN=1表示這是一個連接請求報文,
iii)終止FIN:用來釋放一個連接,FIN=1表示此報文段的客戶端的資料已經發送完畢,并要求釋放連接,
這里需要注意2點:
1)不要混淆ACK標志位與ack確認號;
2)SYN這個標志位只有在TCP創建連接時才會被置1,握手完成后SYN標志位被置0,
2、三次握手程序
程序如下圖:

注意,此處所謂的“客戶端”與“服務器端”,只是為了方便標識連接的雙方,即確認哪一方是“要求斷開連接”的主動方,哪一方是“要求斷開連接”的被動方,事實上任何一方都可能要求建立連接,
步驟如下:
1)首先客戶端向服務器端發送一段TCP報文,其中:
i)標記位為SYN=1,表示“請求建立新連接”;
ii)序號為 seq = x,表示客戶端發送給服務器端的資料報文的序號是 x ,即資料報文的第一個位元組的編號為 x,注意,建立連接的SYN報文雖然沒有資料,但是會占用一個序號的大小;
iii)此時,客戶端進入 SYNC-SENT 狀態:同步已發送狀態,
2)服務器端接收到來自客戶端 TCP 報文之后,回傳一段TCP報文,其中:
i)標志位為 SYN 和 ACK ,ACK=1 是確認標志,表示 “確認客戶端的報文seq序號有效,服務器端能正常接收客戶端發送的資料,即告訴客戶端,服務器端收到了它的請求報文”,SYN=1 是請求連接標志,表示“服務器端同意創建新連接”,ACK與SYN 合起來,就是告訴客戶端,服務器端 收到了你的資料,同意與你建立連接;
ii)ack=x+1,表示希望客戶端下一次發送回來的資料報序號是 x+1;
iii)seq = y,服務器端向客戶端發送自己的資料報,序號是 y,
iv)同時,服務器端結束 LISTEN 監聽階段,進入 SYNC-RCVD 同步已接收狀態,
3)客戶端接收到來自服務器端的確認收到資料的TCP報文之后,明確了從客戶端到服務器端的資料傳輸是正常的,可以建立連接,回傳一段TCP報文,其中:
i)標志位為ACK,表示 “確認收到服務器端同意連接的信號”(即告訴服務器端,我知道你收到我發的資料了);
ii)seq=x+1,表示向服務器端發送序號為x+1的資料,根據第二次握手的 ack=x+1,將seq設定為 x+1;
iii)ack=y+1,表示希望服務器端下一次發送回來的資料報序號為y+1,
iv)隨后它會進入 ESTABLISHED 建立連接階段,
4)服務器端在接收到客戶端發送的第三次握手的資料后,也會進入 ESTABLISHED 建立連接階段,
在“三次握手”中,通過第一、第二次握手的SYN,客戶端與服務器端建立連接;而且通過第二、第三次握手的ACK,雙方都確認對方已經收到自己的報文,客戶端與服務器端的 ack 與 seq 的值,都是在對方 ack 與 seq 值的基礎上計算的,即通過“三次握手”,客戶端與服務器端也同步了各自的序號與確認號,這樣做保證了TCP報文的連貫性,一旦有一方的報文丟失,另一方便無法正確“握手”(因為想正確握手,發出的 seq 需要與對方發來的 ack 相同),
3、為什么要進行“三次握手”才能建立TCP連接
原因:避免已經失效的連接請求報文傳送到服務器端,導致服務器端開啟一些無效的連接,增加服務器端開銷,
分析如下圖:

如果是三次握手,就可以避免上面這種情況的發生,如下圖:

4、擴展
在客戶端與服務器端建立連接之后,在這個連接上,客戶端與服務器端之間可以發送的HTTP請求數量與使用的HTTP協議的版本相關,
1)HTTP1.0版本:TCP連接是在HTTP請求創建的時候同步創建的,HTTP請求發送到服務器端,服務器端回應了之后,這個TCP連接就關閉了,即一次連接只能發送一次HTTP請求;
2)HTTP1.1版本:三次握手建立TCP連接后,以某種方式宣告這個連接一直保持,后面的HTTP請求可以繼續使用這個連接,
由于在創建一個TCP連接的程序中需要“三次握手”的性能消耗,如果每次HTTP請求都要重新建立TCP連接,那么每次HTTP請求都有“三次握手”的性能消耗,如果使用HTTP1.1,只有第一次請求需要建立連接,后面的請求不需要建立連接,則只有一次“三次握手”的消耗,
“四次揮手”請參考文章:https://i.cnblogs.com/posts/edit;postId=13067989
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/5096.html
標籤:其他
上一篇:資訊收集---1
