TCP三次握手四次揮手

xjlgxlgx發表於2019-09-22
每次面試的時候都會多多少少聊一點TCP/IP協議,那麼你是如何理解其中的三次握手四次揮手的?

什麼是“三次握手,4次揮手“?

首先我們需要知道TCP是一種面向連線的單播協議。

單播協議一般指單播路由協議,單播路由協議是通過路由器將到網際網路上某一位置的通訊從源主機轉發到目標主機。網際網路至少有兩個通過路由器連線的網路。路由器是網路層中介系統,用於根據公用網路層協議(如 TCP/IP)將多個網路連線在一起。網路是通過路由器連線,並與稱為網路地址或網路 ID 的同一網路層地址相關聯的聯網基礎結構(包括中繼器、集線器和橋/ 2 層交換機)的一部分。

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

所以TCP提供了一種可靠、面向連線、位元組流、傳輸層的服務,採用三次握手建立一個連線。採用4次揮手來關閉一個連線。

圖示為

TCP三次握手四次揮手

三次握手的過程

三次握手你可以想象成這樣的一個場景,有兩個兩個人A和B,A想給B一些包裹,B想收一些包裹,但是A害怕給B剛發了包裹,B就走了,包裹到了以後沒有收,而B則害怕A只是口頭上說要把包裹寄過來,B在這裡等了半天發現自己被耍了。所以這兩個人需要達成一個規定或者說是一個協議來保證雙方都能達到目的。這就需要三次握手。

三次握手:A對B說我要給你發一些包裹!B問A說你真的要給我發包裹嗎!然後A回答我真的真的要給你發包裹(B就像言情劇的女主一樣,A說的第一遍B是不信的,非要A再說一遍B才信)至此A和B的協議達成,A就可以給B發包裹啦.

這是一種比喻,真正的表現為:

(1)第一次握手:

客戶端傳送syn包(syn=x)到伺服器,並進入SYN_SEND狀態,等待伺服器確認。

(2)第二次握手:

伺服器收到syn包,必須確認客戶的SYN(ack=x+1),同時自己也傳送一個SYN包(syn=y),即SYN+ACK包,此時伺服器進入SYN_RECV狀態。

(3)第三次握手:

客戶端收到伺服器的SYN+ACK包,向伺服器傳送確認包ACK(ack=y+1),此包傳送完畢,客戶端和伺服器進入ESTABLISHED狀態,萬次三次握手。

注意:以上動作傳送的包中沒有任何資料,等三次握手完成後客戶端與伺服器才正式開始傳送資料。並且理想狀態下,TCP連線一旦建立,在通訊雙方中的任何一方主動關閉連線之前,TCP連線都將被一直保持下去。

TCP三次握手四次揮手

那麼為什麼要三次握手?

為什麼要三次握手,我握兩次不行嗎?我覺得我說發,你說好,不就完了嗎,非要矯情一下,握第三次手的意義是什麼?

首先我們先來理解一下為什麼需要握手?

客戶端和伺服器端通訊前需要連線,而”握手“作用就是為了證明,客戶端的傳送能力和伺服器端的接受能力都是正常的,這是”握手“來達到的目的。

第一次握手:客戶端傳送網路包,伺服器端收到了,這樣伺服器端就能證明:客戶端的傳送能力、以及伺服器端的接收能力都是正常的。

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

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

而從上面的過程可以看到,最少是需要三次握手過程的。兩次達不到讓雙方都得出自己、對方的接收、傳送能力都正常的結論。

四次揮手

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

通俗的來說就是

四次揮手:  A對B說:我要和你斷開連線!B說:好的,斷吧! B也對A說我也要和你斷開連線!

A說:好的,斷吧!

真實的過程是

(1)第一次揮手

客戶端主動關閉方傳送一個FIN,用來關閉客戶端到伺服器端的資料傳送,也就是客戶端告訴伺服器端:我已經不會再給你發資料了, (當然,在 fin 包之前傳送出去的資料,如果沒有收到對應的 ack 確認報文,客戶端依然會重發這些資料),但是,此時客戶端還可以接受資料

(2)第二次揮手

服務端收到FIN包後,傳送一個ACK給客戶端,確認序號為收到序號+1(與 SYN 相同,一個 FIN 佔用一個序號)。

(3)第三次揮手

伺服器端傳送一個FIN,用來關閉伺服器端到客戶端的資料傳送,也就是告訴客戶端,我的資料也傳送完了,不會再給你傳送資料了!!!

(4)第四次揮手

客戶端收到 FIN 後,傳送一個 ACK 給服務端,確認序號為收到序號 + 1,至此,完成四次揮手。

TCP三次握手四次揮手


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


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

相關文章