TCP傳輸層協議(4)

TCP應用層協議(4)

流量控制

接收端處理數據的速度是有限的. 如果發送端發的太快, 導致接收端的緩沖區被打滿, 這個時候如果發送端繼續發送, 就會造成丟包, 繼而引起丟包重傳等等一系列連鎖反應.

因此 TCP 支持根據接收端的處理能力, 來決定發送端的發送速度. 這個機制就叫做流量控制(Flow Control);

? 接收端將自己可以接收的緩沖區大小放入 TCP 首部中的 “窗口大小” 字段, 通過 ACK 端通知發送端;

? 窗口大小字段越大, 說明網絡的吞吐量越高;

? 接收端一旦發現自己的緩沖區快滿了, 就會將窗口大小設置成一個更小的值通知給發送端;

? 發送端接受到這個窗口之后, 就會減慢自己的發送速度;

? 如果接收端緩沖區滿了, 就會將窗口置為 0; 這時發送方不再發送數據, 但是需要定期發送一個窗口探測數據段, 使接收端把窗口大小告訴發送端.

在這里插入圖片描述

接收端如何把窗口大小告訴發送端呢? 回憶我們的 TCP 首部中, 有一個 16 位窗口字段, 就是存放了窗口大小信息;

那么問題來了, 16 位數字最大表示 65535, 那么 TCP 窗口最大就是 65535 字節么?

實際上, TCP 首部 40 字節選項中還包含了一個窗口擴大因子 M, 實際窗口大小是 窗口字段的值左移 M 位;

擁塞控制

在這里插入圖片描述

如果是大面積丟包
在這里插入圖片描述

這時候如果我們是多個客戶端多個服務端呢

在這里插入圖片描述

滑動窗口是擁塞窗口和對方窗口的最小值,誰小誰是主要矛盾,即考慮了網絡擁堵問題和對方的接受能力,什么是擁塞窗口,擁塞窗口就是一個臨界值,網絡不會擁塞,這是衡量是否擁塞的標準

雖然 TCP 有了滑動窗口這個大殺器, 能夠高效可靠的發送大量的數據. 但是如果在剛開始階段就發送大量的數據, 仍然可能引發問題.

因為網絡上有很多的計算機, 可能當前的網絡狀態就已經比較擁堵. 在不清楚當前網絡狀態下, 貿然發送大量的數據, 是很有可能引起雪上加霜的.

TCP 引入 慢啟動 機制, 先發少量的數據, 探探路, 摸清當前的網絡擁堵狀態, 再決定按照多大的速度傳輸數據;

? 此處引入一個概念稱為擁塞窗口

? 發送開始的時候, 定義擁塞窗口大小為 1;

? 每次收到一個 ACK 應答, 擁塞窗口加 1;

? 每次發送數據包的時候, 將擁塞窗口和接收端主機反饋的窗口大小做比較, 取較小的值作為實際發送的窗口;

像上面這樣的擁塞窗口增長速度, 是指數級別的. “慢啟動” 只是指初使時慢, 但是增長速度非常快.

? 為了不增長的那么快, 因此不能使擁塞窗口單純的加倍.

? 此處引入一個叫做慢啟動的閾值

? 當擁塞窗口超過這個閾值的時候, 不再按照指數方式增長, 而是按照線性方式增長
在這里插入圖片描述

? 當 TCP 開始啟動的時候, 慢啟動閾值等于窗口最大值;

? 在每次超時重發的時候, 慢啟動閾值會變成原來的一半, 同時擁塞窗口置回 1;少量的丟包, 我們僅僅是觸發超時重傳; 大量的丟包, 我們就認為網絡擁塞;當 TCP 通信開始后, 網絡吞吐量會逐漸上升; 隨著網絡發生擁堵, 吞吐量會立刻下降;擁塞控制, 歸根結底是 TCP 協議想盡可能快的把數據傳輸給對方, 但是又要避免給網絡造成太大壓力的折中方案.

TCP 擁塞控制這樣的過程, 就好像 熱戀的感覺

延遲應答

如果接收數據的主機立刻返回 ACK 應答, 這時候返回的窗口可能比較小

? 假設接收端緩沖區為 1M. 一次收到了 500K 的數據; 如果立刻應答, 返回的窗口就是 500K;

? 但實際上可能處理端處理的速度很快, 10ms 之內就把 500K 數據從緩沖區消費掉了;

? 在這種情況下, 接收端處理還遠沒有達到自己的極限, 即使窗口再放大一些, 也能處理過來;

? 如果接收端稍微等一會再應答, 比如等待 200ms 再應答, 那么這個時候返回的窗口大小就是 1M;

一定要記得, 窗口越大, 網絡吞吐量就越大, 傳輸效率就越高. 我們的目標是在保證網絡不擁塞的情況下盡量提高傳輸效率;

那么所有的包都可以延遲應答么? 肯定也不是;

? 數量限制: 每隔 N 個包就應答一次;

? 時間限制: 超過最大延遲時間就應答一次;

具體的數量和超時時間, 依操作系統不同也有差異; 一般 N 取 2, 超時時間取 200ms;

在這里插入圖片描述

捎帶應答

在延遲應答的基礎上, 我們發現, 很多情況下, 客戶端服務器在應用層也是 “一發一收” 的. 意味著客戶端給服務器說了 “How are you”, 服務器也會給客戶端回一個 “Fine,thank you”;那么這個時候 ACK 就可以搭順風車, 和服務器回應的 “Fine, thank you” 一起回給客戶端

面向字節流

創建一個 TCP 的 socket, 同時在內核中創建一個 發送緩沖區 和一個 接收緩沖區;

? 調用 write 時, 數據會先寫入發送緩沖區中;

? 如果發送的字節數太長, 會被拆分成多個 TCP 的數據包發出;

? 如果發送的字節數太短, 就會先在緩沖區里等待, 等到緩沖區長度差不多了, 或者其他合適的時機發送出去;

? 接收數據的時候, 數據也是從網卡驅動程序到達內核的接收緩沖區;

? 然后應用程序可以調用 read 從接收緩沖區拿數據;

? 另一方面, TCP 的一個連接, 既有發送緩沖區, 也有接收緩沖區, 那么對于這一個連接, 既可以讀數據, 也可以寫數據. 這個概念叫做 全雙工

由于緩沖區的存在, TCP 程序的讀和寫不需要一一匹配, 例如:

? 寫 100 個字節數據時, 可以調用一次 write 寫 100 個字節, 也可以調用 100 次write, 每次寫一個字節;

? 讀 100 個字節數據時, 也完全不需要考慮寫的時候是怎么寫的, 既可以一次read 100 個字節, 也可以一次 read 一個字節, 重復 100 次;

粘包問題

? 首先要明確, 粘包問題中的 “包” , 是指的應用層的數據包.

? 在 TCP 的協議頭中, 沒有如同 UDP 一樣的 “報文長度” 這樣的字段, 但是有一個序號這樣的字段.

? 站在傳輸層的角度, TCP 是一個一個報文過來的. 按照序號排好序放在緩沖區中.

? 站在應用層的角度, 看到的只是一串連續的字節數據.

? 那么應用程序看到了這么一連串的字節數據, 就不知道從哪個部分開始到哪個部分, 是一個完整的應用層數據包. 那么如何避免粘包問題呢? 歸根結底就是一句話, 明確兩個包之間的邊界.

? 對于定長的包, 保證每次都按固定大小讀取即可; 例如上面的 Request 結構, 是固定大小的, 那么就從緩沖區從頭開始按 sizeof(Request)依次讀取即可;

? 對于變長的包, 可以在包頭的位置, 約定一個包總長度的字段, 從而就知道了包的結束位置;

? 對于變長的包, 還可以在包和包之間使用明確的分隔符(應用層協議, 是程序猿自己來定的, 只要保證分隔符不和正文沖突即可);

思考: 對于 UDP 協議來說, 是否也存在 “粘包問題” 呢?

? 對于 UDP, 如果還沒有上層交付數據, UDP 的報文長度仍然在. 同時, UDP 是一個一個把數據交付給應用層. 就有很明確的數據邊界.

? 站在應用層的站在應用層的角度, 使用 UDP 的時候, 要么收到完整的 UDP 報文, 要么不收. 不會出現"半個"的情況.

TCP 異常情況

進程終止: 進程終止會釋放文件描述符, 仍然可以發送 FIN. 和正常關閉沒有什么區別.

機器重啟: 和進程終止的情況相同.

機器掉電/網線斷開: 接收端認為連接還在, 一旦接收端有寫入操作, 接收端發現連接已經不在了, 就會進行 reset. 即使沒有寫入操作, TCP 自己也內置了一個保活定時器, 會定期詢問對方是否還在. 如果對方不在, 也會把連接釋放.

另外, 應用層的某些協議, 也有一些這樣的檢測機制. 例如 HTTP 長連接中, 也會定期檢測對方的狀態. 例如 QQ, 在 QQ 斷線之后, 也會定期嘗試重新連接

TCP 小結

為什么 TCP 這么復雜? 因為要保證可靠性, 同時又盡可能的提高性能.

可靠性:

? 校驗和

? 序列號(按序到達)

? 確認應答

? 超時重發

? 連接管理

? 流量控制

? 擁塞控制

提高性能:

? 滑動窗口

? 快速重傳

? 延遲應答

? 捎帶應答

其他:

為什么 TCP 這么復雜? 因為要保證可靠性, 同時又盡可能的提高性能.

可靠性:

? 校驗和

? 序列號(按序到達)

? 確認應答

? 超時重發

? 連接管理

? 流量控制

? 擁塞控制

提高性能:

? 滑動窗口

? 快速重傳

? 延遲應答

? 捎帶應答

其他:

? 定時器(超時重傳定時器, 保活定時器, TIME_WAIT 定時器等)

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

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

相關文章

雙向SSL認證之Apache實戰配置

防御未授權訪問,為企業級應用構筑雙重身份驗證防線 本文是關于Apache配置雙向SSL認證的深度技術指南,包含全流程操作、調試技巧及企業級解決方案,適用于運維工程師和安全管理員。 1.為什么需要雙向認證 ? 核心價值 &#x1f51…

JavaScript 實用工具方法小全

1. 精確獲取小數位數/*** 獲取數字的小數位數(支持科學計數法)* param {number|string} num - 要檢查的數字,可以是數字或字符串形式* returns {number} 返回小數部分的位數* * 實現原理:* 1. 處理科學計數法(如1.23e-…

【易錯題】C語言

今日遇到的易錯題 #include <stdio.h> int i;//全局變量默認初始化是0 int main() {i--;//-1if (i > sizeof(i)){printf(">\n");}else{printf("<\n");}return 0; }易錯點&#xff1a;sizeof的返回值類型實際為無符號整形&#xff0c;因此編…

第七十五章:AI的“思維操控師”:Prompt變動對潛在空間(Latent Space)的影響可視化——看懂AI的“微言大義”!

Prompt變動對潛在空間影響前言&#xff1a;AI的“思維操控師”——Prompt變動對潛在空間的影響可視化&#xff01;第一章&#xff1a;痛點直擊——Prompt“難伺候”&#xff1f;改一個字就“面目全非”&#xff01;第二章&#xff1a;AI的“思維圣地”&#xff1a;潛在空間&…

【計算機視覺與深度學習實戰】03基于Canny、Sobel和Laplacian算子的邊緣檢測系統設計與實現

第一章 引言 邊緣檢測作為計算機視覺和圖像處理領域的核心技術之一,在現代數字圖像分析中占據著舉足輕重的地位。邊緣是圖像中亮度變化劇烈的區域,通常對應著物體的輪廓、表面方向的不連續性、材質變化或照明條件的改變。準確而高效的邊緣檢測不僅是圖像分割、特征提取、模式…

【大語言模型 02】多頭注意力深度剖析:為什么需要多個頭

多頭注意力深度剖析&#xff1a;為什么需要多個頭 - 解密Transformer的核心升級 關鍵詞&#xff1a;多頭注意力、Multi-Head Attention、注意力頭、并行計算、特征學習、Transformer架構、深度學習 摘要&#xff1a;在掌握了Self-Attention基礎后&#xff0c;本文深入探討多頭注…

Python Condition對象wait方法使用與修復

在 Python 中&#xff0c;Condition 對象用于線程同步&#xff0c;其 wait() 方法用于釋放鎖并阻塞線程&#xff0c;直到被其他線程喚醒。使用不當可能導致死鎖、虛假喚醒或邏輯錯誤。以下是常見問題及修復方案&#xff1a;常見問題與修復方案1. 未檢查條件&#xff08;虛假喚醒…

嵌入式硬件——ARM

一、ARM體系結構程序編譯的過程&#xff1a;預處理&#xff08;.c-.i&#xff09;&#xff1a;宏替換&#xff0c;頭文件展開&#xff0c;去掉注釋&#xff0c;特殊符號的處理編譯&#xff08;.i-.s&#xff09;&#xff1a;C語言轉換成匯編語言匯編&#xff08;.s-.o&#xff…

Flutter 以模塊化方案 適配 HarmonyOS 的實現方法

Flutter 以模塊化方案 適配 HarmonyOS 的實現方法 Flutter的SDK&#xff1a; https://gitcode.com/openharmony-tpc/flutter_flutter 分支Tag&#xff1a;3.27.5-ohos-0.1.0-beta DevecoStudio&#xff1a;DevEco Studio 5.1.1 Release HarmonyOS版本&#xff1a;API18 本文使…

Redis入門與背景詳解:構建高并發、高可用系統的關鍵基石

本文前言認識Redis單機架構淺談分布式系統分布式是什么數據庫分離和負載均衡引入緩存數據庫分庫分表引入微服務念補充小結Redis特性介紹持久化支持集群高可用快Redis的應用場景總結前言 在當今這個數據驅動的時代&#xff0c;應用的性能和可擴展性已成為衡量其成功的關鍵指標。…

Mysql常見的優化方法

數據庫優化(底層基礎優化) 數據庫層面的優化是性能“基礎"&#xff0c; 主要包含架構設計、存儲引擎、表結構、索引策略、配置參數等方面考慮。目標是減少資源(CPU、IO和內存)消耗。 架構設計 讀寫分離&#xff1a;將"讀操作"和"寫操作"分離到不同的數…

利用Claude Code打造多語言網站內容翻譯工具:出海應用開發全流程實戰教程

一、工具選型與準備Claude Code 簡介 Claude Code 是 Anthropic 公司推出的 AI 編程助手&#xff0c;可以輔助開發者生成代碼、優化代碼結構、進行代碼解釋等&#xff0c;支持多種主流編程語言。開發環境準備 Claude Code 賬號或 API 接入權限Node.js 或 Python 環境&#xff0…

集成運算放大器(反向比例,同相比例)

基礎知識&#xff1a;反相比例運算原理&#xff1a;示波器顯示&#xff1a;結論&#xff1a;放大倍數為-R2/R1。R3的大小約等于R1與R2的并聯電阻。由于放大器的最大輸出電壓取決于供電電壓&#xff0c;所以如果R2為7k時&#xff0c;會導致失真。同向比例原理&#xff1a;示波器…

【HBase】HBaseJMX 接口監控信息實現釘釘告警

目錄 一、JMX 簡介 二、JMX監控信息釘釘告警實現 一、JMX 簡介 官網&#xff1a;Apache HBase ? Reference Guide JMX &#xff08;Java管理擴展&#xff09;提供了內置的工具&#xff0c;使您能夠監視和管理Java VM。要啟用遠程系統的監視和管理&#xff0c;需要在啟動Java…

SQL 語言規范與基礎操作指南

SQL 語言規范與基礎操作指南 SQL 作為數據庫操作的核心語言&#xff0c;遵循規范的語法和書寫習慣不僅能提高代碼可讀性&#xff0c;還能減少錯誤。本文整理了 SQL 的基礎規則、書寫規范及常用操作&#xff0c;適合初學者快速上手。 一、SQL 基本規則 1. 書寫格式 SQL 語句可寫…

產業園IBMS智能化集成系統功能有哪些?

產業園 IBMS&#xff08;建筑集成管理系統&#xff09;智能化集成系統是針對產業園 “多業態、多系統、多租戶” 特點設計的全局管理平臺&#xff0c;通過整合樓宇自控、安防、消防、能源、停車、租戶服務等子系統&#xff0c;實現 “集中監控、協同聯動、數據驅動、靈活服務”…

線性代數之兩個宇宙文明關于距離的對話

矢量的客觀性和主觀性宇宙中飄過來一個自由矢量&#xff0c;全世界的人都可以看到&#xff0c;大家都在想&#xff0c;怎么描述它呢&#xff0c;總不能指著它說“那個矢量”吧。數學家很聰明&#xff0c;于是建立了一個坐標系&#xff0c;這個矢量投影到坐標系下&#xff0c;就…

Camx-Tuning參數加載流程分析

調用時序圖 一、效果參數在開機時加載 CreateTuningDataManager邏輯分析 1.從xxx_module.xml獲取sensor名稱和效果參數名稱&#xff0c; 比如效果參數名稱為&#xff1a;xtc_tsp_sc520cs那么效果庫的完整名稱就是&#xff1a;com.qti.tuned.xtc_tsp_sc520cs.bin 2.優先從/data/…

《P4180 [BJWC2010] 嚴格次小生成樹》

題目描述小 C 最近學了很多最小生成樹的算法&#xff0c;Prim 算法、Kruskal 算法、消圈算法等等。正當小 C 洋洋得意之時&#xff0c;小 P 又來潑小 C 冷水了。小 P 說&#xff0c;讓小 C 求出一個無向圖的次小生成樹&#xff0c;而且這個次小生成樹還得是嚴格次小的&#xff…

Transformer淺說

rag系列文章目錄 文章目錄rag系列文章目錄前言一、簡介二、注意力機制三、架構優勢四、模型加速總結前言 近兩年大模型爆火&#xff0c;大模型的背后是transformer架構&#xff0c;transformer成為家喻戶曉的詞&#xff0c;人人都知道它&#xff0c;但是想要詳細講清楚&#x…