網絡編程(12): TCP重傳、滑動窗口、流量控制、擁塞控制

1、TCP重傳機制

通過序列號和確認號確保可靠傳輸,當發送端發送數據給接收到,接收端會返回一個確認號,表示收到消息了

  • 超時重傳:沒有在指定時間內收到ACK報文
    • 超時重傳的兩種可能:數據包丟失確認包丟失
    • 超時重傳時間RTO:
      • RTO較大:重發就變慢了,丟包之后需要半天才能重發,效率低
      • RTO較小:可能沒有丟包,還在等待ACK過程中,就重發了,會導致網絡擁塞,進而導致更多的超時重發
      • 所以RTO需要略大于報文往返的時間RTT(數據發送到接收到ACK的時間差)
    • 由于網絡波動問題,RTT可能不是固定的,所以RTO對應也不是固定的
    • 一般超時重傳一次,下一次超時重傳的間隔會加倍,避免網絡環境差的頻繁發送
  • 快速重傳
    • 超時重傳的問題:重傳周期可能很長(時間會加倍),快速重傳可以解決這個問題,以數據為驅動作為重傳
    • 發送了數據包seq1~seq5,
      • 發送端發送seq1,接收端回復ack=2,表示接收到包1
      • seq2丟失
      • 發送端連續發送seq3~seq5,接收端會重復返回ack=2
      • 連續三次ack=2,觸發快速重傳,重復seq2
      • 由于接收到了seq3~seq5,發送端會返回ack=6
    • 快速重傳只解決了超時問題,但是還有一個問題:重傳的時候重傳一個還是所有數據包
    • 因為如果只重傳一個,當有兩個數據包丟失的時候,需要判斷兩次返回的ack(三次重復),來進行單包重傳,效率低
    • 如果重傳所有,就會有多余的包被重新發送,無用功
  • SACK:選擇性確認,可以知道哪些數據丟失了
    • 需要TCP頭部選項字段中,添加一個SACK,可以將已接收到的數據的信息發送給發送方,發送方就知道了哪些數據丟失了,從而只發送丟失的數據
    • 在快速重傳的基礎上,發送方收到三次相同的ack報文,觸發快速重傳機制,通過SACK信息可以知道哪段數據丟失了,只對丟失的數據重傳
  • D-SACK:通過SACK告訴發送端哪些數據被重復接收了
    • 可以讓發送端知道是包丟失,還是ACK包丟失了
    • 可以知道發送的數據包是不是被網絡延遲了
    • 可以知道網絡中是不是把發送端的數據包給復制了
  • 小結:
    • 如果數據包丟失或者ACK包丟失,超過一定時間會觸發超時重傳,超時時間RTO略大于RTT時間(發送數據到接收ACK包的時間間隔)
    • 為了解決超時等待的時間,提高效率,就有了快速重傳,當有一個包丟失的時候,可以通過判斷重復的ack進行快速重傳,通過在TCP頭部的選項字段里面添加SACK,就可以知道哪些包是丟失的,從而只重傳丟失的包
    • 如果在ACK包丟失,導致的超時重傳,發送端接收到接收端SACK從而知道收到了重復數據,這個SACK就是D-SACK,如果一個包由于網絡問題導致的快速重傳,也可以通過D-SACK來進行判斷

2、TCP滑動窗口

TCP每次發送數據都要進行確認應答,當上一個包收到應答了再發下一個

  • 如果是一問一答的形式,則數據包往返的時間周期越長,通信效率就越低
  • 為了解決上面的問題,就有窗口概念,
    • 可以指定窗口大小,窗口大小是不需要等待確認應答,可以繼續發送數據的最大值
    • 窗口是內核里面開辟的緩存區,需要保留發送的數據,只有收到應答才會從緩沖區中刪除
    • TCP頭部可以指定窗口大小,發送端會根據ACK返回的窗口大小,來發送數據,從而保證對端可以正常接收數據,所以窗口大小是由接收端決定的
  • 發送端的窗口
    • 有兩個絕對指針:一個指向沒有收到ack的第一個字節的序列號, 一個指向窗口中可用空間的第一個字節的序列號
    • 會根據ACK報文中的窗口大小進行調整,因為應用層不一定及時收數據
    • 此外,如果發送端窗口滿了,沒有及時收到ACK,就不能在應用層進行發送數據,如果序列號較前的收到ack,窗口會向右移動,存在可發空間,應用層可以繼續拷貝發送數據
  • 接收端的窗口:可以接收發送端發送的數據量,一次能處理的數據量
    • 只有一個絕對指針,指向期望對端發送來的下一個字節的序列號
    • 窗口里面是還沒進行確認的數據,也就是還沒收到的數據,但是可以接收的數據大小
  • 發送端窗口約等于接收端窗口,因為傳輸存在延遲,不一定及時調整窗口大小,所以是約等于
  • 小結:
    • 三次握手確定窗口大小,接收端能接收多少數據,發送端根據接收端數據進行調整,去發送數據,在發送端窗口大小內,發送端可以一直發,并等待接收端返回ack確認號來發送窗口移動,每次ack報文都會攜帶窗口大小,可能會改變;

3、TCP流量控制

利用滑動窗口實現流量控制,發送端不能一股腦的發過去,如果對方處理不過來就會觸發重傳機制

  • 流量控制:發送方 根據 接收方的實際接收能力發送數據,也就是接收端滑動窗口的大小
  • TCP內核緩沖區和滑動窗口的關系:緩沖區大小會影響窗口大小
    • 應用層不及時收取數據,會導致窗口變小:
      • TCP滑動窗口(指針實現)是處于TCP緩沖區中間的,如果接收端接收到數據并返回ACK,但是應用層沒有及時收取,當緩沖區內存不夠,可能會導致滑動窗口變小,當窗口大小變成0,就發生了窗口關閉
    • 系統資源減少,會導致緩沖區變小:
      • 如果用戶空間沒有及時讀取緩沖區數據,并且接收緩沖區由于系統資源突然變小,發送端來不及調整,會導致數據丟包現象,這是因為先減少緩沖區再收縮窗口
      • 所以不允許同時減少緩沖又收縮窗口,而先收縮窗口后一段時間再減少緩沖,從而避免丟包
  • 窗口關閉
    • 窗口大小為0的情況,就會阻止發送端發送數據,直到大小變成非0
    • 如果接收端窗口變成非0,會通過發送攜帶窗口大小的ACK報文,如果ACK報文丟失,發送端會一直等待,造成死鎖問題
    • 如何避免死鎖問題:當窗口關閉,就會啟動一個持續計時器,如果超時就會發送一個窗口探測報文,接收端收到這個報文,就會返回一個攜帶當前窗口大小的ACK報文,如果窗口依舊為0,就會重啟持續計時器
  • 糊涂窗口綜合癥
    • 接收端太忙,會導致發送端的窗口越來越小,到最后只有接收端騰出字節空間,發送端就會馬上發送,但是TCP/IP包頭就有40字節,有數據就傳輸的話,開銷太大了
    • 導致的原因是:
      • 接收端告知小窗口大小
      • 發送端發送小數據
    • 如何避免:
      • 接收方不告知小窗口,窗口小于某個值就發送窗口為0的ACK,阻止對端發送數據
      • 發送發避免發送小數據,開啟Nagle算法,避免小包發送
  • Nagle算法思想,延時處理,滿足下面一個條件即可:
    • 窗口大小>=MSS并且數據大小>=MSS
    • 收到前一個數據的ack報文
  • 一般需要搭配 不通知小窗口給發送方+開啟Nagle算法才能避免糊涂窗口綜合癥

4、TCP擁塞控制

  • 流量控制:是為了避免,發送端 數據填滿 接收端的緩存,但是流量控制并不知道網絡中發送的情況

  • 網絡擁塞:網絡發生擁堵的時候,繼續發送大量數據包,就可能導致數據包延時、丟失等情況,TCP就會重傳數據,一旦重傳就會導致網絡更加擁堵,從而不斷惡性循環

  • 擁塞控制避免發送方的數據填滿整個網絡,并且為了調節發送數據的量,定義了一個擁塞窗口(cwnd)的概念

  • 擁塞窗口(cwnd):是發送方維護的一個狀態變量,會根據網絡的擁塞程度進行變化,滑動的發送窗口=min(滑動的接收窗口,擁塞窗口),當網絡沒有出現擁塞,cwnd窗口就會越大,當網絡出現擁塞,cwnd就會越小

  • 如何判斷網絡擁塞:發送方沒有在指定時間接收到ACK應答報文,也就是發送超時重傳,就會認為網絡出現擁塞了

  • 擁塞控制主要是四算法:

    • 慢啟動:(指數增長)
      • TCP建立連接后,一點點點提高數據包發送的數量,發送端沒收到一個ACK,擁塞窗口cwnd的大小就會+1;
      • 存在一個慢啟動門限ssthresh,如果cwnd<ssthresh使用的就是慢啟動算法,如果cwnd>=ssthresh,就使用擁塞避免算法;ssthresh一般大小為65535字節
    • 擁塞避免
      • 沒收到一個ACK,cwnd增加1/cwnd,是為了確保cwnd的線性增長
      • 如果一直保持增長,網絡就會慢慢進入擁塞狀態,從而出現了丟包現象
      • 如果觸發了重傳機制,就會進入擁塞發生算法
    • 擁塞發送
      • 發生重傳(超時、快速)的時候就會進入擁塞發生算法
      • 超時重傳的擁塞發生:
        • ssthresh會設置為cwnd/2,并且cwnd會回復為初始值,linux的初始值是10(10個MSS);
        • 設置完ssthreshcwnd之后,會重新開始慢啟動;
        • 這種方式下來的擁塞發生太激進了,容易造成網絡卡頓
      • 快速重傳的擁塞發生:
        • 設置cwndcwnd/2,再設置ssthreshcwnd
        • 設置完之后,會進入快速回復算法
    • 快速回復
      • 當發生快速重傳的時候,表示網絡不是太糟糕,一般快速回復和快速重傳同時使用
      • 進入快速回復前, cwndssthresh都全部設置完了
      • 快速回復
        • cwnd = ssthresh+3,3表示接收到了三個數據包
        • 重傳丟失的數據包;
        • 如果再收到重復的ACKcwnd就+1
        • 如果收到的是新的ACK,表示網絡沒問題了,則將cwnd設置為ssthresh,進入擁塞避免狀態;
  • 擁塞控制算法過程:

    • 從TCP三次握手建立連接開始,發送端開始慢啟動,沒收到一個包的ACK,擁塞窗口就會+1,如果達到閾值,就會進入擁塞避免算法,每收到一個包的ACK,擁塞窗口就會增加窗口的倒數,從而保證擁塞窗口的線性增加
    • 當遇到丟包的情況,就判斷為網絡擁塞,從而重復重傳機制,進入擁塞發送算法,根據重傳機制的不同,擁塞發送算法也會不同
    • 超時重傳,sthresh=cwnd/2,并且cwnd=初始值,重新重慢啟動開始
    • 快速重傳,cwnd=cwnd/2,ssthresh=cwnd,開啟快速回復
    • 快速回復:先是設置cwnd=ssthresh+3,并重傳丟失數據包,如果依舊重復收到相同的ACK,就會重復觸發快速重傳和快速回復,如果收到的是新的數據包,則進入擁塞避免狀態。

參考文章:小林coding

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

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

相關文章

第十三課:QtCmd 命令行終端應用程序開發

功能描述&#xff1a;開發一個類似于 Windows 命令行提示符或 Linux 命令行終端的應用程序 一、最終演示效果 QtCmd 不是因為它是 Qt 的組件&#xff0c;而是采用 Qt 開發了一個類似 Windows 命令提示符或者 Linux 命令行終端的應用程序&#xff0c;故取名為 QtCmd。 上述演示…

FreeMarker系列--list的用法(長度,遍歷,下標,嵌套,排序)

原文網址&#xff1a;FreeMarker系列--list的用法&#xff08;長度,遍歷,下標,嵌套,排序&#xff09;_IT利刃出鞘的博客-CSDN博客 簡介 本文介紹FreeMarker的list的用法。 大小 Java ArrayList<String> list new ArrayList<String>(); Freemaker ${list?s…

W5500-EVB-PICO 做UDP Server進行數據回環測試(七)

前言 前面我們用W5500-EVB-PICO 開發板在TCP Client和TCP Server模式下&#xff0c;分別進行數據回環測試&#xff0c;本章我們將用開發板在UDP Server模式下進行數據回環測試。 UDP是什么&#xff1f;什么是UDP Server&#xff1f;能干什么&#xff1f; UDP (User Dataqram P…

圖數據庫_Neo4j學習cypher語言_使用CQL命令002_刪除節點_刪除屬性_結果排序Order By---Neo4j圖數據庫工作筆記0006

然后我們再來看如何刪除節點 可以看到首先 我們這里 比如我要刪除張三 可以看到 match (n:student) where n.name = "張三" delete n 這樣就是刪除了student集合中,name是張三的節點 然后我們再來看 如何來刪除關系 match (n:student)-[r]->(m:student) where…

機器學習、cv、nlp的一些前置知識

為節省篇幅&#xff0c;不標注文章來源和文章的問題場景。大部分是我的通俗理解。 文章目錄 向量關于向量的偏導數&#xff1a;雅可比矩陣二階導數矩陣&#xff1a;海森矩陣隨機變量隨機場伽馬函數beta分布數學術語坐標上升法協方差訓練集&#xff0c;驗證集&#xff0c;測試集…

Nginx的安裝及負載均衡搭建

一.Nginx的安裝 1&#xff09;準備安裝環境 yum install -y make gcc gcc-c pcre-devel pcre zlib zlib-devel openssl openssl-develPERE PCRE(Perl Compatible Regular Expressions)是一個Perl庫&#xff0c;包括 perl 兼容的正則表達式庫。 nginx的http模塊使用pcre來解…

前端jd要求:了解一門后端開發語言優先 解決方案之Node.js

前端jd要求&#xff1a;了解一門后端開發語言優先 解決方案之Node.js 前言常見的后端開發語言一、什么是 Node.js二、學習 Node.js 的前置知識三、學習 Node.js 的步驟1、Node.js 的安裝2、Node.js 的基本語法和 API模塊導入和導出文件讀寫操作HTTP 服務器命令行參數 3、Node.j…

可能導致不可接受的信息安全事件發生的核電站事故。

立陶宛伊格納利納核電站&#xff08;1992 年&#xff09; 一名在該核電站工作的程序員將惡意代碼上傳到一個負責反應堆子系統運行的自動化系統中&#xff0c;該系統被及時發現。 但如果沒有及時發現&#xff0c;誰知道會發生什么呢&#xff1f;核電站被關閉以進行調查。有關這…

Vue-8.集成(.editorconfig、.eslintrc.js、.prettierrc)

介紹 同時使用 .editorconfig、.prettierrc 和 .eslintrc.js 是很常見的做法&#xff0c;因為它們可以在不同層面上幫助確保代碼的格式一致性和質量。這種組合可以在開發過程中提供全面的代碼維護和質量保證。然而&#xff0c;這也可能增加一些復雜性&#xff0c;需要謹慎配置…

Coreutils工具包,Windows下使用Linux命令

之前總結過兩篇有關【如何在Windows系統下使用Linux的常用命令】的文章&#xff1a; GnuWin32&#xff0c;Windows下使用Linux命令 UnxUtils工具包&#xff0c;Windows下使用Linux命令 今天再推薦一個類似的工具包Coreutils 一、簡介 GNU core utilities是GNU操作系統基本…

【HDFS】hdfs的count命令的參數詳解

Usage: hadoop fs -count [-q] [-h] [-v] [-x] [-t [<storage type>]] [-u] [-e] [-s] <paths

(學習筆記-進程管理)怎么避免死鎖?

死鎖的概念 在多線程編程中&#xff0c;我們為了防止多線程競爭共享資源而導致數據錯亂&#xff0c;都會在操作共享資源之前加上互斥鎖&#xff0c;只有成功獲得到鎖的線程&#xff0c;才能操作共享資源&#xff0c;獲取不到鎖的線程就只能等待&#xff0c;直到鎖被釋放。 那…

創建一個簡單的HTML Viewer應用程序

使用wxPython和內嵌瀏覽器來創建一個簡單的HTML Viewer應用程序。 在本篇文章中&#xff0c;我們將使用Python和wxPython模塊來創建一個簡單的HTML Viewer應用程序。這個應用程序可以讓用戶輸入HTML內容&#xff0c;并在內嵌瀏覽器中顯示該內容的效果。 準備工作 在開始之前…

apache doris和StarRocks的區別

記錄一下最新要用到2個新數據庫的區別 Apache Doris是一個分布式的列式存儲系統&#xff0c;它的設計目標是提供大規模數據處理的可靠性和高性能。Doris采用了集群方式&#xff0c;通過將數據分布在多個機器上進行處理來提高性能&#xff0c;并提供了SQL查詢接口方便用戶使用。…

QT:定時器事件

定時器第一種辦法&#xff1a; 1.利用事件timerEvent&#xff0c;在幫助文檔中找到該字段&#xff1a;[override virtual protected] void QTimer::timerEvent(QTimerEvent *e) 重寫該虛函數 //重寫定時器事件void timerEvent(QTimerEvent *e);2.啟動定時器startTimer(1000); …

區間預測 | MATLAB實現QRGRU門控循環單元分位數回歸時間序列區間預測

區間預測 | MATLAB實現QRGRU門控循環單元分位數回歸時間序列區間預測 目錄 區間預測 | MATLAB實現QRGRU門控循環單元分位數回歸時間序列區間預測效果一覽基本介紹模型描述程序設計參考資料 效果一覽 基本介紹 MATLAB實現QRGRU門控循環單元分位數回歸時間序列區間預測。基于分位…

卷積神經網絡教程 (CNN) – 使用 TensorFlow 在 Python 中開發圖像分類器

在這篇博客中,讓我們討論什么是卷積神經網絡 (CNN) 以及 卷積神經網絡背后的架構——旨在解決 圖像識別系統和分類問題。 卷積神經網絡在圖像和視頻識別、推薦系統和自然語言處理方面有著廣泛的應用。 目錄 計算機如何讀取圖像? 為什么不是全連接網絡?

[GitOps]微服務版本控制:使用ArgoCD 部署Grafana Loki

背景介紹 請回答&#xff1a;你們是如何保證線上部署的服務&#xff0c;從服務版本到參數配置&#xff0c;都是和測試通過的版本是一致的呢&#xff1f; 本文將介紹GitOps的基本原理以及ArgoCD的使用&#xff1a;ArgoCD部署Grafana Loki 到k8s集群。 本文項目地址&#xff1…

詳細介紹如何使用 OpenCV 對圖像進行銳化

將了解銳化圖像的過程,我們將使用內核來突出顯示每個特定像素并增強其發出的顏色。它與模糊過程非常相似,只不過現在我們不是創建一個內核來平均每個像素強度,而是創建一個內核,該內核將使像素強度更高,因此對人眼來說更加突出。 了解流程的后端。 很高興知道內核用于模糊…

Nginx 解決api跨域問題

環境: nginx 1.22.1 寶塔8.0 php lavarel 在nginx里加入下面的設置 #這里填*就是任何域名都允許跨域add_header Access-Control-Allow-Origin "*";#CORS請求默認不發送Cookie和HTTP認證信息。但是如果要把Cookie發到服務器&#xff0c;要服務器同意&#xff0c…