建立TCP連接爲什麼要進行三次握手

本文試圖解釋爲什麼建立TCP連接必須是三次握手,而不是兩次或者四次或者不握手。以A向B請求建立TCP連接爲例。

前提知識

1、網絡層實現的傳輸是不可靠的,TCP是可靠傳輸

此處的可靠是非常狹義,有具體所指的可靠。鏈路層在兩個網絡節點間傳遞數據時會使用循環冗餘檢測檢查數據是否在傳輸過程中有錯誤,如果有就丟棄數據包,網絡層乃至傳輸層的UDP協議並未對此做什麼改變。所以這種傳輸是不可靠的(丟棄之後數據包就消失了,並且不做任何補救措施)。而TCP的可靠之處在於儘量保證數據能傳給對方,僅此而已。

2、TCP的可靠傳輸實現在於兩個方面(單個數據包的可靠和多個數據包的可靠)

假設A計算機使用TCP協議給B計算機發數據。首先單個數據包的可靠,TCP要求B計算機收到數據後必須發回一個確認報文,如果A長時間未收到確認,或者收到B的報文說數據錯了,A就會重傳一次,直到B確認收到。由此可見,可靠傳輸是靠一去一回實現的。其次多個數據包的可靠,如果一段數據非常長(一般是超過1500字節,由下層物理特性決定),會分成n段一段一段發送。而由於計算機網絡採用分組交換,無法保證先發的數據就一定先到,所以需要給每一段標號。起始標號不從0開始,而是隨機產生一個數,這是爲了區分上一個TCP連接發送的數據和這一個連接的數據,如果每次都從0開始,則如果網絡中有殘留的上一次連接的數據,會對這次連接造成干擾。

3、TCP連接是全雙工的

當TCP連接建立後,A可以給B發數據,B也可以給A發數據,兩個過程可以同時進行,互不干擾。

爲什麼是三次握手

爲了實現可靠傳輸和全雙工這兩個特性,在連接建立前A和B都必須知道一些必要數據,包括A給B發數據的開始序號和A的接收窗口大小,B給A發數據的開始序號和B的接收窗口大小。由單個數據包的可靠傳輸的原理可知,需要一去一回兩次,也就是四次握手:

A-->B    請求建立TCP連接,附加數據:A的開始序號等

B-->A    已收到請求和數據

B-->A    附加數據:B的開始序號等

A-->B    已收到數據

其中第二次的B給A確認和第三次的B給A發送B的開始序號可以合成一個報文。這就是三次握手的由來。

A-->B    請求建立TCP連接,附加數據:A的開始序號等

B-->A    已收到請求和數據,附加數據:B的開始序號等

A-->B    已收到數據

爲什麼兩次握手和四次握手不行

三次握手就是四次握手的簡化,功能和效果完全一樣,還節省一次發數據的時間,所以四次握手沒有必要。

如果偷雞簡化爲兩次握手,省略掉第三次A發給B的確認信號,似乎沒有什麼不妥。但是違背了可靠傳輸的原則:收到數據必須反饋一個確認信號。由此導致B無法得知A是否收到B的數據,並且TCP連接不再是全雙工連接。假如A發起連接請求後,AB間建立了連接,A不先給B發數據而是等待B先給A發數據。由於二次握手無法保證A知道B的開始序號,所以B是不能貿然發送數據的。

《計算機網絡》一書的觀點

《計算機網絡》認爲核心在於建立連接的時機不同:三次握手中A在收到第二次握手時建立連接,B在收到第三次握手時建立連接連接。兩次握手中A在收到第二次握手時建立連接,B在收到第一次握手時建立連接。

兩次握手:如果A給B發送的請求走了遠路,超時又發送第二次並完成通信全過程,關閉連接。此後第一個請求到達B,B立即建立連接,但是A已經不在線了,B只能一直等待,浪費資源。如果是三次握手:B在收到遲到的請求後會進行第二次握手確認,多次重傳A仍然沒有響應,B就會釋放資源。

個人認爲,這是一方面,不過三次握手也不能從根本上解決這類問題,只是降低了發生的概率,更重要的是兩次握手違背了可靠傳輸和全雙工的原則。

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