計算機網絡(一)TCP三次握手以及四次揮手

1. 計算機網絡分層

OSI模型

  • 物理層
  • 數據鏈路層
  • 網絡層
  • 傳輸層
  • 會話層
  • 表示層

物理層:定義了物理設備的標準,傳輸比特流(二進制數據轉換爲強弱不同的電流,到達目的後再轉換爲機器碼)

數據鏈路層:定義瞭如何格式化數據以及如何傳輸,提供錯誤檢測以及糾正,將比特數據轉換爲幀

網絡層:將網絡地址翻譯爲對應的物理地址,並決定將數據從發送方路由到接收方,選擇最佳路由。IP協議,IP數據包

傳輸層:接受上一層的數據,在必要的時候將數據進行分割。並將這些數據交給網絡層,且保證這些數據段有效的到達接收方。TCP協議,UDP協議

會話層:自動收發包,自動尋址。在不同機器上的用戶之間建立及管理會話,接觸或建立與別的節點的聯繫

表示層:解決不同系統之間通信語法不同的問題,數據加密,代碼轉化、將數據以網絡能理解的方案進行格式化。

應用層:規定接收方和發送方以一個固定長度的消息頭,例如文件傳輸、電子郵件、文件服務、虛擬終端等。HTTP協議

2. TCP/IP協議

TCP:傳輸控制協議

  • 面向連接的、可靠的、基於字節流的傳輸層通信協議
  • 將應用層的數據流分割成報文段併發送給目標節點的TCP層
  • 數據包都有序號,保證到目標節點的按序處理。對方收到則發送ACK確認,如果在合理的往返時延內未收到確認則重傳
  • 使用檢驗和來檢驗數據在傳輸過程中是否有誤

TCP報文頭部結構
在這裏插入圖片描述

  1. 源端口和目的端口: 各佔2個字節,分別寫入源端口號和目的端口號,源端口號在需要對方回信時選用,目的端口在終點交付報文的時必須使用

  2. 序號:在一個TCP連接中傳送的字節流中的每一個字節都按順序編號

  3. 確認號:是期望收到對方下一個報文段的第一個數據字節的序號。若確認號 = N,則表明:到序號N-1爲止的所有數據都已正確收到

  4. 數據偏移: 指出TCP報文段的數據起始處距離TCP報文段的起始處有多遠

  5. Flags

    • URG:緊急指針標誌,爲1表明緊急指針有效,告訴系統此報文段中有緊急數據,優先級高
    • ACK:確認序號標誌,僅當ACK=1時確認號字段纔有效。TCP規定,在連接建立後所有穿梭那個的報文段必須把ACK置爲1
    • PSH:push標誌,用於提高優先級
    • RST:重置連接標誌,當RST=1時,表明TCP連接中出現嚴重差錯,必須釋放連接並重新建立連接
    • SYN:在連接時用來同步序號,當SYN=1而ACK=0時,表明這是一個連接請求的報文段,對方若同意建立連接,則響應的報文端中ACK=1且SYN=1。
    • FIN: 用於釋放一個連接,當FIN=1時,表明此報文段數據已發送完畢,並要求釋放連接。
  6. 窗口: 窗口值作爲接收方讓發送方設置其發送窗口的依據,用於流量控制

  7. 檢驗和: 檢驗和字段檢驗的範圍包括首部和數據兩部分

  8. 緊急指針: 僅在URG=1時纔有效,用於指出本報文段中的緊急數據的字節數。

  9. 可選項: 僅用於使整個TCP報文的首部長度是4的整數倍

TCP的三次握手
在這裏插入圖片描述

  1. 假設A、B首次建立通信
  2. 服務端創建傳輸控制塊TCP時刻監聽客戶端發送的請求,服務端進入Listen狀態
  3. 客戶端創建傳輸控制塊TCP向服務器發送連接請求報文,SYN=1 初始序號爲 x,客戶端進入SYN-SENT(同步已發送)狀態 (第一次握手)
  4. 服務端收到請求報文後,若同意建立連接,則向A發送確認報文段、在確認報文段中應把ACK 和 SYN都置爲1,確認號ack=x+1(因爲請求報文段中消耗了一個序號)、爲自己的緩存初始化序列號seq=y。服務端進入SYN-RCVD(同步收到)狀態 (第二次握手)
  5. 客戶端接收到服務端的確認報文後,還要給服務端發送確認報文,確認報文中ACK=1、確認號ack=y+1,自己的序號seq=x+1,這時TCP連接已經建立,客戶端和服務端進入ESTANLISHED(已建立連接)狀態 (第三次握手)

爲什麼需要三次握手才能建立連接

  1. 爲了初始化seq(序號)的初始值,以保證傳輸的數據不會因爲網絡上的問題而亂序

  2. 首次握手時的隱患——SYN超時

    • 問題起因分析

      1. 客戶端收到服務端的SYN,回覆的SYN-ACK的時候未收到ACK確認

      2. 服務端不斷重試直至超時,Linux默認等待63s才能斷開連接

        • 針對SYN Flood的防護措施

          • SYN隊列滿後,通過tcp_syncookies參數回發SYN Cookie
          • 若爲正常連接則服務端會回發SYN-COOKIE,直至完成連接
      3. 建立連接後,客戶端出現故障怎麼辦

        • 向對方發送保活探測報文,如果未收到響應則繼續發送
        • 嘗試次數打到保活探測數仍未收到響應則中斷連接

TCP的四次揮手
在這裏插入圖片描述

  1. 假設數據傳輸過程中,由客戶端進程主動關閉,則服務端被動關閉

  2. 客戶端進程先向其TCP發送***連接釋放***報文段,並停止再發送數據,連接釋放報文段中將終止控制位FIN置爲1,seq=u(等於已傳送過的數據的最後一個字節的序號加1)客戶端進入FIN–WAIT-1(
    終止等待)狀態,等待B確認。FIN報文段即使不攜帶數據,它也消耗一個序號。 (第一次揮手)

  3. 服務端進程收到連接釋放報文段後即發出確認,確認號是ack=u+1,seq爲v(等於客戶端前面已傳送的數據的最後一個字節的序號加1),然後服務端進入CLOSE-WAIT(關閉等待)狀態。TCP服務器此時會通知高層應用進程,因爲從客戶端到服務端這個方向的連接就被釋放了,這是TCP連接處於半關閉狀態,這時客戶端已經沒有數據向服務端發送了,但是服務端要發送數據,客戶端仍要接收。也就是說,從服務端到客戶端這個方向的連接還沒有關閉,這個狀態可能會持續一段時間。(第二次揮手)

  4. 客戶端收到服務端的確認後,就進入FIN-WAIT-2(終止等待2)狀態,等待服務端發送的連接釋放報文段。

  5. 若服務端已經沒有向客戶端發送的數據,其應用程序就通知TCP釋放連接,這時服務端發送的連接釋放報文必須時FIN置爲1,假定服務端進程的序號爲w(在半關閉狀態可能又發送了一部分數據)。服務端還必須重複上次已經發送的確認號ack=u+1,這時服務端進程進入LAST-ACK(最後確認)狀態,等待客戶端的確認。 (第三次揮手)

  6. 客戶端收到服務端發送的連接釋放報文後,必須對此進行確認。在確人報文段中吧ACK置爲1,確認號ack=w+1,而自己的序號seq=u+1,然後進入TIME-WAIT(時間等待)狀態。此時客戶端進程的TCP連接還沒有釋放掉,必須等待時間等待計時器設置的時間2MSL之後,客戶端才能進入CLOSED狀態。RFC793建議爲2min,Linux爲30s,而服務端接收到客戶端的確認報文後,立即進入CLOSED狀態關閉連接。(第四次揮手)

爲什麼會有TIME-WAIT狀態(爲什麼要等待2MSL)

  1. 確保有足夠的時間讓對方收到ACK包
  2. 避免新舊連接混淆

爲什麼需要四次揮手才能斷開連接

  1. 因爲TCP協議是全雙工,發送方和接收方都需要FIN報文和ACK報文

服務器出現大量CLOSE_WAIT狀態的原因

  1. 客戶端發送了一個連接釋放的報文之後,服務器端沒有發送確認報文,即客戶端關閉了socket連接,但服務端忙於讀或寫,沒有及時的關閉連接。

    • 檢查代碼,特別是釋放資源的代碼
    • 檢查配置,特別是處理請求的線程配置
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章