1. 程式人生 > >TCP 為什麼是三次握手,為什麼不是兩次或四次?

TCP 為什麼是三次握手,為什麼不是兩次或四次?

TCP作為一種可靠傳輸控制協議,其核心思想:既要保證資料可靠傳輸,又要提高傳輸的效率,而用三次恰恰可以滿足以上兩方面的需求!

TCP可靠傳輸的精髓:TCP連線的一方A,由作業系統動態隨機選取一個32位長的序列號(Initial Sequence Number),假設A的初始序列號為1000,以該序列號為原點,對自己將要傳送的每個位元組的資料進行編號,1001,1002,1003…,並把自己的初始序列號ISN告訴B,讓B有一個思想準備,什麼樣編號的資料是合法的,什麼編號是非法的,比如編號900就是非法的,同時B還可以對A每一個編號的位元組資料進行確認。如果A收到B確認編號為2001,則意味著位元組編號為1001-2000,共1000個位元組已經安全到達。

同理B也是類似的操作,假設B的初始序列號ISN為2000,以該序列號為原點,對自己將要傳送的每個位元組的資料進行編號,2001,2002,2003…,並把自己的初始序列號ISN告訴A,以便A可以確認B傳送的每一個位元組。如果B收到A確認編號為4001,則意味著位元組編號為2001-4000,共2000個位元組已經安全到達。

一句話概括,TCP連線握手,握的是啥?

通訊雙方資料原點的序列號!

以此核心思想我們來分析二、三、四次握手的過程。

A <——-> B

四次握手的過程:

1.1 A 傳送同步訊號SYN + A’s Initial sequence number

1.2 B 確認收到A的同步訊號,並記錄 A’s ISN 到本地,命名 B’s ACK sequence number


1.3 B傳送同步訊號SYN + B’s Initial sequence number

1.4 A確認收到B的同步訊號,並記錄 B’s ISN 到本地,命名 A’s ACK sequence number

很顯然1.2和1.3 這兩個步驟可以合併,只需要三次握手,可以提高連線的速度與效率。


二次握手的過程:

2.1 A 傳送同步訊號SYN + A’s Initial sequence number

2.2 B傳送同步訊號SYN + B’s Initial sequence number + B’s ACK sequence number

這裡有一個問題,A與B就A的初始序列號達成了一致,這裡是1000。但是

B無法知道A是否已經接收到自己的同步訊號,如果這個同步訊號丟失了,A和B就B的初始序列號將無法達成一致。

於是TCP的設計者將SYN這個同步標誌位SYN設計成佔用一個位元組的編號(FIN標誌位也是),既然是一個位元組的資料,按照TCP對有資料的TCP segment 必須確認的原則,所以在這裡A必須給B一個確認,以確認A已經接收到B的同步訊號。

有童鞋會說,如果A發給B的確認丟了,該如何?
A會超時重傳這個ACK嗎?不會!TCP不會為沒有資料的ACK超時重傳

那該如何是好?B如果沒有收到A的ACK,會超時重傳自己的SYN同步訊號,一直到收到A的ACK為止。


——————-
補充閱讀:

第一個包,即A發給B的SYN 中途被丟,沒有到達B

A會週期性超時重傳,直到收到B的確認

第二個包,即B發給A的SYN +ACK 中途被丟,沒有到達A

B會週期性超時重傳,直到收到A的確認

第三個包,即A發給B的ACK 中途被丟,沒有到達B

A發完ACK,單方面認為TCP為 Established狀態,而B顯然認為TCP為Active狀態:


a. 假定此時雙方都沒有資料傳送,B會週期性超時重傳,直到收到A的確認,收到之後B的TCP 連線也為 Established狀態,雙向可以發包。

b. 假定此時A有資料傳送,B收到A的 Data + ACK,自然會切換為established 狀態,並接受A的 Data。

c. 假定B有資料傳送,資料傳送不了,會一直週期性超時重傳SYN + ACK,直到收到A的確認才可以傳送資料。