TCP的三次握手
所謂三次握手 Three-Way Handshake 是指建立一個TCP連接時,需要客戶端和服務端總共發送3個包以確認連接的建立,好比兩個人在打電話:
當連接被建立或被終止,交換的報文段只包含TCP頭部,而沒有資料,
tcp報文頭部結構

-
- 序號:seq序號,占32位,用來標識從TCP源端向目的端發送的位元組流,發起方發送資料時對此進行標記,
-
- 確認序號:ack序號,占32位,只有ACK標志位為1時,確認序號欄位才有效,確認方ack=發起方seq+1,兩端配對,
-
- 標志位
-
ACK:確認序號有效,
-
FIN:釋放一個連接,
-
RST:重置連接,
-
SYN:發起一個新連接,
-
PSH:接收方應該盡快將這個報文交給應用層,
-
URG:緊急指標(urgent pointer)有效,
第一次握手:客戶端要向服務端發起連接請求,首先客戶端隨機生成一個起始序列號ISN(比如是100),那客戶端向服務端發送的報文段包含SYN標志位(也就是SYN=1),序列號seq=100,
第二次握手:服務端收到客戶端發過來的報文后,發現SYN=1,知道這是一個連接請求,于是將客戶端的起始序列號100存起來,并且隨機生成一個服務端的起始序列號(比如是300),然后給客戶端回復一段報文,回復報文包含SYN和ACK標志(也就是SYN=1,ACK=1)、序列號seq=300、確認號ack=101(客戶端發過來的序列號+1),
第三次握手:客戶端收到服務端的回復后發現ACK=1并且ack=101,于是知道服務端已經收到了序列號為100的那段報文;同時發現SYN=1,知道了服務端同意了這次連接,于是就將服務端的序列號300給存下來,然后客戶端再回復一段報文給服務端,報文包含ACK標志位(ACK=1)、ack=301(服務端序列號+1)、seq=101(第一次握手時發送報文是占據一個序列號的,所以這次seq就從101開始,需要注意的是不攜帶資料的ACK報文是不占據序列號的,所以后面第一次正式發送資料時seq還是101),當服務端收到報文后發現ACK=1并且ack=301,就知道客戶端收到序列號為300的報文了,就這樣客戶端和服務端通過TCP建立了連接,

四次揮手
比如客戶端初始化的序列號ISA=100,服務端初始化的序列號ISA=300,TCP連接成功后客戶端總共發送了1000個位元組的資料,服務端在客戶端發FIN報文前總共回復了2000個位元組的資料,
第一次揮手:當客戶端的資料都傳輸完成后,客戶端向服務端發出連接釋放報文(當然資料沒發完時也可以發送連接釋放報文并停止發送資料),釋放連接報文包含FIN標志位(FIN=1)、序列號seq=1101(100+1+1000,其中的1是建立連接時占的一個序列號),需要注意的是客戶端發出FIN報文段后只是不能發資料了,但是還可以正常收資料;另外FIN報文段即使不攜帶資料也要占據一個序列號,
第二次揮手:服務端收到客戶端發的FIN報文后給客戶端回復確認報文,確認報文包含ACK標志位(ACK=1)、確認號ack=1102(客戶端FIN報文序列號1101+1)、序列號seq=2300(300+2000),此時服務端處于關閉等待狀態,而不是立馬給客戶端發FIN報文,這個狀態還要持續一段時間,因為服務端可能還有資料沒發完,
第三次揮手:服務端將最后資料(比如50個位元組)發送完畢后就向客戶端發出連接釋放報文,報文包含FIN和ACK標志位(FIN=1,ACK=1)、確認號和第二次揮手一樣ack=1102、序列號seq=2350(2300+50),
第四次揮手:客戶端收到服務端發的FIN報文后,向服務端發出確認報文,確認報文包含ACK標志位(ACK=1)、確認號ack=2351、序列號seq=1102,注意客戶端發出確認報文后不是立馬釋放TCP連接,而是要經過2MSL(最長報文段壽命的2倍時長)后才釋放TCP連接,而服務端一旦收到客戶端發出的確認報文就會立馬釋放TCP連接,所以服務端結束TCP連接的時間要比客戶端早一些,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/173099.html
標籤:Go
下一篇:Java 中的 6 顆語法糖
