1. 程式人生 > >TCP為什麼是三次握手,不是四次或兩次,終於理解了

TCP為什麼是三次握手,不是四次或兩次,終於理解了

過往

我很久以前就看過三次握手和四次揮手的部落格,但根本沒懂,直到最近為了面試再看,也是僅僅知道過程,至於面試中的為什麼需要三次握手,而不是四次或兩次?,網上的部落格千千萬,國內外的,我還是一直沒有理解,知道今天看了學校發的教科書上的解釋,這才理解了.

解惑

我寫下這些,僅供我自己和有緣和我有一樣想法的人看懂

網上關於三次握手和四次揮手的圖太多了,我懶得copy一份了,就文字說一說
前兩次握手很好理解,就是傳送端先發一個SYN=1,seq=x(SYN和seq等等欄位自行查詢TCP首部欄位詳解),表示我傳送端要和你接受端建立連線,接收端在接受到這個請求報文段時,為了表示我接收端接收到了,要給傳送端一個表示我接收到了的訊息,傳送的是SYN=1,ACK=1,seq=y,ack=x+1

這裡就有的說了.

我的書上說,三次握手這個比喻並不恰當,準確的說,應該是三報文握手,因為書的作者認為,這個過程其實是一次握手中進行了三次報文交換,而不是三次握手,硬要用握手來說,也是兩個人見面握住手,搖晃了三下,這也符合現實.

接著前一段說,接收端發給接收端的訊息,其實也可以分為兩段,一個是ACK=1,ack=x+1,另一個是SYN=1,seq=y,前一個是確認報文段,是告訴傳送端,我接收到你的訊息了,後者則是同步報文段,是接收端發給接收端的建立連線的報文,但是這兩個報文段在一個tcp首部並不衝突,所以可以一次發過去.

再來,傳送端接收到接收端傳送的報文,知道接收端剛才接收到了自己的訊息,按理說,這個時候連線就建立了,該發資料了啊,為什麼還要再確定一次呢?

這裡我們用一個現實的例子來解釋.就拿大家都喜歡的約會來解釋.傳送端相當一個男生,接收端是一個女生.一開始,男生髮送一條微信告訴女生,今天晚上九點在公園見面唄,然後這條訊息因為不可抗力,沒有傳送到女生的手機上,這時,這條訊息有兩個去路,一個是徹底消失,另一個是它迷失在網路中,沒有找到方向.回來繼續說,男生看女生沒有迴應,就又發了一條一樣的微信,這次微信順利的發過去了,男生女生也順利的見面了,這一天也就這麼過去了.到了第二天,那條迷失在網路中的微信重新找到了方向(真正的網路資訊不可能滯留這麼久,例子而已),發到了女生的手機上,女生一看,很高興,畢竟昨天玩的很開心,以為今天又可以開心一次,就又去了,男生昨天玩了一晚上,身體跟不上,就在家躺著,也早忘了那條迷失的微信.就這樣,女生在公園等了很久,很難受.

其實上面的例子已經說的很明白了,保險起見,再在具體連線裡說一下.如果是兩次連線,很可能發生上面的問題,如果有訊息在一次tcp連線完成後才到達接收端,那麼接收端以為是新的連線,就會發確認報文到接收端確認並建立連線,但傳送端可能已經關閉,即使沒關閉,在沒有到達SYN-SENT狀態時,也不會響應接收端的確認資訊,接收端可能就這樣等待,這在網路中就浪費了資源.

但是有了第三次報文確定就不一樣了,第三次,傳送端在此傳送確認報文包接收端,接收端接收到後,也就知道了傳送端接收到自己的確認資訊了,如果在此發生上面的問題,接收端再次接收到了滯留在網路中的資訊,傳送確認資訊給傳送端,但是當傳送端沒有理會的時候,接收端也就知道這是錯誤資訊,就不會等待,也就沒有資源浪費了.

說句題外話,即使是三次握手也不能保證百分百的連線確定,想象一下這樣的場景,兩軍對陣,A軍分兩部分位於兩個山頭,B軍在兩山之間,只有兩個A軍聯合才能戰勝B軍,但是兩個A軍之間的路徑就只有經過B軍的一條線路.任何送信人都有可能被攔截殺掉.

這個時候,如果兩A軍想聯合出擊,必須派出密探傳送進軍指令,這就有一個問題存在,假設第一次送信成功,A2知道了A1的計劃,那他必須再發一一封信告訴A1自己知道了,不然A1怎麼知道A2收沒收到,萬一信被攔截了,自己明天一個人去,不是找死.再假設A2給A1的表明自己收到資訊的信也順利發到A1了,那就安全了嗎,這個時候A2就擔心自己的信送沒送到,萬一沒送到,那明天自己去,不也是找死.顯然A1也知道這個問題,所以又要傳送第三封信,告訴A2自己收到信了,我們再一次假設,A2收到了這第三封信,但是同樣的問題又發生了,A1還是擔心這第三封信送沒送到,畢竟關乎生死,A2當然也知道,就只能再送信,
可以看到,這樣其實是沒有止境的,也是無解的,在TCP協議中,我們不使用四次,五次握手,是因為達到的效果是一樣的,但是消耗更多的資源,得不償失