TCP三次握手與四次揮手

這裏主要記錄在平常中對知識的學習,經過結合筆記與自身理解的方式嘗試寫下總結
文章對細節可能不會一一介紹解釋,內容僅做參考
複製代碼

前段時間看了HTTP相關的知識,但感受還有還多細節面沒有了解到位。此次補充與TCP鏈接有關的服務器

1、頭部字段

一些須要前置瞭解的知識點網絡

  • Sequence number 順序號碼:保證TCP傳輸的報文都是有序的
  • Acknowledge number 確認號碼:表示數據接收端指望接收的下一個字節的編號是多少,並表示上一個序號已接收完成
  • 確認方Ack = 發起方Req+1,兩端配對
  • Window Size 窗口大小:表示還能接收多少字節的數據,用於流量控制
  • RTT:表示發送端發送數據到接收到對端數據所需的往返時間

標識符:學習

  • URG=1: 表示本數據報的數據部分包含緊急信息,是一個高優先級數據報文,此時緊急指針有效。緊急數據必定位於當前數據報數據部分的最前面,緊急指針標明瞭緊急數據的尾部
  • ACK=1: 表示確認字段有效。TCP還規定在鏈接創建後傳送的全部報文段都必須把ACK置爲1
  • PSH=1: 表示接收端應該當即將數據push給應用層,而不是等到緩衝區滿後再提交
  • RST=1: 表示當前TCP鏈接出現嚴重問題,可能須要從新創建TCP鏈接,也可能用於拒絕非法的報文段和拒絕鏈接請求
  • SYN=1: 當SYN=1,ACK=0時,表示當前報文段是一個鏈接請求報文;當SYN=1,ACK=1時,表示當前報文段是一個贊成創建鏈接的應答報文
  • FIN=1: 表示此報文段是一個釋放鏈接的請求報文

2、三次握手

在TCP協議中,主動發起請求的一端爲客戶端,被動鏈接的一端爲服務端。不論是客戶端仍是服務端,TCP鏈接創建完成後都能發送和接收數據,因此TCP是一個全雙工的協議spa

一次TCP的創建須要進行三次對話,從而肯定一個鏈接,進而開始通信3d

過程如圖所示:指針

  • 第一次握手:客戶端向服務端發送連接請求報文段。該報文段中包含自身的數據通信初始序號Seq=X和鏈接請求SYN。請求發送後,客戶端進入SYN-SENT狀態
  • 第二次握手:服務端收到連接請求報文段後,若是贊成鏈接,則會發送一個包含自身的數據通信初始序號Seq=Y、確認序號Ack=X+1和應答標識ACK的確認應答。發送完成後,服務端進入SYN-RECEIVED狀態
  • 第三次握手:當客戶端收到鏈接贊成的應答後,還要向服務端發送一個確認報文(Ack=Y+1,Seq=Z,ACK)。客戶端發完這個報文段後進入ESTABLISHED狀態,此時鏈接創建成功

明明兩次握手就能夠創建鏈接,爲何還須要第三次應答呢:code

由於這是爲了防止失效的鏈接請求報文段被服務端接收,從而產生錯誤cdn

若是是這樣:客戶端發送了一個鏈接請求A,可是由於網絡緣由形成了超時,這時TCP會啓動超時重傳的機制再發送一個鏈接請求B。此時請求B順利到達服務端,服務端應答完成就創建鏈接。若是鏈接請求A在兩端關閉後終於到達了服務端,那麼這時服務端會認爲客戶端又須要創建TCP鏈接從而應答後進入ESTABLISHED狀態。此時客戶端實際上是CLOSED狀態,那麼就會致使服務端一直等待,形成資源浪費blog

在創建鏈接中,任意一端掉線,TCP都會重發SYN包,通常會重試5次,在創建鏈接中可能會遇到SYN FLOOD攻擊,能夠選擇調低重試次數或乾脆在不能處理的狀況下拒絕請求資源

3、四次揮手

TCP是全雙工的,在斷開鏈接時兩端都須要發送FIN斷開請求和ACK確認

過程如圖所示:

  • 第一次揮手:客戶端認爲數據發送完成,向服務端發送鏈接釋放請求
  • 第二次揮手:服務端收到鏈接釋放請求,會告訴應用層要釋放TCP鏈接。而後發送確認應答,並進入CLOSE_WAIT狀態,表示客戶端到服務端的鏈接已經釋放,不接收客戶端發的數據了。可是由於TCP鏈接是雙向的,因此服務端仍舊能夠發送數據給客戶端
  • 第三次揮手:若是此時服務端還有沒有發完的數據,會繼續發送。等到發送完畢後會向客戶端發送鏈接釋放請求,並進入LAST-ACK狀態
  • 第四次揮手:客戶端收到釋放請求後,會向服務端發送確認應答。此時客戶端進入TIME-WAIT狀態,會持續2MSL(最大段生存期,指報文段在網絡中生存的時間,超時會被拋棄),若該時間段內沒有服務器的重發請求的話,就進入CLOSED狀態。當服務端收到確認應答的時候,也進入了CLOSED狀態

爲何客戶端要進入TIME-WAIT狀態,等待2MSL後才進入CLOSED狀態呢:

爲了保證服務端能收到客戶端的確認應答。若客戶端發完確認應答後直接進入CLOSED狀態,若是確認應答由於網絡問題一直沒有到達,那麼會形成服務端不能正常關閉

爲何鏈接的時候是三次握手,關閉的時候倒是四次握手:

由於當服務端收到客戶端的SYN鏈接請求報文後,能夠直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。可是關閉鏈接時,當服務端收到FIN報文時,極可能並不會當即關閉SOCKET,因此只能先回復一個ACK報文,告訴客戶端,"你發的FIN報文我收到了"。只有等到我服務端全部的報文都發送完了,我才能發送FIN報文,所以不能一塊兒發送。故須要四步握手

相關文章
相關標籤/搜索