計算機網絡——傳輸層(TCP)

傳輸層

在計算機網絡中,傳輸層是將數據向上向下傳輸的一個重要的層面,其中傳輸層中有兩個協議,TCP,UDP 這兩個協議。

TCP

話不多說,我們直接來看協議報頭。

在這里插入圖片描述

源/目的端口號:表示數據從哪個進程來,到哪個進程去;

序號(Sequence Number)

在數據的傳輸中,傳輸報文的數據部分的每一個字節,都有一個他自己的編號。序號(Sequence Number),簡稱SN。
SN與SYN標志控制位的值有關,SYN值不同,SN表達不同的含義:

當SYN為1時,說明此時為連接建立階段,這時的SN為初始序號:ISN(Intial Sequence Number),通過隨機生成SN。
當SYN為0時,說明現在是數據傳輸階段,第一個報文的序號是ISN+1,后面的報文的序號, 當前的報文的SN值+Tcp報文的凈荷字節數(不包括Tcp報頭)eg.如果發送端發送的報文的SN為3,他的凈荷字節數為20,那么發送端發送的下一個報文的SN為20 。
在實際的數據傳輸中,SN的作用是當我們主機收到很多報文時,我們可以利用SN值對當前報文進行一個去重效果

確認序號(Acknowledge Number)

對當前收到的序號進行一個確認。如果設置了一個ACK控制位,確認序號表示一個準備接受的包的序列號,注意,他的序列號指向的是準備接受的包,也就是下一個期望接受的包的序列號。

舉個例子,假設發送端(如Cient)發送3個凈荷為1000byte、起始SN序號為1的數據包給Server四服務端,Server每收到一個包之后需要回復一個ACK響應確認數據包給Client。ACK響應數據包的ACKNumber值,為每個Client包的為SN+包凈荷,既表示Server已經確認收到的字節數,還表示期望接收到的下一個Cient發送包的SN序號。(三次握手詳細圖解)。

數據偏移(首部長度)

4位Tcp報頭長度:表示該TCP 頭部有多少個32 位bit(有多少個4 字節); 所以TCP 頭部最大長度是15 * 4 = 60

標志控制位

· URG:占一位,表示緊急指針字段有效。在實際中,優先處理緊急字段,此時緊急字段指針才有用,并且指向緊急數據(應用較少,一般用來錯誤碼,eg.在傳輸中,突然不要某個數據了)。
· ACK:置位ACK=1表示確認號字段有效:TCP協議規定,連接建立后所有發送的報文的ACK必須為1;當ACK=0時,表示該數據段不包含確認信息。當ACK=1時,表示該報文段包括一個對已被成功接收報文段的確認序號Acknowedgment Number,該序號同時也是下一個報文的預期序號。
· PSH:表示當前報文需要請求推(push)操作;當PSH=1時,接收方在收到數據后立即將數據交給上層,而不是直到整個緩沖中區滿。(在窗口檢測中,發送PSH,將消息進行交互)。
· RST:置位RST=1表示復位TCP連接;用于重置已經混亂的連接,也可用于拒絕一個無效的數據段或者拒絕一個連接請求。如果數據段被RST置了RST位,說明報文發送方有問題發生。
· SYN:在連接建立時用來同步序號。當SYN=1而ACK=0時,表明這是一個連接清求報文,對方若同意建立連接,則應在響應報文中使SYN=1和ACK=1。綜合下,SYN置1,就表示這是一個連接請求或連接接受報文。
· FIN:用于在釋放TCP連接時,標識發送方比特流結束,用來釋放一個連接。當 FIN=1時,表明此報文的發送方的數據已經發送完畢,并要求釋放連接。

窗口大小

通俗來講,就是表示自己的接收緩沖區的剩余空間大小。用來進行流量控制。

校驗和

對整個TCP報文段,即TCP頭部和TCP數據進行校驗和計算,接收端用于對收到的數據包進行驗證。

緊急指針

它是一個偏移量,和SN序號值相加表示緊急數據最后一個字節的序號。以上內容是TCP報文首部必須的字段,也稱固有字段,長度為20個字節。接下來是TCP報文的可選項和填充部分。

可選項和填充部分

可選項和填充部分的長度為4n字節(n是整數),該部分是根據需要而增加的選項。如果不足4n字節,要加填充位,使得選項長度為32(4字節)的整數倍,具體的做法是在這個字段中加入額外的零,以確保TCP頭是32位(4字節)的整數倍。

Tcp三次握手

三次握手是Tcp面向連接的重要過程,和確保了數據傳輸的可靠性。
(1)第一次握手:CIient進入SYN SENT狀態,發送一個SYN幀來主動打開傳輸通道,該幀的SYN標志位被設置為1,同時會帶上Client分配好的SN序列號,該SN是根據時間產生的一個隨機值,通常情況下每間隔4ms會加1。除此之外,SYN幀還會帶一個MSS(最大報文段長度)可選項的值,表示客戶端發送出去的最大數據塊的長度。

(2)第二次握手:Server接受SYN幀之后,會進入SYN RCVD,同時返回SYN+ACK幀給Client,主要目的在于通知Client,Server端已經收到SYN消息,現在需要進行確認。Server端發出的SYN+ACK幀的ACK標志位被設置為1,其確認序號AN(Acknowledgment Number)值被設置為Client的SN+1,SYN+ACK幀的SYN標志位被設置為1,SN值為Server端生成的SN序號,SYN+ACK幀的MSS(最大報文長度)

(3)第三次握手:Client在收到Server的第二次握手的SYN+ACK確認幀之后,首先將自己的狀態會從SYN SENT變成ESTABLISHED,表示自己方向的連接通道已經建立成功,Client可以發送數據給Server端了。然后,Client發AGK幀給Server端,該ACK幀的ACK標志位被設置為1,其確認序號AN(Acknowledqment Number)值被設置為Server端的SN序號+1,還有一種情況,Client可能會將ACK幀和一幀要發送的數據,合并到一起發送給Server端。

(4)Server端在收到Client的ACK幀之后,會從SKN RCVD狀態會進入ESTABLISHED狀態,至此,Server方向的通道連接建立成功,Server可以發送數據給Client,TCP的全雙工連接建立完成。

如下圖:
在這里插入圖片描述

四次揮手

(1)第一次揮手:主動斷開方(可以是客戶端,也可以是服務器端),向對方發送一個FIN結束請求報文,此報文的FIN位被設置為1并且正確設置Sequence Number(序列號)和Acknowledgment Number(確認號)。發送完成后,主動斷開方進入FIN_WAIT_1狀態,這表示主動斷開方沒有業務數據要發送給對方,準備關閉SOCKET連接了。

(2)第二次揮手:正常情況下,在收到了主動斷開方發送的FIN斷開請求報文后,被動斷開方會發送一個ACK響應報文,報文的Acknowledqment Number(確認號)值為斷開請求報文的SN+1,該ACK確認報文的含義是:“我同意你的連接斷開請求”。之后,被動斷開方就進入了(CLOSE_WAIT)狀態,TCP協議服務會通知高層的應用進程,對方向本地方向的連接已經關閉,對方已經沒有數據要發送了,若本地還要發送數據給對方,對方依然會接受。被動斷開方的==CLOSE_WAIT(關閉等待)==還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的時間。主動斷開方在收到了ACK報文后,FIN _WAIT_1轉換成FIN_WAIT_2狀態。

(3)第三次揮手:在發送完成ACK報文后,被動斷開方還可以繼續完成業務數據的發送,待剩余數據發送,或者CLOSE-WAIT(關閉等待)截止后,被動斷開方會向主動斷開方發送一個FIN+ACK結束響應報文,表示被動斷開方的數據都發送完了,然后,被動斷開方進入LAST_ACK狀態。

(4)第四次揮手:主動斷開方收在到FIN+ACK斷開響應報文還需要進行最后的確認,向被動斷開方發送一個ACK確認報文然后,自己就進入TIME_WAIT狀態,等待超時后最終關閉連接。處于TIME_WAIT狀態的主動斷開方,在等待完成2MSL的時間后,如果期間沒有收到其他報文,則證明對方已正常關閉,主動斷開方的連接最終關閉。

被動斷開方在收到主動斷開方的最后的ACK報文以后,最終關閉了連接,自己啥也不管了。

在這里插入圖片描述

小問

為什么建立連接是三次握手?為什么不是一次兩次?

因為三次握手,C/S雙方都有一次的確定的收發。并且中間兩次(SYN和ACK被捎帶應答了)。它也能確定通信雙方是健康的。

四次揮手可以是三次揮手嗎?
可以,當C發送close請求時,剛好S也發送了close請求,這種情況就和三次握手一樣,同樣被做捎帶應答了,但是這種情況就很少。

洪水攻擊
SYN洪水攻擊(SYN Flood Attack) 是一種常見的 DDoS攻擊(分布式拒絕服務攻擊),利用 TCP協議的三次握手缺陷 耗盡服務器資源,使其無法正常響應合法用戶的請求。防御需結合協議優化(如SYN Cookie)和流量過濾技術。

Tcp特性

滑動窗口

如果我們每次都是一發一接受,他的效率就會低很多,性能就會低一點。
如下圖:
在這里插入圖片描述
如果我們同時發很多數據呢,這樣不就解決了效率低下的問題(其實是將多個段的等待時間重疊在一起了)。
在這里插入圖片描述

? 窗口大小指的是無需等待確認應答而可以繼續發送數據的最大值。上圖的窗口大小就是4000 個字節(四個段)。
? 發送前四個段的時候, 不需要等待任何ACK, 直接發送;
? 收到第一個ACK 后, 滑動窗口向后移動, 繼續發送第五個段的數據; 依次類推;
? 操作系統內核為了維護這個滑動窗口, 需要開辟發送緩沖區來記錄當前還有哪些數據沒有應答; 只有確認應答過的數據, 才能從緩沖區刪掉;
? 窗口越大, 則網絡的吞吐率就越高;

如下圖:
在這里插入圖片描述

快重傳

在上面的傳輸過程中,在同時傳輸多個數據報文時,如果遇到某個數據包丟包了,這種情況下Tcp會怎么做呢?
Tcp首先會讓確實的數據包進行一個重傳。其余的同時傳輸的數據包也會收到,但是不會進行一個重發。
如下圖:

在這里插入圖片描述

流量控制

接收端處理數據的速度是有限的. 如果發送端發的太快, 導致接收端的緩沖區被打滿, 這個時候如果發送端繼續發送, 就會造成丟包, 繼而引起丟包重傳等等一系列連鎖反應.因此TCP 支持根據接收端的處理能力, 來決定發送端的發送速度. 這個機制就叫做流量控制(Flow Control);

接收端將自己可以接收的緩沖區大小放入TCP 首部中的"窗口大小" 字段, 通過ACK 端通知發送端;表示自己能接受的數量大小。
窗口大小字段越大, 說明網絡的吞吐量越高;
接收端一旦發現自己的緩沖區快滿了, 就會將窗口大小設置成一個更小的值通知給發送端;
發送端接受到這個窗口之后, 就會減慢自己的發送速度;
如果接收端緩沖區滿了, 就會將窗口置為0; 這時發送方不再發送數據, 但是需要定期發送一個窗口探測數據段, 使接收端把窗口大小告訴發送端。
發送窗口探測包被接受后,發送端會發送一個Ack其中它的一個標志位PSH也將置1,表示我需要盡快收到數據。
在這里插入圖片描述

擁塞控制

因為網絡上有很多的計算機, 可能當前的網絡狀態就已經比較擁堵. 在不清楚當前網絡狀態下, 貿然發送大量的數據, 是很有可能引起雪上加霜的,少量的丟包, 我們僅僅是觸發超時重傳; 大量的丟包, 我們就認為網絡擁塞。

擁塞控制, 歸根結底是TCP 協議想盡可能快的把數據傳輸給對方, 但是又要避免給網絡造成太大壓力的折中方案。

TCP 引入慢啟動機制, 先發少量的數據, 探探路, 摸清當前的網絡擁堵狀態, 再決定按照多大的速度傳輸數據;這樣也確保了一個可靠性。
擁塞控制的窗口=min(擁塞窗口大小,接收端反饋的窗口大小)。
因為他作為一個高效的傳輸,需要一個快速的擁塞窗口增長速度。
因為接受的能力有限,因此不能單純使擁塞窗口變大。就需要一個閾值,來限制一下他的增長速度。讓他的增長的速度減緩。
在每次超時重發的時候, 慢啟動閾值會變成原來的一半, 同時擁塞窗口置回1;少量的丟包, 我們僅僅是觸發超時重傳; 大量的丟包, 我們就認為網絡擁塞;當TCP 通信開始后, 網絡吞吐量會逐漸上升; 隨著網絡發生擁堵, 吞吐量會立刻下降;
如下圖
在這里插入圖片描述

延遲應答

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

假設接收端緩沖區為1M. 一次收到了500K 的數據; 如果立刻應答, 返回的窗口就是500K;
但實際上可能處理端處理的速度很快, 10ms 之內就把500K 數據從緩沖區消費掉了;
在這種情況下, 接收端處理還遠沒有達到自己的極限, 即使窗口再放大一些, 也能處理過來;
如果接收端稍微等一會再應答, 比如等待200ms 再應答, 那么這個時候返回的窗口大小就是1M;

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

捎帶應答

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

我們的三次握手,也是采用的是捎帶應答,接收端收到數據后,我們會將一個ACK+SYN一起發送給發送端。

面向字節流

創建一個TCP 的socket, 同時在內核中創建一個發送緩沖區和一個接收緩沖區;
? 調用write 時, 數據會先寫入發送緩沖區中;
? 如果發送的字節數太長, 會被拆分成多個TCP 的數據包發出;
? 如果發送的字節數太短, 就會先在緩沖區里等待, 等到緩沖區長度差不多了, 或者其他合適的時機發送出去;
? 接收數據的時候, 數據也是從網卡驅動程序到達內核的接收緩沖區;
? 然后應用程序可以調用read 從接收緩沖區拿數據;
如下圖:
在這里插入圖片描述

eg.
由于緩沖區的存在, TCP 程序的讀和寫不需要一一匹配, 例如:
? 寫100 個字節數據時, 可以調用一次write 寫100 個字節, 也可以調用100 次write, 每次寫一個字節;
? 讀100 個字節數據時, 也完全不需要考慮寫的時候是怎么寫的, 既可以一次read 100 個字節, 也可以一次read 一個字節, 重復100 次;

粘包問題

因為他是一個全雙工的,并且面向字節流,就會導致它的一個發送的數據不全或者是發送的數據多了一點。
那么如何避免粘包問題呢? 歸根結底就是一句話,明確兩個包之間的邊界
對于定長的包, 保證每次都按固定大小讀取即可; 例如上面的Request 結構, 是固定大小的, 那么就從緩沖區從頭開始按sizeof(Request)依次讀取即可;對于變長的包, 可以在包頭的位置, 約定一個包總長度的字段, 從而就知道了包的結束位置;對于變長的包, 還可以在包和包之間使用明確的分隔符(應用層協議, 是我們自己來定的, 只要保證分隔符不和正文沖突即可);
對UDP來說不會存在粘包問題,因為他每次發送的就是一個數據報格式的。UDP發送的數據要么收到,要么不收到。

小結

TCP 復雜,是因為要保證可靠性, 同時又盡可能的提高性能。
可靠性:

校驗和
序列號(按序到達)
確認應答
超時重發
連接管理
流量控制
擁塞控制

提高性能:

滑動窗口
快速重傳
延遲應答
捎帶應答

這就是TCP的主要內容。

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

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

相關文章

界面控件DevExpress WinForms v25.1 - 人工智能(AI)方面全新升級

DevExpress WinForms擁有180組件和UI庫,能為Windows Forms平臺創建具有影響力的業務解決方案。DevExpress WinForms能完美構建流暢、美觀且易于使用的應用程序,無論是Office風格的界面,還是分析處理大批量的業務數據,它都能輕松勝…

WinFrom真入門(1)——Windows窗體應用概念

窗體的基本結構 用Winform開發的桌面程序,是在Windows操作系統上運行的,這個不用多說。窗體(Form)的作用?:窗體是用戶交互的容器,承載按鈕、文本框等控件,構成應用程序的界面?。 在Windows操…

scss預處理器對比css的優點以及基本的使用

本文主要在vue中演示&#xff0c;scss的基本使用。安裝命令 npm install sass sass-loader --save-dev 變量 SCSS 支持變量&#xff0c;可將常用的值&#xff08;如顏色、字體大小、間距等&#xff09;定義為變量&#xff0c;方便重復使用和統一修改。 <template><…

Postman 如何高效地轉換時間戳?

在 Postman 中&#xff0c;時間戳的處理對于 API 請求和響應的調試和測試至關重要&#xff0c;正確處理時間戳可以確保數據的準確性和一致性&#xff0c;而 Moment 庫和原生 JS 是兩種常見的處理方式。此外&#xff0c;我們還將介紹 Apifox&#xff0c;它提供了更直觀、更簡便的…

iptables學習記錄

一.四表 filter 表&#xff1a; 主要用于控制數據包的過濾&#xff0c;決定數據包是否允許進出及轉發 。比如設置規則允許特定 IP 訪問服務器的 SSH 端口&#xff08;22 端口&#xff09;&#xff0c;或禁止某些 IP 訪問網站端口&#xff08;80 或 443 端口 &#xff09;。可作…

前端自動創建react項目腳手架

步驟&#xff1a;在終端窗口運行如下命令&#xff1a; npm create vitelatest 也可以指定 vite包 版本&#xff0c; 例如&#xff1a; npm create vite4.1.0 npm執行npm install 很慢 還出現證書問題 執行命令行:npm install -g create-vite npm error code UNABLE_TO_GET_IS…

[從零開始學習JAVA ] 了解線程池

前言&#xff1a; 在Java編程中&#xff0c;線程池是一個強大的工具&#xff0c;它能夠管理和復用線程&#xff0c;提供高效的并發處理能力。通過線程池&#xff0c;我們可以有效地控制并發線程的數量&#xff0c;并降低線程創建和銷毀的開銷。本文將引導你深入了解Java中的線程…

Nginx — Nginx處理Web請求機制解析

一、Nginx請求默認頁面資源 1、配置文件詳解 修改端口號為8080并重啟服務&#xff1a; 二、Nginx進程模型 1、nginx常用命令解析 master進程&#xff1a;主進程&#xff08;只有一個&#xff09; worker進程&#xff1a;工作進程&#xff08;可以有多個&#xff0c;默認只有一…

【C++標準IO庫】字符串流

目錄 一、字符串流概述 1.1 流的概念回顧 1.2 字符串流的定義和作用 二、istringstream 的使用 2.1 基本用法 2.2 常見應用場景 三、ostringstream 的使用 3.1 基本用法 3.2 常見應用場景 四、stringstream 的使用 4.1 基本用法 4.2 常見應用場景 五、字符串流的錯…

C語言pthread庫的線程休眠和喚醒的案例

一、代碼如下 #include<stdio.h> #include<pthread.h> // 定義獨占鎖 pthread_mutex_t mutex; // 定義條件信號對象 pthread_cond_t condition; // 初始化函數 void init(){ int code pthread_mutex_init(&mutex, NULL); printf("共享鎖初…

人臉照片比對 API 接口如何對接?

隨著數字化程度加深&#xff0c;身份驗證的重要性也日益凸顯&#xff0c;它成為保障個人信息安全、維護交易秩序的關鍵環節。人臉照片比對 API 接口作為連接人臉比對技術與各類應用的橋梁&#xff0c;正發揮著越來越重要的作用&#xff0c;成為眾多企業和開發者實現高效、安全身…

java學習筆記9——常用類

字符串相關的類&#xff1a; String 指向同一個地址可才相等 注意這個地方&#xff0c;兩個person對象的name實際上指向的是同一個字符串常量池&#xff08;Tom&#xff09; String常用方法 總結&#xff1a; 1.string類的理解(以JDK8為例說明) 1.1 類的聲明 public final cl…

Day 09

文章目錄 指針數組指針和函數技術名詞解釋技術細節課堂筆記 指針數組 #include<stdio.h> int main() {int a[3] {0,1,2};//指針數組&#xff0c;它是數組&#xff0c;每個元素都是指針int *p[3];p[0] &a[0];p[0] a;p[1] &a[1];p[1] a1;p[2] &a[2];p[…

Nginx — Nginx安裝證書模塊(配置HTTPS和TCPS)

一、安裝和編譯證書模塊 [rootmaster nginx]# wget https://nginx.org/download/nginx-1.25.3.tar.gz [rootmaster nginx]# tar -zxvf nginx-1.25.3.tar.gz [rootmaster nginx]# cd nginx-1.25.3 [rootmaster nginx]# ./configure --prefix/usr/local/nginx --with-http_stub_…

計算機網絡 用deepseek幫助整理的復習資料(一)

### 計算機網絡基礎知識整理 --- #### **一、網絡類型** 1. **局域網 (LAN)** - **定義**&#xff1a;覆蓋小范圍&#xff08;如家庭、教室、公司&#xff09;。 - **特點**&#xff1a;高帶寬、低延遲&#xff0c;設備通過交換機互聯。 - **示例**&#xff1…

Linux SCP傳輸文件免密配置

文章目錄 Linux SCP傳輸文件免密配置生成SSH密鑰對將公鑰復制到遠程服務器測試SSH連接使用SCP免密傳輸文件可選配置帶密碼的秘鑰連接處理使用 ssh-agent進行緩存管理&#xff08;該方式只能確保同一個回話中&#xff0c;多次傳輸只輸一次密碼&#xff09;使用 keychain&#xf…

數字電子技術基礎(三十六)——利用Multisim軟件實現3線-8線譯碼器

目錄 1 手動方式實現3線-8線譯碼器 2 使用字選擇器實現3線-8線譯碼器 現在嘗試利用Multisim軟件來實現3線-8線譯碼器。本實驗目的是驗證74LS138的基本功能&#xff0c;簡單來說就是“N中選1”。 實驗設計&#xff1a; &#xff08;1&#xff09;使能信號&#xff1a;時&am…

wait和notify : 避免線程餓死(以及votile內存可見性和指令重排序問題)

各位看官&#xff0c;大家早安午安晚安呀~~~ 如果您覺得這篇文章對您有幫助的話 歡迎您一鍵三連&#xff0c;小編盡全力做到更好 歡迎您分享給更多人哦 今天我們來學習&#xff1a;wait和notify : 避免線程餓死&#xff08;以及votile內存可見性和指令重排序問題&#xff09; …

HarmonyOS 介紹

HarmonyOS簡介 隨著萬物互聯時代的開啟&#xff0c;應用的設備底座將從幾十億手機擴展到數百億IoT設備。全新的全場景設備體驗&#xff0c;正深入改變消費者的使用習慣。 同時應用開發者也面臨設備底座從手機單設備到全場景多設備的轉變&#xff0c;全場景多設備的全新底座&am…

【視覺提示學習】3.28閱讀隨想

2109.01134 CoOp通過可學習的向量來建模提示的上下文詞匯&#xff0c;這些向量可以用隨機值或預訓練的詞嵌入進行初始化&#xff08;見圖2&#xff09;。我們提供了兩種實現方式&#xff0c;以處理不同性質的任務&#xff1a;一種是基于統一上下文&#xff08;unified context…