三次握手 四次揮手和TIME WAIT機制

2022-05-03 11:57:27 字數 4212 閱讀 5048

乙個tcp連線的建立是通過三次握手來實現的

1. (a) –> [syn] –> (b)

假如伺服器b和客戶機a通訊. 當a要和b通訊時,a首先向b發乙個syn (synchronize) 標記的包,告訴b請求建立連線.

注意: 乙個 syn包就是僅syn標記設為1的tcp包(參見tcp包頭resources). 認識到這點很重要,只有當b受到a發來的syn包,才可建立連線,除此之外別無他法。

2. (a)

接著,b收到後會發乙個對syn包的確認包(syn/ack)回去,表示對第乙個syn包的確認,並繼續握手操作.

注意: syn/ack包是僅syn 和 ack 標記為1的包.

3. (a) –> [ack] –> (b)

a收到syn/ack 包,a發乙個確認包(ack),通知b連線已建立。至此,三次握手完成,乙個tcp連線完成

注意: 需要注意的是當三此握手完成、連線建立以後,tcp連線的每個包都會設定ack位

握手階段的ack和seq值變化:

對上表的解釋:

1:a向b發起連線請求,以乙個隨機數初始化a的seq,這裡假設為10000,此時ack=0,ack無意義

2:b收到a的連線請求後,也以乙個隨機數初始化b的seq,這裡假設為20000,

意思是:你的請求我已收到,我這方的資料流就從這個數開始。b的ack是a的seq加1,即10000+1=10001

3:a收到b的回覆後,它的seq是它的上個請求的seq加1,即10000+1=10001,

意思也是:你的回覆我收到了,我這方的資料流就從這個數開始。a此時的ack是b的seq加1,即20000+1=20001

三次握手建立連線之後,就開始傳輸資料了

取中間一段的傳輸過程舉例

對上表的解釋:

23:b接收到a發來的seq=40000,ack=70000,size=1518的資料報

24:於是b向a也發乙個資料報,告訴a,你的上個包我收到了。此時b的seq就是它收到的資料報a的ackb的ack是它收到的資料報的seq加上該資料報的大小(不包括:

乙太網協議頭=14位元組,ip頭=20位元組,tcp頭=20位元組),以證實b發過來的資料全收到了。

25:a在收到b發過來的ack為41460的資料報時,一看到41460,正好是它的上個資料報的seq加上包的大小,就明白,上次傳送的資料報已安全到達。

於是它再發乙個資料報給b。此時a正在傳送的資料報的seq就等於它收到的資料報的ack填充,a的ack 就等於它收到的資料報的seq(70000)加上包的size(54)填充,

即ack=70000+54-54(全是頭長,沒資料項)。

為什麼要減去54?

鏈路層使用的是ethernet ii 格式,這個格式有14位元組mac幀首部+4位元組mac幀尾部,還有tcp資料報和ip資料報的首部各20個位元組):

應用資料=size-14-20-20=size-54。(假設ip首部和tcp首部都沒有可選選項)

為什麼不減去mac幀尾部的4位元組呢?

因為在物理層上網絡卡要先去掉前導同步碼和幀開始定界符,然後對幀進行crc檢驗,如果幀校驗和錯,就丟棄此幀。如果校驗和正確,就判斷幀的目 的硬體位址是否符合

自己的接收條件(目的位址是自己的物理硬體位址、廣播位址、可接收的多播硬體位址等),如果符合,就將幀交「裝置驅動程式」做進一步處 理。這時我們的抓包軟體才

能抓到資料,因此,抓包軟體抓到的是去掉前導同步碼、幀開始分界符、fcs之外的資料,

終止字元(fin):值為1表示要傳送的資料報已經傳送完畢,需要釋放傳送連線。

客戶端a沒有要傳送給服務端b的資料了,想要關閉鏈結,則傳送乙個fin=1,ack=1的包,告訴b可以關閉連線了,我沒有什麼資料要給你了。

此時a的狀態由estab-lished變為fin-wait1狀態

2. (a)

然後b會傳送ack=1的包給a,告訴a我知道你沒有什麼想給我的了,但是我還有資料要處理完,你先等下。此時b的狀態由estab-lished變為close-wait

3. (a)

過了一會,服務端處理完資料傳送給客戶端[fin/ack],表明已經處理完資料,最後一次確認是否要準備關閉b->a的通訊連線

4. (a) –> [ack] –> (b)

然後a回應乙個ack,表示確認。b收到這個ack後,就會close。但是a不會直接close,還會進入乙個等待時間狀態time_wait,持續2倍的msl(maximum segment lifetime,報文段在網路上能存活的最大時間,4分鐘)。過了這個狀態,才會close。

a為什麼要等待一段時間,也就是timw-wait的作用?原因有二:

(1)保證tcp的全雙工連線能夠可靠關閉

假如a傳送的最後一次ack丟包了,沒有被b收到,那b超時之後,會再次傳送乙個fin包,然後這個包被處於time_wait狀態的a收到,a會再次傳送乙個ack包,並重新開始計時,一直迴圈這個過程,直到a在time_wait的整個過程中都沒有收到b發過來的fin包,這說明b已經收到了a的ack包並close了,因此a這時候才可以安心close。

如果a沒有time_wait狀態而是直接close,那麼當ack丟包之後,b會再次傳送乙個fin包,但是這個包不會被a回應,因此b最終會收到rst(異常的關閉連線標誌),誤以為是連線錯誤,不符合可靠連線的要求。因此需要等待ack報文到達

(2)保證這次連線的重複資料段從網路中消失

如果a直接close了,然後向b發起了乙個新的tcp連線,可能兩個連線的埠號相同。一般不會有什麼問題,但是如果舊的連線有一些資料堵塞了,沒有達到b呢,新的握手連線就已經到b了,那麼這時候,由於區分不同tcp連線是依據套接字,因此b會將這批遲到的資料認為是新的連線的資料,導致資料混亂(源ip位址和目的ip位址以及源埠號和目的埠號的組合稱為套接字,新舊連線的套接字很有可能相同)

1 需要服務端可靠地終止連線,如果處於time_wait客戶端發給服務端的ack報文丟失,則服務端會再發一次fin,此時客戶端不應該關閉。

2 保證遲來的tcp報文有時間被丟棄,因為2msl裡超時抵達的報文都會被丟棄。

注意:time_wait是主動關閉連線的一方保持的狀態

確認號:

在握手和結束時確認號應該是對方序列號加1,傳輸資料時則是對方序列號加上對方攜帶應用層資料的長度,如果對方攜帶應用層資料長度為0,則ack與對方序列號相同,不要+1,比如25的ack與24的seq相同。也可以這樣理解,因為24沒有傳送資料,所以a期待b下次傳送過來的第乙個位元組的序號不變,因此25的ack與23的ack相同。

序列號:

在握手和結束時序列號應該是上次序列號+1,傳輸資料時則是上次的序列號加上上次應用層資料傳送長度,如果資料長度為0,則seq與上次一樣,不要+1,比如26的seq和24的seq相同。

三次握手和四次揮手

三次握手和四次揮手如圖所示 為什麼是三次握手而不是兩次 因為當客戶端第傳送syn到服務端的時候,如果有幾次請求是因為網路等原因延時等情況的時候,如果沒有第三次握手的確定。服務端就會認為客戶端重寫傳送請求了,就會去開啟連線相應。為什麼關閉連線的時候是四次握手而不是三次?當客戶端傳送請求關閉連線的時候,...

三次握手和四次揮手

tcp三次握手和四次揮手的全過程 tcp是主機對主機層的傳輸控制協議,提供可靠的連線服務,採用三次握手確認建立乙個連線 位碼即tcp標誌位,有6種表示 syn synchronous建立連線 ack acknowledgement 表示響應 確認 psh push表示有data資料傳輸 fin fi...

三次握手和四次揮手

1.在學習tcp協議的時候,總是在強調三次握手,那麼為什麼是三次?而不是兩次或者四次?強迫症表示黑人問號?今天我們就來分析一下為什麼是三次,下圖是一次tcp通訊的時序 在這個例子中,首先客戶端主動發起連線 傳送請求,然後伺服器端響應請求,然後客戶端主動關閉連線。兩條豎線表示通訊的兩端,從上到下表 示...