筆記分享:網絡編程基礎之TCP的三次握手

圖片來源自網絡:

  • 第一次握手:建立連接時,客戶端發送SYN包(seq=x)到服務器,並進入SYN_SEND狀態,等待服務器確認;
    • 發送同步信號SYN=1,以及選擇一個初始的字節序號(任意一個正整數值)。
    • 客戶端的進程進入SYN-SENT的同步已發送狀態。
    • 發送的報文段又稱爲SYN報文段,是不能攜帶數據的,但需要消耗一個序號。
  • 第二次握手:服務器收到SYN包,必須確認客戶的SYN(ack=x+1),同時自己也發送一個SYN包(seq=y),即SYN + ACK包,此時服務器進入SYN_RECV狀態。
    • 發送確認連接,同步信號SYN=1,確認信號ACK=1,確認號ack=x+1,然後爲自己的緩存初始化一個序號seq=y
    • 然後服務器端就會進入一個SYN-RCVD同步收到狀態
    • 這段報文同樣不能攜帶數據,但需要消耗一個序號
  • 第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=y+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。
    • 客戶端還需要回復一個確認服務器確認的迴應報文,確認信號ACK=1,確認號ack=y+1,自身序號seq = x+1
    • 這個報文段可攜帶數據,也可不攜帶,如果不攜帶就不需要消耗序號
    • 然後進入數據傳送過程
  • 爲什麼需要三次握手才能建立起連接
    • 爲了初始化Sequence Number的初始值,來確保接收到的數據,沒有因網絡問題而亂序。
    • 第三次握手主要目的是告知服務器,客戶端已接收到服務端的Sequence Number
  • 首次握手的隱患---SYN超時
    • Server收到Client的SYN,回覆SYN-ACK的時候未收到ACK確認
    • Server不斷重試直至超時,Linux默認重試5次,重試時間從1秒開始,每次都翻倍,1+2+4+8+16=31秒,再等待32未迴應,判斷超時。因此Linux默認等待63秒才斷開連接
    • 這裏會造成一個安全隱患,不斷觸發連接,耗盡連接請求隊列資源,讓正常的連接隊列無法連接。
    • 針對SYN Flood的防護措施
      • SYN隊列滿後,通過tcp_syncookies參數回發SYN Cookie,服務端通過原地址端口、目標地址端口、時間戳打造出一個特殊的Sequence Number回發回去,簡稱tcp_syncookies。
      • 若爲正常連接則Client會回發SYN Cookie,直接建立連接
  • 建立連接後,Client出現故障怎麼辦
    • 保活機制
      • 向對方發送保活探測報文,如果未收到相應則繼續發送
      • 嘗試次數打到保活探測數仍未收到響應則中斷連接
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章