什麼是三次握手和四次握手

1. 三次握手

1.1 什麼是三次握手 (three-way handshake)?

在這裏插入圖片描述

  • 第一次握手:Client將SYN置1,隨機產生一個初始序列號seq發送給Server,進入SYN_SENT狀態;
  • 第二次握手:Server收到Client的SYN=1之後,知道客戶端請求建立連接,將自己的SYN置1,ACK置1,產生一個acknowledge number=sequence number+1,並隨機產生一個自己的初始序列號,發送給客戶端;進入SYN_RCVD狀態;
  • 第三次握手:客戶端檢查acknowledge number是否爲序列號+1,ACK是否爲1,檢查正確之後將自己的ACK置爲1,產生一個acknowledge number=服務器發的序列號+1,發送給服務器;進入ESTABLISHED狀態;服務器檢查ACK爲1和acknowledge number爲序列號+1之後,也進入ESTABLISHED狀態;完成三次握手,連接建立。

1.2 TCP建立連接可以兩次握手嗎?爲什麼?

不可以。有兩個原因:

  • 首先,可能會出現已失效的連接請求報文段又傳到了服務器端。
    client 發出的第一個連接請求報文段並沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以後的某個時間纔到達 server。本來這是一個早已失效的報文段。但 server 收到此失效的連接請求報文段後,就誤認爲是 client 再次發出的一個新的連接請求。於是就向 client 發出確認報文段,同意建立連接。假設不採用 “三次握手”,那麼只要 server 發出確認,新的連接就建立了。由於現在 client 並沒有發出建立連接的請求,因此不會理睬 server 的確認,也不會向 server 發送數據。但 server 卻以爲新的運輸連接已經建立,並一直等待 client 發來數據。這樣,server 的很多資源就白白浪費掉了。採用 “三次握手” 的辦法可以防止上述現象發生。例如剛纔那種情況,client 不會向 server 的確認發出確認。server 由於收不到確認,就知道 client 並沒有要求建立連接。
  • 其次,兩次握手無法保證Client正確接收第二次握手的報文(Server無法確認Client是否收到),也無法保證Client和Server之間成功互換初始序列號。

1.3 可以採用四次握手嗎?爲什麼?

可以。但是會降低傳輸的效率。

四次握手是指:第二次握手:Server只發送ACK和acknowledge number;而Server的SYN和初始序列號在第三次握手時發送;原來協議中的第三次握手變爲第四次握手。出於優化目的,四次握手中的二、三可以合併。

1.4 第三次握手中,如果客戶端的ACK未送達服務器,會怎樣?

Server端:
由於Server沒有收到ACK確認,因此會重發之前的SYN+ACK(默認重發五次,之後自動關閉連接進入CLOSED狀態),Client收到後會重新傳ACK給Server。

Client端,兩種情況:

  • 在Server進行超時重發的過程中,如果Client向服務器發送數據,數據頭部的ACK是爲1的,所以服務器收到數據之後會讀取 ACK number,進入 establish 狀態
  • 在Server進入CLOSED狀態之後,如果Client向服務器發送數據,服務器會以RST包應答。

1.5 如果已經建立了連接,但客戶端出現了故障怎麼辦?

服務器每收到一次客戶端的請求後都會重新復位一個計時器,時間通常是設置爲2小時,若兩小時還沒有收到客戶端的任何數據,服務器就會發送一個探測報文段,以後每隔75秒鐘發送一次。若一連發送10個探測報文仍然沒反應,服務器就認爲客戶端出了故障,接着就關閉連接。

1.6 初始序列號是什麼?

TCP連接的一方A,隨機選擇一個32位的序列號(Sequence Number)作爲發送數據的初始序列號(Initial Sequence Number,ISN),比如爲1000,以該序列號爲原點,對要傳送的數據進行編號:1001、1002…三次握手時,把這個初始序列號傳送給另一方B,以便在傳輸數據時,B可以確認什麼樣的數據編號是合法的;同時在進行數據傳輸時,A還可以確認B收到的每一個字節,如果A收到了B的確認編號(acknowledge number)是2001,就說明編號爲1001-2000的數據已經被B成功接受。

2. 四次揮手

2.1 什麼是四次揮手?

在這裏插入圖片描述

  • 第一次揮手:Client將FIN置爲1,發送一個序列號seq給Server;進入FIN_WAIT_1狀態;
  • 第二次揮手:Server收到FIN之後,發送一個ACK=1,acknowledge number=收到的序列號+1;進入CLOSE_WAIT狀態。此時客戶端已經沒有要發送的數據了,但仍可以接受服務器發來的數據。
  • 第三次揮手:Server將FIN置1,發送一個序列號給Client;進入LAST_ACK狀態;
  • 第四次揮手:Client收到服務器的FIN後,進入TIME_WAIT狀態;接着將ACK置1,發送一個acknowledge number=序列號+1給服務器;服務器收到後,確認acknowledge number後,變爲CLOSED狀態,不再向客戶端發送數據。客戶端等待2*MSL(報文段最長壽命)時間後,也進入CLOSED狀態。完成四次揮手。

2.2 爲什麼不能把服務器發送的ACK和FIN合併起來,變成三次揮手(CLOSE_WAIT狀態意義是什麼)?

因爲服務器收到客戶端斷開連接的請求時,可能還有一些數據沒有發完,這時先回復ACK,表示接收到了斷開連接的請求。等到數據發完之後再發FIN,斷開服務器到客戶端的數據傳送。

2.3 如果第二次揮手時服務器的ACK沒有送達客戶端,會怎樣?

客戶端沒有收到ACK確認,會重新發送FIN請求。

2.4 客戶端TIME_WAIT狀態的意義是什麼?

第四次揮手時,客戶端發送給服務器的ACK有可能丟失,TIME_WAIT狀態就是用來重發可能丟失的ACK報文。如果Server沒有收到ACK,就會重發FIN,如果Client在2*MSL的時間內收到了FIN,就會重新發送ACK並再次等待2MSL,防止Server沒有收到ACK而不斷重發FIN。

MSL(Maximum Segment Lifetime),指一個片段在網絡中最大的存活時間,2MSL就是一個發送和一個回覆所需的最大時間。如果直到2MSL,Client都沒有再次收到FIN,那麼Client推斷ACK已經被成功接收,則結束TCP連接。

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