重溫TCP通信過程

文章目錄

    • 1. 慢啟動
    • 2. 擁塞避免
  • 3. 快速重傳和快速恢復

初識tcp報文

我們先來簡單認識一下報文的格式,具體理解需要后面詳細介紹

  1. 源端口和目的端口:顧名思義就是標識傳輸雙方的信息
  2. 首部長度:指的是TCP報頭的長度,換句話來說,我們需要用一個屬性來描述報頭的長度,就說明TCP的報頭是變長的
  3. 選項:實際上這里翻譯為"可選項"更加準確,這是TCP為了適應復雜的網絡環境和更好的服務應用層而進行設計的,TCP選項部分最長可以達到40byte ,再加上TCP選項外的固定的20byte字節部分, TCP的最長頭部可達60byte
  4. 序列號:在一個TCP連接中傳輸的字節流中的每一個字節都按順序編號,該字段表示本報文所發送的數據的第一個字節的序號
  5. 確認號:表示期待收到對方下一個報文段的第一個數據字節的字段,例如當確認號為N,表示序列號N-1之前的所有數據都已全部接收到
  6. 窗口:通知發送端,接收端可接受的空間大小
  7. 校驗和:發送端計算發送的TCP報文段的校驗和,接收端對接收到的TCP報文段,驗證其校驗和,如果不一致,說明數據包在發送端和接受端之間傳輸的時候發生了變動,此時該TCP報文會被直接丟棄
  8. 保留位: TCP報頭里,提前申請好的一塊空間,這個空間暫時用不上,但是說不定以后就能夠用的上(萬一以后TCP要擴展一些新的功能,就可以用這個保留位來表示了)
  9. 6位標志位:他們中的一位或者多位可以同時設置為1,用于說明該報文性質,其中下面三個字段需要格外注意:
    1. ACK,僅當ACK為1的時候,確認號字段才有效,TCP規定,當連接建立之后,所有傳輸的報文都必須將ACK設置為1
    2. SYN,僅在三次握手建立TCP連接時有效,當SYN=1,ACK=0時,表明這是一個連接請求報文,若對方同意連接,則在響應報文中設置SYN=1 和 ACK = 1
    3. FIN,用來釋放一個連接,當FIN=1時,表示此報文的發送方的數據已經發送完畢,并要求釋放連接

三次握手建立連接

為了確保通信雙方都能**確認對方的存在和可用性**,并且**數據能夠被正確的傳輸和接收**,TCP要求通信雙方建立一條可靠的通信連接

三次握手是TCP協議中用于建立可靠連接的過程:

  1. A向B發送一個SYN報文,請求建立連接

  1. B收到A的SYN報文后回復一個SYN + ACK的報文

  1. A收到B的SYN報文之后,回復一個ACK報文

  1. B接受到ACK報文之后,表示一個TCP連接就建立好了

如果對上面的建立連接過程不懂,可以看下面的例子:

那么此時就很容易發現,為什么一定要三次握手??兩次行不行??

答案是否定的,因為只有經過最后一次交互,B才能知道對方的接受能力和自己的發送能力是沒問題的

分段機制

TCP經過三次握手之后就能發送數據了,但是一般網絡不能連續的傳輸任意長的數據,因此,發送方A將需要傳輸的消息分割成小快,按照順序分別發送,這些小塊就是數據包

B接受到數據報之后,經過校驗和校驗無誤之后,開始將收到的數據包進行重新組裝,還原成原始消息

但是可想而知,數據包組裝需要安裝分割前的順序進行拼接,但是我們確不能保證B接受數據包的順序和我們傳輸的順序是一致的,因為在網絡傳輸過程中會經過很多交換機和路由器的傳輸,而不同的設備傳輸速度,負載情況,網絡擁堵等因素都會影響數據包的傳輸順序

為了解決這個問題,TCP在數據包的頭部定義了一個序列號的字段,用于對在一個TCP連接中傳輸的字節流中的每一個字節按順序進行編號,就可以解決亂序的問題了

確認應答+超時重傳機制

為了保證所有的數據包都能夠正確接收,TCP引入了確認應答機制

B在接收到數據之后,會回復一個攜帶確認號的確認包,也就是ACK包,A接收到ACK報之后,再發送下一個數據包

如果結果一段等待時間之后,發送包無法知道數據包的情況,則可能出現以下的情況:

解決這個問題的一般方法是超時重傳,A在發送數據包之后,不會一直等待,而是啟動一個重傳定時器,定時到期之后未收到數據包,就會認為數據包丟失了,從而重傳數據包

滑動窗口機制

在上面確認應答機制的情況下,A只有當接收到B回復的ACK包之后,才能繼續發送下一個數據包

在這種場景下,發送方大多數時間都是在等待接收方的ACK中,極大的影響了通信的效率

一種解決問題的方法就是滑動窗口,這種機制允許發送方連續發送多個數據包而無需等待

TCP使用一個稱為發送窗口的變量,表示無需等待確認即可發送的數據包的數量

那么發送窗口的大小設置為多少才是合理的呢?

如果太小,那就和我們上面簡單的確認應答機制沒什么區別了

如果太大,接收方可能會來不及處理而丟失數據包,得不償失

TCP使用滑動窗口的機制,要求接收方維護一個可處理的接收窗口,發送方根據接收窗口來調整發送窗口的大小,從而根據接收方的接受能力來動態控制流量

通信雙方每次在發送數據時,都會在TCP報頭中攜帶窗口的大小.表示自己當前的接收能力

前面我們說過為了保證所有數據包都被收到,要求每個數據包接收到之后都要返回一個ACK包

延時應答 +累計確認

在滑動窗口的場景下,如果每個數據包都要回復一個ACK包的話,過多的確認包會消耗網絡資源,降低網絡利用率

對于累計確認來說,就是如果接收方返回確認號為N的ACK包,則表明N之前但不包括N的數據包已經全部接收到了

而延遲確認指的是接收方在接收到數據包之后不立即回復,而是延遲等待一段時間,這樣在延遲的時間內收到多個連續的包可以累計成一個ACK確認

通過這兩種方式,減少了ACK包的數量,提高了網絡利用率

快速重傳機制

前面說過,接收方等待一定時間之后,如果未接收到ACK包,就會觸發超時重傳

但是還是需要等待一定時間,降低了傳輸效率

TCP引入了快速重傳機制:當接收方連續收到三個相同的確認號的時候,就會觸發快速重傳,立即重傳數據包,而不必等待超時時間

擁塞控制

滑動窗口只考了接收方的處理能力,發送端根據接收窗口的大小發送數據,而忽略了網絡的負載情況

隨著網絡連接數量的增加,必然會造成網絡擁堵,就可能引起大量的超時重傳,形成惡性循環,造成整個網絡不可用

因此要進行擁塞控制來避免這種情況的發生

擁塞控制的主要思路是防止過多數據注入網絡,以避免網絡出現負載過大,也就是要根據網絡擁塞情況,對發送數據包的數據進行控制

TCP定義了一個擁塞窗口的變量,如果網絡擁堵就減少擁塞窗口,暢通就增加擁塞窗口

我們前面說過,發送窗口的大小等于接收窗口的大小

現在引入擁塞窗口之后,發送窗口的大小就等于擁塞窗口和接收窗口中的最小值,這樣就能有效控制網絡的發送效率

其中Reno算法是當前應用最廣泛的擁塞控制算法

主要包含慢啟動、擁塞避免、快速重傳、快速回復

1. 慢啟動

剛接入網絡的時候先發送少量數據包,探測網絡情況,然后再一點點逐步提高發送包的數量

2. 擁塞避免

慢啟動的指數級別增長不可能一直持續下去,當發生網絡擁堵的時候,慢啟動增長就會結束

同時TCP定義了一個慢啟動閾值的變量,當擁塞窗口超過這個閾值,就會進入擁塞避免模式,結束指數級增長

假設我們這個閾值是8,當超過8之后,就會以1的數量級增加,以線性增長,這種線性增長的方式相對于指數增長的方式更加穩定,可以避免網絡擁塞的發生

但是也不能一直增長,和慢啟動一樣,當發生網絡擁堵的時候,擁塞窗口的增長就會結束

那么網絡擁堵是怎么感知到的?? 同時擁塞窗口又怎么調整呢?

TCP是通過丟包來感知網絡擁堵狀態的

丟包可以分為兩種

  1. 超時丟包

也就是經過一段等待時間之后,還沒收到ACK包,這種情況說明網絡擁堵比較嚴重,TCP會進入慢啟動模式,并將慢啟動閾值設置為出現丟包時候的擁塞窗口的一般,重新開始慢啟動,后擁塞避免…

  1. 第二種是收到三次重復的ACK

此時就會認為之前發送的數據包丟失,這種情況下認為當前網絡發生了輕微擁堵,此時擁塞窗口減小的幅度不會像超時丟包那么大,會執行快速重傳和快速恢復算法

3. 快速重傳和快速恢復

  1. 將慢啟動閾值設置為當前擁塞窗口的一半,并重傳丟失的數據包
  2. 將擁塞窗口設置為當前慢啟動閾值加上3,這是因為,發送方收到了3個相同的ACK說明當前已經有三個數據包到達了接收端,網絡的"在途數據量"減少了三個,此時將擁塞窗口加上3,就是適當將擁塞窗口盡可能的變大些
  3. 再次收到重復的ACK,將擁塞窗口增加1
  4. 當收到新的數據包的ACK的時候,將擁塞窗口設置為第一步設置的閾值的值,此時快速恢復結束,再次進入擁塞避免階段

實際上第一次學我也是云里霧里的,這里有必要通過一個例子來解釋一下我的理解:

  1. cwnd(擁塞窗口)=9,此時發送9個數據包(序號1-9)
  2. 假設5數據包丟失,但是報文6~9正常到達接收端
  3. 接收端每次接受到6~9的數據包,都會回復一個ACK=5,發送端連續收到了3個ACK
  4. 觸發快速重傳,立即重傳丟失的報文5,同時更新閾值(ssthresh= cwnd / 2 = 4.5 = 4)
  5. 進入快速恢復階段,設置cwnd = ssthresh+3 = 7,加3是因為,由于已經收到了3個重復的ACK,說明(6,7,8)報文已經成功到達了接收端,可以將窗口向上提3個大小,不會導致下降太多
  6. 在等待ACK=5的報文階段,允許發送新的報文(10~13),此時又會收到連續的重復的ACK=5,此時每收到一個就將cwnd+1,原因和5一樣
  7. 當收到新的ACK=6,說明網絡恢復,此時重置窗口cwnd=4,退出快速回復,進入擁塞避免階段,為什么要重新降低?? 我覺得有以下原因
    1. 快速恢復階段通過臨時增大窗口(**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">cwnd = ssthresh + 3</font>**)來維持數據傳輸,但此時網絡可能仍處于敏感狀態,若繼續保持這個值,可能會導致擁塞循環
    2. 重置窗口后,TCP進入擁塞避免階段,確保窗口增長更平滑,避免突然的流量激增。

四次揮手結束通信

TCP是全雙工的,每個方向可以同時傳遞數據,因此每個方向需要單獨的關閉
  1. A方發送FIN來終止這個方向上的傳輸,待對方確認(返回ACK)后進入半關閉狀態(也就是說A此時還能接受B發送來的數據 ,因為只是A認為自己結束了,B可能還在發送)
  2. B發現自己數據發送完畢之后,發送給AFIN來終止傳輸,待A確定后(返回ACK)終斷連接

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/78722.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/78722.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/78722.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

力扣HOT100之鏈表:23. 合并 K 個升序鏈表

這道題我是用最淳樸最簡單的思路去做的&#xff0c;用一個while循環持續地將當前遍歷到的最小值加入到合并鏈表中&#xff0c;while循環中使用一個for循環遍歷整個指針數組&#xff0c;將其中的最小值和對應下標記錄下來&#xff0c;并將其值加入到合并鏈表中&#xff0c;同時對…

Spring Boot 支持政策

&#x1f9d1;&#x1f4bb; Spring Boot 支持政策 ?? Andy Wilkinson 于2023年12月7日編輯本頁 32次修訂 &#x1f4cc; 核心政策 &#x1f6e1;? VMware Tanzu 開源支持政策 Spring Boot 針對關鍵錯誤和安全問題提供支持 &#x1f4c6; 版本支持周期 1?? 主要版本&a…

WeakAuras Lua Script TOC BOSS2 <Lord Jaraxxus>

WeakAuras Lua腳本&#xff08;WA 字符串&#xff09; 十字軍試煉老2 加拉克蘇斯 血肉成灰 !WA:2!TIv7VnYrz8UXuDudiDN7PqFfCdTHKYLOeN7sBpXvKDIZf36Kyw7KRT3DYE2Dh7DAwV7CZSoXUOIewf4GdAfgbu13LPasv8MS4diavKoH4RSkIp0phXDT8je5FGYZmZU2oVCqrGLJZUpZZoZZB)EEz1wkr9ewjSU6MD5u…

Spring security詳細上手教學(二)用戶管理

Spring security詳細上手教學&#xff08;二&#xff09;用戶管理 這章節主要學習&#xff1a; 如何使用UserDetails接口描述用戶在鑒權流中使用UserDetailsService自定義的UserDetailsService實現自定義的UserDetailsManager實現在鑒權中使用JdbcUserDetialsManager 在Spri…

網絡安全廠商F5榮登2025 CRN AI 100榜單,釋放AI潛力

近期&#xff0c;網絡安全廠商F5憑借其應用交付和安全技術與前沿的人工智能洞察&#xff0c;成功入選“2025 CRN AI 100 榜單”&#xff0c;并躋身“領導者”之列。這一榮譽的獲得&#xff0c;彰顯了F5在助力企業擁抱人工智能創新的過程中&#xff0c;無需犧牲性能、靈活性或安…

4.RabbitMQ - 延遲消息

RabbitMQ延遲消息 文章目錄 RabbitMQ延遲消息一、延遲消息介紹二、實現2.1 死信交換機2.2 延遲消息插件2.3 取消超時訂單 一、延遲消息介紹 延遲消息&#xff1a;生產者發送消息時指定一個時間&#xff0c;消費者不會立刻收到消息&#xff0c;而是在指定時間后才收到消息 用戶…

5.學習筆記-SpringMVC(P53-P60)

1.響應 &#xff08;1&#xff09;響應頁面 &#xff08;2&#xff09;響應數據&#xff08;異步提交&#xff09;&#xff1a;文本數據、json數據 2.REST風格 (1)REST:表現形式狀態轉換。 (2)傳統風格資源描述形式 3.Restful入門案例 5.基于RESTful頁面數據…

Golang | 搜索表達式

// (( A | B | C ) & D ) | E & (( F | G ) & H )import "strings"// 實例化一個搜索表達式 func NewTermQuery(field, keyword string) *TermQuery {return &TermQuery{Keyword: &Keyword{Field: field, Word: keyword},} }func (tq *TermQuery…

LangChain構建大模型應用之RAG

RAG(Retrieval-augmented Generation 檢索增強生成)是一種結合信息檢索與生成模型的技術,通過動態整合外部知識庫提升大模型輸出的準確性和時效性。其核心思想是在生成答案前,先檢索外部知識庫中的相關信息作為上下文依據,從而突破傳統生成模型的靜態知識邊界。 為什么我們…

Ubuntu 下 Nginx 1.28.0 源碼編譯安裝與 systemd 管理全流程指南

一、環境與依賴準備 為確保編譯順利&#xff0c;我們首先更新系統并安裝必要的編譯工具和庫&#xff1a; sudo apt update sudo apt install -y build-essential \libpcre3 libpcre3-dev \zlib1g zlib1g-dev \libssl-dev \wgetbuild-essential&#xff1a;提供 gcc、make 等基…

第十二章-PHP文件上傳

第十二章-PHP文件上傳 一&#xff0c;文件上傳原理 一、HTTP協議與文件上傳 1. 請求體結構 當表單設置enctype"multipart/form-data"時&#xff0c;瀏覽器會將表單數據編碼為多部分&#xff08;multipart&#xff09;格式。 Boundary分隔符&#xff1a;隨機生成的…

CSS元素動畫篇:基于當前位置的變換動畫(三)

基于當前位置的變換動畫&#xff08;三&#xff09; 前言縮放效果類元素動畫脈沖動畫效果效果預覽代碼實現 橡皮筋動畫效果效果預覽代碼實現 果凍動畫效果效果預覽代碼實現 歡呼動畫效果效果預覽代碼實現 心跳動畫效果效果預覽代碼實現 結語 前言 CSS元素動畫一般分為兩種&…

Redis ssd是什么?Redis 內存空間優化的點都有哪些?embstr 和 row、intset、ziplist分別是什么?

Redis SSD 是什么&#xff1f; Redis SSD 通常指 Redis 使用 SSD&#xff08;固態硬盤&#xff09;作為持久化存儲介質的場景。雖然 Redis 是內存數據庫&#xff08;數據主要駐留內存&#xff09;&#xff0c;但其持久化機制&#xff08;如 RDB 快照和 AOF 日志&#xff09;需…

【藍橋杯】 數字詩意

數字詩意 在詩人的眼中&#xff0c;數字是生活的韻律&#xff0c;也是詩意的表達。 小藍&#xff0c;當代頂級詩人與數學家&#xff0c;被賦予了”數學詩人”的美譽。他擅長將冰冷的數字與抽象的詩意相融合&#xff0c;并用優雅的文字將數學之美展現于紙上。 某日&#xff0…

DHCP 服務器運行流程圖

以常見的 DHCP v4 為例,其完整流程如下: 一、客戶端請求 IP 地址階段 DHCPDiscover:客戶端啟動后,會以廣播的形式發送 DHCPDiscover 報文,目的是在網絡中尋找可用的 DHCP 服務器。該報文中包含客戶端的 MAC 地址等信息,以便服務器能夠識別客戶端。DHCPOffer:網絡中的 D…

一種企業信息查詢系統設計和實現:xujian.tech/cs

一種企業信息查詢系統設計和實現&#xff1a;xujian.tech/cs 背景與定位 企業在對外合作、風控審查或市場調研時&#xff0c;常需快速獲取公開的工商信息。本文介紹一個企業信息搜索引擎&#xff0c;面向普通用戶與開發者&#xff0c;幫助快速定位企業名稱、統一社會信用代碼…

前端面試高頻算法

前端面試高頻算法 1 排序算法&#xff1b;1.1 如何分析一個排序算法1.1.1 執行效率3.1.2 內存消耗1.1.3 穩定性 1.2 冒泡排序&#xff08;Bubble Sort&#xff09;1.3 插入排序&#xff08;Insertion Sort&#xff09;1.4 選擇排序&#xff08;Selection Sort&#xff09;1.5 歸…

C++初階-模板初階

目錄 1.泛型編程 2.函數模板 2.1函數模板概念 2.2實現函數模板 2.3模板的原理 2.4函數模板的實例化 2.4.1隱式實例化 2.4.2顯式初始化 2.5模板參數的匹配原則 3.類模板 3.1類模板定義格式 3.2類模板的實例化 4.總結 1.泛型編程 對廣泛的類型法寫代碼&#xff0c;我…

「Mac暢玩AIGC與多模態02」部署篇01 - 在 Mac 上部署 Ollama + Open WebUI

一、概述 本篇介紹如何在 macOS 環境下本地部署 Ollama 推理服務,并通過 Open WebUI 實現可視化交互界面。該流程無需 CUDA 或專用驅動,適用于 M 系列或 Intel 芯片的 Mac,便于快速測試本地大語言模型能力。 二、部署流程 1. 環境準備 安裝 Homebrew(如尚未安裝):/bin…

JavaScript 中 undefined 和 not defined 的區別

在 JavaScript 的調試過程中&#xff0c;你是否經常看到 undefined 卻不知其來源&#xff1f;是否曾被 ReferenceError: xxx is not defined 的錯誤提示困擾&#xff1f;這兩個看似相似的概念&#xff0c;實際上是 JavaScript 類型系統中最重要的分水嶺。本文將帶你撥開迷霧&am…