一文讓你輕鬆掌握TCP三次握手和四次揮手

一文讓你輕鬆掌握TCP三次握手和四次揮手

1、TCP和UDP對比

TCP 和 UDP是網絡協議的傳輸層上的兩種不同的協議。

TCP的特點是面向連接的、可靠的字節流服務。客戶端需要和服務器之間建立一個TCP連接,之後才能傳輸數據。數據到達之前對方就一直在等待,除非對方直接關閉連接,數據有序,先發先到。

UDP是一種無連接不可靠的數據發送協議。發送方根據對方的ip地址發送數據包,但是不保證接收發接包的質量,數據無序還容易丟包。雖然UDP協議不穩定但是在即時通訊(QQ聊天、在線視頻、網絡語音電話)的場景下,可以允許偶爾的斷續,但是這種協議速度快

TCP、UDP的報文結構 對比

一文讓你輕鬆掌握TCP三次握手和四次揮手

一文讓你輕鬆掌握TCP三次握手和四次揮手

在瞭解三次握手和四次揮手之前,先知道TCP報文內部包含了哪些東西。

  1. TCP報頭中的源端口號和目的端口號同IP數據報中的源IP與目的IP唯一確定一條TCP連接。TCP在發送數據前必須在彼此間建立連接,這裡連接意思是:雙方需要內保存對方信息(例如:IP,Port…)
  2. 報文主要段的意思

序號:表示發送的數據字節流,確保TCP傳輸有序,對每個字節編號

確認序號:發送方期待接收的下一序列號,接收成功後的數據字節序列號加 1。只有ACK=1時才有效。

ACK:確認序號的標誌,ACK=1表示確認號有效,ACK=0表示報文不含確認序號信息

SYN:連接請求序號標誌,用於建立連接,SYN=1表示請求連接

FIN:結束標誌,用於釋放連接,為1表示關閉本方數據流

二、三次握手

2.1 TCP握手過程

建立TCP連接時,需要客戶端和服務器共發送3個包。

  • 第一次:客戶端發送初始序號x和syn=1請求標誌
  • 第二次:服務器發送請求標誌syn,發送確認標誌ACK,發送自己的序號seq=y,發送客戶端的確認序號ack=x+1
  • 第三次:客戶端發送ACK確認號,發送自己的序號seq=x+1,發送對方的確認號ack=y+1


一文讓你輕鬆掌握TCP三次握手和四次揮手


2.2 三次握手過程分析:

  • 第一次:客戶端發送請求到服務器,服務器知道客戶端發送,自己接收正常。SYN=1,seq=x
  • 第二次:服務器發給客戶端,客戶端知道自己發送、接收正常,服務器接收、發送正常。ACK=1,ack=x+1,SYN=1,seq=y
  • 第三次:客戶端發給服務器:服務器知道客戶端發送,接收正常,自己接收,發送也正常.seq=x+1,ACK=1,ack=y+1

2.3 三次握手的必要性

  1. 第一次握手:客戶端發送網絡包,服務端收到了。這樣服務端就能得出結論:客戶端的發送能力、服務端的接收能力是正常的。
  2. 第二次握手:服務端發包,客戶端收到了。這樣客戶端就能得出結論:服務端的接收、發送能力,客戶端的接收、發送能力是正常的。不過此時服務器並不能確認客戶端的接收能力是否正常。
  3. 第三次握手:客戶端發包,服務端收到了。這樣服務端就能得出結論:客戶端的接收能力,服務器自己的發送能力也正常。

上面分析過程可以看出,握手兩次達不到讓雙方都得出自己、對方的接收、發送能力都正常的結論的。


一文讓你輕鬆掌握TCP三次握手和四次揮手


2.4 第三次握手的必要性

這主要是為了防止已失效的連接請求報文段突然又傳送到了服務器端,從而減少服務端的開銷。 如果只有兩次握手就建立連接會出現這種情況:客戶端發出的連接請求報文段在某些網絡節點長時間滯留了,以致延誤到連接釋放以後的某個時間才能到達服務端。本來這是一個早已失效的報文段,但服務端收到此失效的連接請求報文段後,就誤認為客戶端又發出了一次新的連接請求。於是向客戶端發出確認報文段,同意建立連接。由於現在客戶端並沒有發出建立連接的請求,因此不會處理服務端的確認,也不會向服務端發送數據。但服務端卻以為新的連接已經建立了,並一直等待客戶端發來數據。 服務端會因此浪費很多了。

2.5 如果第三次握手丟失了,客戶端服務端會如何處理?

服務端: 該TCP連接的狀態為SYN_RECV,並且會根據TCP的超時重傳機制,會等待3秒、6秒、12秒後重新發送SYN+ACK包,以便Client重新發送ACK包。而Server重發SYN+ACK包的次數,可以通過設置
/proc/sys/net/ipv4/tcp_synack_retries修改,默認值為5。如果重發指定次數之後,仍然未收到客戶端的ACK應答,那麼一段時間後,服務端自動關閉這個連接。 客戶端: 客戶端在接收到SYN+ACK包,它的TCP連接狀態就為ESTABLISHED(已連接),表示該連接已經建立。那麼如果第三次握手中的ACK包丟失的情況下,客戶端向服務端發送數據,服務端將以RST包(reset重置)響應,才能感知到服務端的錯誤。

三、 四次揮手

3.1 四次揮手過程

  • 第一次揮手:客戶端發出釋放FIN=1,自己序列號seq=u,進入FIN-WAIT-1狀態
  • 第二次揮手:服務器收到客戶端的後,發出ACK=1確認標誌和客戶端的確認號ack=u+1,自己的序列號seq=v,進入CLOSE-WAIT狀態
  • 第三次揮手:客戶端收到服務器確認結果後,進入FIN-WAIT-2狀態。此時服務器發送釋放FIN=1信號,確認標誌ACK=1,確認序號ack=u+1,自己序號seq=w,服務器進入LAST-ACK(最後確認態)
  • 第四次揮手:客戶端收到回覆後,發送確認ACK=1,ack=w+1,自己的seq=u+1,客戶端進入TIME-WAIT(時間等待)。客戶端經過2個最長報文段壽命後,客戶端CLOSE;服務器收到確認後,立刻進入CLOSE狀態。


一文讓你輕鬆掌握TCP三次握手和四次揮手


3.2 四次揮手過程分析

  • 第一次:客戶端請求斷開FIN,seq=u
  • 第二次:服務器確認客戶端的斷開請求ACK,ack=u+1,seq=v
  • 第三次:服務器請求斷開FIN,seq=w,ACK,ack=u+1
  • 第四次:客戶端確認服務器的斷開ACK,ack=w+1,seq=u+1

3.3 揮手為什麼需要四次?

因為當服務端收到客戶端的SYN連接請求報文後,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連接時,當服務端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴客戶端,"你發的FIN報文我收到了"。只有等到我服務端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四次揮手。


一文讓你輕鬆掌握TCP三次握手和四次揮手

四、面試高頻問題

4.1為什麼三次握手和四次揮手?

  • 三次握手時,服務器同時把ACK和SYN放在一起發送到了客戶端那裡
  • 四次揮手時,當收到對方的 FIN 報文時,僅僅表示對方不再發送數據了但是還能接受數據,己方是否現在關閉發送數據通道,需要上層應用來決定,因此,己方ACK和FIN一般都會分開發送。

4.2為什麼客戶端最後還要等待2MSL?

  • 兩個存在的理由:1、無法保證最後發送的ACK報文會一定被對方收到,所以需要重發可能丟失的ACK報文。2、關閉鏈接一段時間後可能會在相同的IP地址和端口建立新的連接,為了防止舊連接的重複分組在新連接已經終止後再現。2MSL足以讓分組最多存活msl秒被丟棄。

4.3、為什麼必須是三次握手,不能用兩次握手進行連接?

記住服務器的資源寶貴不能浪費! 如果在斷開連接後,第一次握手請求連接的包才到會使服務器打開連接,佔用資源而且容易被惡意攻擊!防止攻擊的方法,縮短服務器等待時間。兩次握手容易死鎖。如果服務器的應答分組在傳輸中丟失,將不知道S建立什麼樣的序列號,C認為連接還未建立成功,將忽略S發來的任何數據分組,只等待連接確認應答分組。而S在發出的分組超時後,重複發送同樣的分組。這樣就形成了死鎖。

4.4 如果已經建立了連接,但是客戶端突然出現故障了怎麼辦?

TCP還設有一個保活計時器,顯然,客戶端如果出現故障,服務器不能一直等下去,白白浪費資源。服務器每收到一次客戶端的請求後都會重新復位這個計時器,時間通常是設置為2小時,若兩小時還沒有收到客戶端的任何數據,服務器就會發送一個探測報文段,以後每隔75秒鐘發送一次。若一連發送10個探測報文仍然沒反應,服務器就認為客戶端出了故障,接著就關閉連接。

以上就是關於TCP三次握手和四次揮手的總結,歡迎大家轉發留言交流。


分享到:


相關文章: