網絡基礎②-TCP 三次握手與四次揮手

TCP三次握手:

注意:這裏客戶端和服務端並不是常認爲身份定義,誰發出請求誰就是客戶端

(1)第一次握手:Client將標誌位SYN置爲1,隨機產生一個值seq=x,並將該數據包發送給Server,Client進入SYN_SENT狀態,等待Server確認。

 (2)第二次握手:Server收到數據包後由標誌位SYN=1知道Client請求建立連接,Server將標誌位SYN和ACK都置爲1,ack (number )=x+1,隨機產生一個值seq=y,並將該數據包發送給Client以確認連接請求,Server進入SYN_RCVD狀態。

(3)第三次握手:Client收到確認後,檢查ack是否爲x+1,ACK是否爲1,如果正確則將標誌位ACK置爲1,ack=y+1,並將該數據包發送給Server,Server檢查ack是否爲y+1,ACK是否爲1,如果正確則連接建立成功,Client和Server進入ESTABLISHED狀態,完成三次握手,隨後Client與Server之間可以開始傳輸數據了。

爲什麼不能用兩次握手進行連接?
        我們知道。3次握手完畢兩個重要的功能。既要兩方做好發送數據的準備工作(兩方都知道彼此已準備好),也要同意兩方就初始序列號進行協商,這個序列號在握手過程中被髮送和確認。

       如今把三次握手改成僅須要兩次握手。死鎖是可能發生的。現在,考慮計算機S和C之間的通信,假定C給S發送一個連接請求分組,S收到了這個分組,併發送了確認應答分組。依照兩次握手的協定,S覺得連接已經成功地建立了,能夠開始發送數據分組。但是,C在S的應答分組在傳輸中被丟失的情況下,將不知道S是否已準備好。不知道S建立什麼樣的序列號。C甚至懷疑S是否收到自己的連接請求分組。在這樣的情況下,C覺得連接還未建立成功,將忽略S發來的不論什麼數據分組,僅僅等待連接確認應答分組。而S在發出的分組超時後,反覆發送相同的分組。這樣就形成了死鎖。

TCP四次揮手:

 

 

       由於TCP連接時全雙工的,因此,每個方向都必須要單獨進行關閉,這一原則是當一方完成數據發送任務後,發送一個FIN來終止這一方向的連接,收到一個FIN只是意味着這一方向上沒有數據流動了,即不會再收到數據了,但是在這個TCP連接上仍然能夠發送數據,直到這一方向也發送了FIN。首先進行關閉的一方將執行主動關閉,而另一方則執行被動關閉,上圖描述的即是如此。

 (1)第一次揮手:Client發送一個FIN,用來關閉Client到Server的數據傳送,Client進入FIN_WAIT_1狀態。

  (2)第二次揮手:Server收到FIN後,發送一個ACK給Client,確認序號爲收到序號+1(與SYN相同,一個FIN佔用一個序號),Server進入CLOSE_WAIT狀態。

 (3)第三次揮手:Server發送一個FIN,用來關閉Server到Client的數據傳送,Server進入LAST_ACK狀態。

  (4)第四次揮手:Client收到FIN後,Client進入TIME_WAIT狀態,接着發送一個ACK給Server,確認序號爲收到序號+1,Server進入CLOSED狀態,完成四次揮手。

爲什麼建立連接協議是三次握手,而關閉連接卻是四次握手呢?

        這是因爲服務端的LISTEN狀態下的SOCKET當收到SYN報文的連接請求後,它可以把ACK和SYN(ACK起應答作用,而SYN起同步作用)放在一個報文裏來發送。但關閉連接時,當收到對方的FIN報文通知時,它僅僅表示對方沒有數據發送給你了;但未必你所有的數據都全部發送給對方了,所以你可能未必會馬上會關閉SOCKET,也即你可能還需要發送一些數據給對方之後,再發送FIN報文給對方來表示你同意現在可以關閉連接了,所以它這裏的ACK報文和FIN報文多數情況下都是分開發送的。

參考:https://www.cnblogs.com/cxt-janson/p/10904503.html 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章