三次握手,四次揮手,TCP可靠傳輸的重要保障

TCP是一種面向連接的、可靠的、基於字節流的傳輸層通信協議,在發送數據前,通信雙方必須在彼此間建立一條連接。所謂的“連接”,其實是客戶端和服務端保存的一份關於對方的信息,如ip地址、端口號等。

TCP可以看成是一種字節流,它會處理IP層或以下的層的丟包、重複以及錯誤問題。在連接的建立過程中,雙方需要交換一些連接的參數。這些參數可以放在TCP頭部。

一個TCP連接由一個4元組構成,分別是兩個IP地址和兩個端口號。一個TCP連接通常分為三個階段:連接、數據傳輸、退出(關閉)。通過三次握手建立一個鏈接,通過四次揮手來關閉一個連接。

當一個連接被建立或被終止時,交換的報文段只包含TCP頭部,而沒有數據。

先來了解一下TCP報文的頭部結構。

三次握手,四次揮手,TCP可靠傳輸的重要保障

圖中有幾個字段需要重點介紹下:

(1)序號:seq序號,佔32位,用來標識從TCP源端向目的端發送的字節流,發起方發送數據時對此進行標記。

(2)確認序號:ack序號,佔32位,只有ACK標誌位為1時,確認序號字段才有效,ack=seq+1。

(3)標誌位:共6個,即URG、ACK、PSH、RST、SYN、FIN等,具體含義如下:

ACK:確認序號有效。

FIN:釋放一個連接。

PSH:接收方應該儘快將這個報文交給應用層。

RST:重置連接。

SYN:發起一個新連接。

URG:緊急指針(urgent pointer)有效。

需要注意的是:

  • 不要將確認序號ack與標誌位中的ACK搞混了;
  • 確認方ack=發起方seq+1,兩端配對。

三次握手

三次握手的本質是確認通信雙方收發數據的能力。

首先,我讓信使運輸一份信件給對方,對方收到了,那麼他就知道了我的發件能力和他的收件能力是可以的。

於是他給我回信,我若收到了,我便知我的發件能力和他的收件能力是可以的,並且他的發件能力和我的收件能力是可以。

然而此時他還不知道他的發件能力和我的收件能力到底可不可以,於是我最後回饋一次,他若收到了,他便清楚了他的發件能力和我的收件能力是可以的。

這就是三次握手,這樣說,你理解了嗎?

三次握手,四次揮手,TCP可靠傳輸的重要保障

第一次握手:客戶端要向服務端發起連接請求,首先客戶端隨機生成一個起始序列號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建立了連接。

四次揮手

四次揮手的目的是關閉一個連接。

三次握手,四次揮手,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連接的時間要比客戶端早一些。

至此,完成了TCP的三次握手四次揮手,確保數據傳輸的安全準確。


分享到:


相關文章: