“三次握手”與“四次揮手”

一、什麼是“3次握手,4次揮手”?

TCP是一種面向連接的單播協議,在發送數據前,通信雙方必須在彼此間建立一條連接。所謂的“連接”,其實是客戶端和服務器的內存裏保存的一份關於對方的信息,如ip地址、端口號等。

TCP可以看成是一種字節流,它會處理IP層或以下的層的丟包、重複以及錯誤問題。在連接的建立過程中,雙方需要交換一些連接的參數。這些參數可以放在TCP頭部。

TCP提供了一種可靠、面向連接、字節流、傳輸層的服務,採用三次握手建立一個連接。採用4次揮手來關閉一個連接。

 

二、爲什麼要“三次握手,四次揮手”?

1、三次握手

換個易於理解的視角來看爲什麼要3次握手。

客戶端和服務端通信前要進行連接,“3次握手”的作用就是雙方都能明確自己和對方的收、發能力是正常的。

第一次握手:

客戶端發送網絡包,服務端收到了。這樣服務端就能得出結論:客戶端的發送能力、服務端的接收能力是正常的。

第二次握手:

服務端發包,客戶端收到了。這樣客戶端就能得出結論:服務端的接收、發送能力,客戶端的接收、發送能力是正常的。 從客戶端的視角來看,我接到了服務端發送過來的響應數據包,說明服務端接收到了我在第一次握手時發送的網絡包,並且成功發送了響應數據包,這就說明,服務端的接收、發送能力正常。而另一方面,我收到了服務端的響應數據包,說明我第一次發送的網絡包成功到達服務端,這樣,我自己的發送和接收能力也是正常的。

第三次握手:

客戶端發包,服務端收到了。這樣服務端就能得出結論:客戶端的接收、發送能力,服務端的發送、接收能力是正常的。 第一、二次握手後,服務端並不知道客戶端的接收能力以及自己的發送能力是否正常。而在第三次握手時,服務端收到了客戶端對第二次握手作的迴應。從服務端的角度,我在第二次握手時的響應數據發送出去了,客戶端接收到了。所以,我的發送能力是正常的。而客戶端的接收能力也是正常的。

小結:

經歷了上面的三次握手過程,客戶端和服務端都確認了自己的接收、發送能力是正常的。之後就可以正常通信了。

每次都是接收到數據包的一方可以得到一些結論,發送的一方其實沒有任何頭緒。我雖然有發包的動作,但是我怎麼知道我有沒有發出去,而對方有沒有接收到呢?

而從上面的過程可以看到,最少是需要三次握手過程的。兩次達不到讓雙方都得出自己、對方的接收、發送能力都正常的結論。其實每次收到網絡包的一方至少是可以得到:對方的發送、我方的接收是正常的。而每一步都是有關聯的,下一次的“響應”是由於第一次的“請求”觸發,因此每次握手其實是可以得到額外的結論的。比如第三次握手時,服務端收到數據包,表明看服務端只能得到客戶端的發送能力、服務端的接收能力是正常的,但是結合第二次,說明服務端在第二次發送的響應包,客戶端接收到了,並且作出了響應,從而得到額外的結論:客戶端的接收、服務端的發送是正常的。

  客戶端 服務端
第一次握手   客戶端發送、服務端接收正常
第二次握手 客戶端發送、客戶端接收、服務端發送、服務端接收正常  
第三次握手   客戶端發送、客戶端接收、服務端發送、服務端接收正常

2、四次揮手

TCP連接是雙向傳輸的對等的模式,就是說雙方都可以同時向對方發送或接收數據。當有一方要關閉連接時,會發送指令告知對方,我要關閉連接了。這時對方會回一個ACK,此時一個方向的連接關閉。但是另一個方向仍然可以繼續傳輸數據,等到發送完了所有的數據後,會發送一個FIN段來關閉此方向上的連接。接收方發送ACK確認關閉連接。

注意,接收到FIN報文的一方只能回覆一個ACK, 它是無法馬上返回對方一個FIN報文段的,因爲結束數據傳輸的“指令”是上層應用層給出的,我只是一個“搬運工”,我無法瞭解“上層的意志”。

 

三、“三次握手,四次揮手”怎麼完成?

其實3次握手的目的並不只是讓通信雙方都瞭解到一個連接正在建立,還在於利用數據包的選項來傳輸特殊的信息,交換初始序列號ISN。

 

3次握手是指發送了3個報文段,4次揮手是指發送了4個報文段。注意,SYN和FIN段都是會利用重傳進行可靠傳輸的。

640?wx_fmt=png

 

三次握手

  • 客戶端發送一個SYN段,並指明客戶端的初始序列號,即ISN(c).

  • 服務端發送自己的SYN段作爲應答,同樣指明自己的ISN(s)。爲了確認客戶端的SYN,將ISN(c)+1作爲ACK數值。這樣,每發送一個SYN,序列號就會加1. 如果有丟失的情況,則會重傳。

  • 爲了確認服務器端的SYN,客戶端將ISN(s)+1作爲返回的ACK數值。

 

四次揮手

640?wx_fmt=png

 

  • 客戶端發送一個FIN段,幷包含一個希望接收者看到的自己當前的序列號K. 同時還包含一個ACK表示確認對方最近一次發過來的數據。 

  • 服務端將K值加1作爲ACK序號值,表明收到了上一個包。這時上層的應用程序會被告知另一端發起了關閉操作,通常這將引起應用程序發起自己的關閉操作。

  • 服務端發起自己的FIN段,ACK=K+1, Seq=L 4. 客戶端確認。ACK=L+1

 

爲什麼建立連接是三次握手,而關閉連接卻是四次揮手呢?

這是因爲服務端在LISTEN狀態下,收到建立連接請求的SYN報文後,把ACK和SYN放在一個報文裏發送給客戶端。而關閉連接時,當收到對方的FIN報文時,僅僅表示對方不再發送數據了但是還能接收數據,己方是否現在關閉發送數據通道,需要上層應用來決定,因此,己方ACK和FIN一般都會分開發送。

本文轉自:https://blog.csdn.net/csdnnews/article/details/86570658

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