傳輸層協議 TCP

TCP 協議


TCP 全稱為 "傳輸控制協議(Transmission Control Protocol"). 人如其名, 要對數據的傳輸進行一個詳細的控制

TCP 協議段格式

  • 源/目的端口號: 表示數據是從哪個進程來, 到哪個進程去
  • 32 位序號/32 位確認號
  • 4 位 TCP 報頭長度: 表示該 TCP 頭部有多少個 32 位 bit(有多少個 4 字節),?所以TCP 頭部最大長度是 15 * 4 = 60
  • 6位標志位
  • 16 位窗口大小
  • 16 位校驗和: 發送端填充, CRC 校驗. 接收端校驗不通過, 則認為數據有問題. 此處的檢驗和不光包含 TCP 首部, 也包含 TCP 數據部分.
  • 16 位緊急指針: 標識哪部分數據是緊急數據;
  • 40 字節頭部選項

內核中對報頭的描述

六個標志位

表示對應的報文類型,對應的六個比特位,要用就設置成1

  1. URG: 緊急指針是否有效
  2. ACK: 確認號是否有效
  3. PSH: 提示接收端應用程序立刻從 TCP 緩沖區把數據讀走
  4. RST: 通信異常對方要求重新建立連接; 我們把攜帶 RST 標識的稱為復位報文段
  5. SYN: 請求建立連接; 我們把攜帶 SYN 標識的稱為同步報文段
  6. FIN: 通知對方, 本端要關閉了, 我們稱攜帶 FIN 標識的為結束報文段

ACK一般都是置1,因為確認需要是要用來表示自己在該確認序號之前的報文全部收到,通常確認序號要有效,第一次建立連接SYN然后等待對方發送SYN和ACK,然后對方再用ACK告訴自己收到了建立請求,雙方都有意愿建立連接,FIN用于斷開連接時告訴對方斷開連接,雙方都要斷開,所以得先發ACK給對方,對方響應了然后發送ACK和FIN

三次握手能保證一定連接成功C端發送SYN對方能收到,對方會給予回應,自己也能收到,自己在告訴對方收到了,在這個過程中,C和S發了一次收了一次,能最小代價驗證自己和對方全雙工并且建立連接成功,如果中間一環出錯就代表建立不成功無法通信

?

16位窗口大小

網絡傳輸需要消耗資源,為了提高效率,對方接受不了那么多,就控制一下發送的量,16位窗口大小表示自己接受緩沖區的剩余空間的大小用來告訴對端自己的剩余大小

16位緊急指針?

配合URG來用,數據發送到接收緩沖區后,它是一個字節流式的接受隊列,提高優先級,優先處理,緊急指針表示偏移量位置存放緊急數據

?

確認應答(ACK)機制

TCP 將每個字節的數據都進行了編號. 即為序列號.

每一個 ACK 都帶有對應的確認序列號, 意思是告訴發送者, 我已經收到了哪些數據; 下一次你從哪里開始發.向對方發送數據的時候不知道對方有沒有收到,對端會送一個帶有確認需要的報文并將ACK標記為置1,表示該確認序號以前的報文全部收到

為什么又兩個序號?

一個確認序號,一個序號,因為TCP是全雙工,可以發也可以讀,在接受的同時也可以發,我告訴對方收到了,我也可以發送別的數據,就像三次握手一樣,本質是四次握手,但是有兩次合并了,當成一條報文發送,這就是要有一對序號的原因,一個負責發帶編號,一個用來確定自己有沒有收到,可以捎帶應答,我告訴你我收到了,我也可以攜帶數據給你

?捎帶應答


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

超時重傳機制

主機 A 發送數據給 B 之后, 可能因為網絡擁堵等原因, 數據無法到達主機 B;如果主機 A 在一個特定時間間隔內沒有收到 B 發來的確認應答, 就會進行重發,但是, 主機 A 未收到 B 發來的確認應答,也可能是因為 ACK 丟失了

因此主機 B 會收到很多重復數據. 那么 TCP 協議需要能夠識別出那些包是重復的包, 并且把重復的丟棄掉.這時候我們可以利用前面提到的序列號, 就可以很容易做到去重的效果.那么, 如果超時的時間如何確定?

最理想的情況下, 找到一個最小的時間, 保證 "確認應答一定能在這個時間內返回",但是這個時間的長短, 隨著網絡環境的不同, 是有差異的.如果超時時間設的太長, 會影響整體的重傳效率,如果超時時間設的太短, 有可能會頻繁發送重復的包;

TCP 為了保證無論在任何環境下都能比較高性能的通信, 因此會動態計算這個最大超時時間.

Linux 中(BSD Unix 和 Windows 也是如此), 超時以 500ms 為一個單位進行控制, 每次判定超時重發的超時時間都是 500ms 的整數倍.如果重發一次之后, 仍然得不到應答, 等待 2*500ms 后再進行重傳.如果仍然得不到應答, 等待 4*500ms 進行重傳. 依次類推, 以指數形式遞增.累計到一定的重傳次數, TCP 認為網絡或者對端主機出現異常, 強制關閉連接.

第一種可以用超時重傳機制解決,但是第二種,因為確認序號的定義是在這個序號之前的報文全部收到,后續接收更大的序號也默認認為收到了

連接管理機制


在正常情況下, TCP 要經過三次握手建立連接, 四次揮手斷開連接

三次握手,本質是四次握手,一方發起連接SYN,然后對端收到后,發送ACK應答,然后再發送SYN向對方請求連接,但是捎帶應答使兩個報文合成一條發送過去,最后對端收到貨,返回ACK,表示同意連接,至此雙方意愿達成可進通信

四次揮手,一方發起FIN向對方表示要斷開連接,對方發送ACK表示接收到了斷開請求,然后自己在向先有斷開意愿的一方發送FIN斷開請求,對端收到后,返回ACK表示同意,至此雙方都斷開對方的連接,結束通信

服務端狀態轉化:

  • [CLOSED -> LISTEN] 服務器端調用 listen 后進入 LISTEN 狀態, 等待客戶端連接
  • [LISTEN -> SYN_RCVD] 一旦監聽到連接請求(同步報文段), 就將該連接放入內核等待隊列中, 并向客戶端發送 SYN 確認報文.
  • [SYN_RCVD -> ESTABLISHED] 服務端一旦收到客戶端的確認報文, 就進入ESTABLISHED 狀態, 可以進行讀寫數據了.
  • [ESTABLISHED -> CLOSE_WAIT] 當客戶端主動關閉連接(調用 close), 服務器會收到結束報文段, 服務器返回確認報文段并進入 CLOSE_WAIT(誰先關閉誰就CLOSE_WAIT,依舊占用文件描述符沒有被釋放,要手動關,不然fd泄漏
  • [CLOSE_WAIT -> LAST_ACK] 進入 CLOSE_WAIT 后說明服務器準備關閉連接(需要處理完之前的數據); 當服務器真正調用 close 關閉連接時, 會向客戶端發送FIN, 此時服務器進入 LAST_ACK 狀態, 等待最后一個 ACK 到來(這個 ACK 是客戶端確認收到了 FIN)
  • [LAST_ACK -> CLOSED] 服務器收到了對 FIN 的 ACK, 徹底關閉連接.

客戶端狀態轉化:

  • [CLOSED -> SYN_SENT] 客戶端調用 connect, 發送同步報文段
  • [SYN_SENT -> ESTABLISHED] connect 調用成功, 則進入 ESTABLISHED 狀態, 開始讀寫數據
  • [ESTABLISHED -> FIN_WAIT_1] 客戶端主動調用 close 時, 向服務器發送結束報文段, 同時進入 FIN_WAIT_1
  • [FIN_WAIT_1 -> FIN_WAIT_2] 客戶端收到服務器對結束報文段的確認, 則進入 FIN_WAIT_2, 開始等待服務器的結束報文段
  • [FIN_WAIT_2 -> TIME_WAIT] 客戶端收到服務器發來的結束報文段, 進入TIME_WAIT, 并發出 LAST_ACK
  • [TIME_WAIT -> CLOSED] 客戶端要等待一個 2MSL(Max Segment Life, 報文最大生存時間)的時間, 才會進入 CLOSED 狀態.

下圖是 TCP 狀態轉換的一個匯總:

較粗的虛線表示服務端的狀態變化情況,較粗的實線表示客戶端的狀態變化情況,CLOSED 是一個假想的起始點, 不是真實狀態

理解 TIME_WAIT 狀態


現在做一個測試,首先啟動 server,然后啟動 client,然后用 Ctrl-C 使 server 終止,這時馬上再運行 server, 結果是:

這是因為,雖然 server 的應用程序終止了,但 TCP 協議層的連接并沒有完全斷開,因此不能再次監 聽同樣的 server 端口. 我們用 netstat 命令查看一下:

TCP 協議規定,主動關閉連接的一方要處于 TIME_ WAIT 狀態,等待兩個MSL(maximum segment lifetime)的時間后才能回到 CLOSED 狀態.我們使用 Ctrl-C 終止了 server, 所以 server 是主動關閉連接的一方, 在TIME_WAIT 期間仍然不能再次監聽同樣的 server 端口,MSL 在 RFC1122 中規定為兩分鐘,但是各操作系統的實現不同, 在 Centos7 上默認配置的值是60s,可以通過 cat /proc/sys/net/ipv4/tcp_fin_timeout 查看 msl 的值;

想一想, 為什么是 TIME_WAIT 的時間是 2MSL?


MSL 是 TCP 報文的最大生存時間, 因此 TIME_WAIT 持續存在 2MSL 的話就能保證在兩個傳輸方向上的尚未被接收或遲到的報文段都已經消失(否則服務器立刻重啟, 可能會收到來自上一個進程的遲到的數據, 但是這種數據很可能是錯誤的),同時也是在理論上保證最后一個報文可靠到達(假設最后一個 ACK 丟失, 那么服務器會再重發一個 FIN. 這時雖然客戶端的進程不在了, 但是 TCP 連接還在, 仍然可以重發 LAST_ACK)

解決 TIME_WAIT 狀態引起的 bind 失敗的方法(作業)

在 server 的 TCP 連接沒有完全斷開之前不允許重新監聽, 某些情況下可能是不合理的

服務器需要處理非常大量的客戶端的連接(每個連接的生存時間可能很短, 但是每秒都有很大數量的客戶端來請求).這個時候如果由服務器端主動關閉連接(比如某些客戶端不活躍, 就需要被服務器端主動清理掉), 就會產生大量 TIME_WAIT 連接.由于我們的請求量很大, 就可能導致 TIME_WAIT 的連接數很多, 每個連接都會占用一個通信五元組(源 ip, 源端口, 目的 ip, 目的端口, 協議). 其中服務器的 ip 和端口和協議是固定的. 如果新來的客戶端連接的 ip 和端口號和 TIME_WAIT 占用的鏈接重復了, 就會出現問題.

使用 setsockopt()設置 socket 描述符的 選項 SO_REUSEADDR 為 1, 表示允許創建端口號相同但 IP 地址不同的多個 socket 描述符

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

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

相關文章

RT-Thread的概念和移植

一、操作系統的概念 操作系統(英語:Operating System,縮寫:OS)是一組主管并控制計算機操作、運用和運行硬件、軟件資源和提供公共服務來組織用戶交互的相互關聯的系統軟件程序。根據運行的環境,操作系統可以…

基于單片機傾角測量儀/角度測量/水平儀

傳送門 👉👉👉👉其他作品題目速選一覽表 👉👉👉👉其他作品題目功能速覽 概述 本設計實現了一種基于單片機的高精度數字傾角測量儀。系統核心由傾角傳感器(ADXL345傾…

深度學習 -- 初步認識Torch

深度學習 – 初步認識Torch 文章目錄深度學習 -- 初步認識Torch一,認識人工智能1.1 人工智能的本質1.2 人工智能的實現過程二,認識Torch2.1簡介2.2 概述2.3 Tensor的創建2.3.1 torch.tensor2.3.2 torch.Tensor三,創建線性和隨機張量3.1創建線…

BGP的“聰明選路”遇上了TCP的“路徑潔癖”,需人工調和

在路由器R1上有兩條外網,WAN1和WAN2。R1上做了域名分流功能,全局網址分到WAN1,指定域名分到WAN2(優先級更高)。癥狀是用戶反饋部分網頁無法打開。于是各種檢查嘗試...... 2天過去了......最終結論是:即使S…

ACWing算法筆記 | 二分

🔍 C 二分查找雙模板詳解:左閉右開 vs 左閉右閉(二分筆記)二分查找(Binary Search)是一類高效的搜索算法,在 O(log n) 的時間復雜度下查找答案,適用于單調性問題。C STL 的 lower_bo…

centos 新加磁盤分區動態擴容

你不能直接將一個分區分配給/dev/mapper/centos-root,因為這是一個邏輯卷(屬于 LVM 系統)。不過,你可以通過以下步驟將/dev/sda3添加到現有卷組或創建新的邏輯卷: 確認磁盤和分區信息 首先檢查分區是否已格式化以及是否…

python學智能算法(二十六)|SVM-拉格朗日函數構造

【1】引言 前序學習進程中,已經了解了拉格朗日乘數法求極值的基本原理,也了解了尋找最佳超平面就是尋找最佳分隔距離。 這篇文章的學習目標是:使用拉格朗日乘數法獲取最佳的分隔距離。 【2】構造拉格朗日函數 目標函數 首先是目標函數f&a…

智能制造——48頁畢馬威:汽車營銷與研發數字化研究【附全文閱讀】

涵蓋了汽車行業數字化轉型、汽車營銷業務能力建設(以會員管理為例)以及汽車研發與創新能力建設等議題。畢馬威認為,軟件定義汽車已成為汽車行業中的核心議題,并圍繞此議題提供了相關方案。在市場觀點方面,畢馬威與多家…

嵌入式學習-PyTorch(8)-day24

torch.optim 優化器torch.optim 是 PyTorch 中用于優化神經網絡參數的模塊,里面實現了一系列常用的優化算法,比如 SGD、Adam、RMSprop 等,主要負責根據梯度更新模型的參數。🏗? 核心組成1. 常用優化器優化器作用典型參數torch.op…

PostgreSQL實戰:高效SQL技巧

PostgreSQL PG 在不同領域可能有不同的含義,以下是幾種常見的解釋: PostgreSQL PostgreSQL(簡稱 PG)是一種開源的關系型數據庫管理系統(RDBMS),支持 SQL 標準并提供了豐富的擴展功能。它廣泛應用于企業級應用、Web 服務和數據分析等領域。 PostgreSQL 的詳細介紹 Po…

3-大語言模型—理論基礎:生成式預訓練語言模型GPT(代碼“活起來”)

目錄 1、GPT的模型結構如圖所示 2、介紹GPT自監督預訓練、有監督下游任務微調及預訓練語言模型 2.1、GPT 自監督預訓練 2.1.1、 輸入編碼:詞向量與位置向量的融合 2.1.1.1、 輸入序列與詞表映射 2.1.1.2、 詞向量矩陣與查表操作 3. 位置向量矩陣 4. 詞向量與…

【Redis 】看門狗:分布式鎖的自動續期

在分布式系統的開發中,保證數據的一致性和避免并發沖突是至關重要的任務。Redis 作為一種廣泛使用的內存數據庫,提供了實現分布式鎖的有效手段。然而,傳統的 Redis 分布式鎖在設置了過期時間后,如果任務執行時間超過了鎖的有效期&…

MYSQL--快照讀和當前讀及并發 UPDATE 的鎖阻塞

快照讀和當前讀在 MySQL 中,數據讀取方式主要分為 快照讀 和 當前讀,二者的核心區別在于是否依賴 MVCC(多版本并發控制)的歷史版本、是否加鎖,以及讀取的數據版本是否為最新。以下是詳細說明:一、快照讀&am…

css樣式中的選擇器和盒子模型

目錄 一、行內樣式二、內部樣式三、外部樣式四、結合選擇器五、屬性選擇器六、包含選擇器七、子選擇器八、兄弟選擇器九、選擇器組合十、偽元素選擇器十一、偽類選擇器十二、盒子模型 相關文章 學習標簽、屬性、選擇器和外部加樣式積累CSS樣式屬性:padding、marg…

關于基于lvgl庫做的注冊登錄功能的代碼步驟:

以下是完整的文件拆分和代碼存放說明,按功能模塊化劃分,方便工程管理:一、需要創建的文件清單 文件名 作用 類型 main.c 程序入口,初始化硬件和LVGL 源文件 ui.h 聲明界面相關函數 頭文件 ui.c 實現登錄、注冊、主頁面的UI 源文…

RAII機制以及在ROS的NodeHandler中的實現

好的,這是一個非常核心且優秀的設計問題。我們來分兩步詳細解析:先徹底搞懂什么是 RAII,然后再看 ros::NodeHandle 是如何巧妙地運用這一機制的。1. 什么是 RAII 機制? RAII 是 “Resource Acquisition Is Initialization” 的縮寫…

Linux LVS集群技術

LVS集群概述1、集群概念1.1、介紹集群是指多臺服務器集中在一起,實現同一業務,可以視為一臺計算機。多臺服務器組成的一組計算機,作為一個整體存在,向用戶提供一組網絡資源,這些單個的服務器就是集群的節點。特點&…

spring-ai-alibaba如何上傳文件并解析

問題引出 在我們日常使用大模型時,有一類典型的應用場景,就是將文件發送給大模型,然后由大模型進行解析,提煉總結等,這一類功能在官方app中較為常見,但是在很多模型的api中都不支持,那如何使用…

「雙容器嵌套布局法」:打造清晰層級的網頁架構設計

一、命名與核心概念 “雙容器嵌套布局法”,核心是通過兩層容器嵌套構建網頁結構:外層容器負責控制布局的“宏觀約束”(如頁面最大寬度、背景色等),內層容器聚焦“微觀排版”(內容居中、內邊距調整、紅色內容…

基于深度學習的自然語言處理:構建情感分析模型

前言 自然語言處理(NLP)是人工智能領域中一個非常活躍的研究方向,它致力于使計算機能夠理解和生成人類語言。情感分析(Sentiment Analysis)是NLP中的一個重要應用,其目標是從文本中識別和提取情感傾向&…