TCP爲什麼要三次握手而不採用兩次握手

轉載自:http://blog.csdn.net/xumin330774233/article/details/14448715

謝希仁版《計算機網絡》中的例子是這樣的,“已失效的連接請求報文段”的產生在這樣一種情況下:client發出的第一個連接請求報文段並沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以後的某個時間纔到達server。本來這是一個早已失效的報文段。但server收到此失效的連接請求報文段後,就誤認爲是client再次發出的一個新的連接請求。於是就向client發出確認報文段,同意建立連接。假設不採用“三次握手”,那麼只要server發出確認,新的連接就建立了。由於現在client並沒有發出建立連接的請求,因此不會理睬server的確認,也不會向server發送ack包。(校注:此時因爲client沒有發起建立連接請求,所以client處於CLOSED狀態,接受到任何包都會丟棄,謝希仁舉的例子就是這種場景。但是如果服務器發送對這個延誤的舊連接報文的確認的同時,客戶端調用connect函數發起了連接,就會使客戶端進入SYN_SEND狀態,當服務器那個對延誤舊連接報文的確認傳到客戶端時,因爲客戶端已經處於SYN_SEND狀態,所以就會使客戶端進入ESTABLISHED狀態,此時服務器端反而丟棄了這個重複的通過connect函數發送的SYN包,見第三個圖而連接建立之後,發送包由於SEQ是以被丟棄的SYN包的序號爲準,而服務器接收序號是以那個延誤舊連接SYN報文序號爲準,導致服務器丟棄後續發送的數據包)但server卻以爲新的運輸連接已經建立,並一直等待client發來數據。這樣,server的很多資源就白白浪費掉了。採用“三次握手”的辦法可以防止上述現象發生。例如剛纔那種情況,client不會向server的確認發出確認。server由於收不到確認,就知道client並沒有要求建立連接。

在謝希仁著《計算機網絡》第四版中講“三次握手”的目的是“爲了防止已失效的連接請求報文段突然又傳送到了服務端,因而產生錯誤”。在另一部經典的《計算機網絡》(Andrew S.Tanenbaum著,第四版)一書中講“三次握手”的目的是爲了解決“網絡中存在延遲的重複分組”的問題。這兩種不同的表述其實闡明的是同一個問題。

   





附華中科技大學有一題研究生入學考題,是下面題目的中文翻譯版(不過我覺得這個答案有點牽強,畢竟現在tcp傳輸機制中都有定時器,會有超時重傳,不會導致死鎖的,當然如果沒有超時機制,死鎖還是可能的):

Imagine that a two-way handshake rather than a three-way handshake were used to set up connections. In other words, the third message was not required. Are deadlocks now possible? Give an example or show that none exist.

Answer:
Deadlocks are possible. For example, a packet arrives at A out of the blue, and A acknowledges it. The acknowledgement gets lost, but A is now open while B knows nothing at all about what has happened. Now the same thing happens to B, and both are open, but expecting different sequence numbers. Timeouts have to be introduced to avoid the deadlocks.


網上有一段流傳很廣的解釋:

 爲什麼不能用兩次握手進行連接?

我們知道,3次握手完成兩個重要的功能,既要雙方做好發送數據的準備工作(雙方都知道彼此已準備好),也要允許雙方就初始序列號進行協商,這個序列號在握手過程中被髮送和確認。
    現在把三次握手改成僅需要兩次握手,死鎖是可能發生的。作爲例子,考慮計算機S和C之間的通信,假定C給S發送一個連接請求分組,S收到了這個分組,併發 送了確認應答分組。按照兩次握手的協定,S認爲連接已經成功地建立了,可以開始發送數據分組。可是,C在S的應答分組在傳輸中被丟失的情況下,將不知道S 是否已準備好,不知道S建立什麼樣的序列號,C甚至懷疑S是否收到自己的連接請求分組。在這種情況下,C認爲連接還未建立成功,將忽略S發來的任何數據分 組,只等待連接確認應答分組。而S在發出的分組超時後,重複發送同樣的分組。這樣就形成了死鎖。


校評:這個解釋也值得商榷,這裏指說S超時重傳,難道C沒有收到S的ACK信號,不會重新發送SYN信號麼? 只要重新發送SYN,S端自然也會發送確認應答分組,這樣就不會導致死鎖。



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