網絡原理之 TCP 協議

目錄

1. TCP 協議格式

2. TCP 原理

(1) 確認應答

(2) 超時重傳

(3) 連接管理

a) 三次握手

b) 四次揮手

(4) 滑動窗口

(5) 流量控制

(6) 擁塞控制

(7) 延時應答

(8) 捎帶應答

3. TCP 特性

4. 異常情況的處理

1) 進程崩潰

2) 主機關機 (正常流程)

3) 主機掉電 (非正常)

4) 網線斷開

5. TCP 和 UDP 之間的對比


前文:TCP 的使用

1. TCP 協議格式

想要知道?TCP 的原理,我們首先就得了解 TCP 協議報文的格式。

TCP 數據報分為兩部分,報頭 + 載荷(應用層數據報),選項(可以有,也可以沒有)也是報頭中的一部分。

大家都知道,TCP 的特點是:有連接,可靠傳輸、面向字節流,全雙工

其中可靠傳輸,是 TCP 最最最核心的特性(初心)。

可靠傳輸,不是說發送方能夠 100% 的傳輸給接收方(再厲害的技術,抵不過挖掘機一鏟子)

而是退而求其次:

1) 發送方將數據發出去之后,數據到沒到接收端,發送方能心里有數,知道接收方是否收到數據

2) 如果發現接收端沒收到數據,能采取一系列的措施進行補救。

那么 TCP 是如何保證可靠傳輸的呢?這就涉及到一個非常關鍵的機制,確認應答。

2. TCP 原理

(1) 確認應答

發送方,把數據發給接收端之后,接收端會返回一個應答報文(acknowledge, ack)。

發送方,如果收到這個應答報文了,就說明發送方把數據成功傳給對方了。

而在網絡傳輸過程中,因為每個數據包傳輸是走的路徑不同,所以就可能會出現數據包的 "先發后至" 的情況。

舉個例子:

為了處理這種情況,TCP 就需要完成兩個工作:

1. 確保應答報文和發出去的數據,能夠對得上號,不出現歧義。

2. 確保在出現先發后至的現象時,能夠讓應用程序這邊仍然按照正確的順序來理解數據。

而引入序號和確認序號,給每條數據進行編號,針對性應答,或者按照序號,對數據進行重新排序,就能解決上述問題。

TCP 是按照字節的方式來編序號的,如圖:

TCP 的初心就是實現可靠傳輸,達成可靠傳輸的核心機制就是確認應答,通過確認應答,發送方就能夠知道數據是否到達了接收方。如果數據到達了,那么接收方返回的 ack 里面的確認序號就是下一次發送方發送的數據的第一個字節。如果數據沒到達,那么接收方就不會返回 ack。(不考慮滑動窗口的情況下)

那么如何區分一個數據報是普通的數據,還是 ack 應答數據呢?

可以通過 TCP 報文協議中的,六位標志位的 ACK 來確認,數據報是否是應答報文。

如果 ACK = 1,則說明是應答報文,其中的 "確認序號字段" 就能夠生效。

如果 ACK = 0,那么數據報中的 "確認序號字段" 不會生效。

確認應答,是 TCP 最核心的機制,支持了 TCP 的可靠傳輸。

但是僅僅只有確認應答還不夠,還需要其他的機制來輔助,超時重傳就是這樣的一個輔助機制。

(2) 超時重傳

確認應答,描述的是一個比較理想的情況,

如果網絡傳輸中,出現丟包了,那么發送方就沒有辦法收到 ack 了,那該怎么辦呢?

通過超時重傳,就可以解決上述問題。超時重傳,是針對確認應答機制的補充。

超時重傳,就是等待一定的超時時間,發送方還沒有收到 ACK,發送方會主動把剛剛的數據重新傳輸一遍給接收端。

可以先來思考一下,為什么會出現丟包。

因為丟包是一個隨機的事件,所以在 TCP 傳輸過程中,丟包就存在兩種情況:

第一種是發送方發的數據報丟了,第二種是接收方發送的應答報文丟了。

如圖:

所以當引入可靠性的時候,是會付出代價的,最明顯的兩方面:

1. 傳輸效率? ? 因為有超時重傳,所以傳輸數據效率不高。(這也是 UDP 不會被 TCP 完全取代的意義)

2. 復雜程度

這里其實還有一個問題:

(3) 連接管理

連接管理就是建立連接和斷開連接。

其實 TCP 建立連接的過程也叫做三次握手,斷開連接的過程叫做四次揮手。

那這個握手到底是什么意思呢?

其實握手就是打個招呼,就是給對方傳輸一個簡短的,沒有業務數據的數據報,通過這個數據報來喚起對方的注意,從而觸發后續的操作。四次揮手的 "揮手" 和三次握手的 "握手" 是同一個意思。

舉個例子:比如說你走路遇到熟人的時候,對方主動跟你說 "你好" "hello" 之類的,打招呼的內容通常沒有什么實際的意義,就只是起到喚起對方的注意力的效果。

前面也提到過,TCP 是有連接的,需要主機雙方各自保存對端的信息

a) 三次握手

那 TCP 的三次握手具體流程是怎樣的呢?

TCP 的三次握手,TCP 在建立連接的時候,需要通信雙方一共打三次招呼,才能完成建立連接。

TCP 的初心,是為了實現可靠傳輸,確認應答是核心,超時重傳等機制是輔助。

但進行確認應答和超時重傳有個大前提,那就是當前的網絡環境是基本可用的,通暢的,

如果當前網絡已經存在重大故障了,那么可靠傳輸是無從談起的。

三次握手的核心作用一:

投石問路,確認當前網絡是否是暢通的。

如果連 syn 和 ack 這樣沒攜帶業務數據的數據報都不能夠正常傳輸的話,那么之后要傳輸的攜帶了業務的數據報也不可能正常傳輸。

三次握手的核心作用二:

讓發送方和接收方都能確定自己的發送能力和接收能力均正常。

三次握手的核心作用三:

讓通信雙方,在握手過程中,針對一些重要的參數,進行協商。

TCP 通信過程中,序號是從幾開始,就是雙方協商出來的(一般不是從 1 開始),

每次連接建立的時候,都會協商出一個比較大的,和上次不太一樣的值。

這樣做是放了防止上一次遺留的數據,影響到本次數據的傳輸。

有的時候,網絡如果不太好,那么客戶端和服務器就會斷開,再重新建立連接,重連的時候,就有可能在新的連接建立好的時候,舊的數據姍姍來遲,這種遲到的數據報,是應該被丟棄的,而根據本次連接的正常數據報的序號,對比收到的數據報的序號,如果發現差別非常大的話,就說明收到的數據報是舊連接遲到的數據報,那就可以直接丟棄掉。

三次握手可以的話,那四次握手行不行?兩次握手行不行?

四次握手是可以的,但是沒必要,將中間的兩次合并成一次能夠提升效率。

兩次握手是不可以的,因為少了最后一次的握手,服務器就無法確定自己的發送能力是否正常和客戶端的接收能力是否正常。

b) 四次揮手

斷開連接的過程就是四次揮手,和三次握手類似。

TIME_WAIT 的意義就是當主動連接斷開方發送完最后一次 ACK 時,先進入 TIME_WAIT 狀態,等待 2MSL 的時間,如果在這個時間內,ACK 丟包了,對端重傳了 FIN,那么 主動斷開連接方就能馬上返回 ACK,這樣對端重傳的 FIN 才有意義。

MSL:是一個可配置的參數,這個參數數值是拍腦門拍出來的。

(4) 滑動窗口

前面的確認應答 ,超時重傳,連接管理都是用來保證 TCP 的可靠性的。

滑動窗口是用來提高效率的,其實是一種亡羊補牢。

TCP 因為引入了可靠傳輸,所以傳輸的效率不太高(多出了一些等待 ACK 的時間,單位時間內能傳輸的數據就減少了)

而滑動窗口,就是用來減小可靠傳輸對性能的影響的。

但是再怎么提高 TCP 的效率,也是不可能超過沒有引入可靠傳輸的 UDP 的效率的。

那么具體滑動窗口是怎么做的才能提高效率呢?

其實 TCP 慢就慢在要等對端的 ACK,那就可以在保證可靠傳輸的前提下,將等待時間縮小就好了。

那就可以進行批量傳輸數據,這樣做效率就上來了。

效率是提高了,但是 TCP 的核心是可靠傳輸,在提高效率的前提是數據能可靠傳輸。

上述滑動窗口中,確認應答是可以正常工作的。

但如果在滑動窗口的過程中,出現丟包了,那該怎么辦呢?

這里的重傳,相比于前面的超時重傳,有些不同。

還是得分兩種情況討論:

如果 ACK 全丟了呢?那此時的網絡肯定出現嚴重故障了,平時丟包率達到 10% 都算是比較嚴重的了,現在直接丟包率 100% ,就別想著 "可靠傳輸" 了。

如果通信雙方,傳輸數據的量比較小,也不頻繁,就仍然是普通的確認應答和超時重傳。

如果通信雙方,傳輸數據的量比較大,也更頻繁,就會進入到滑動窗口的模式,按照快速重傳的方式處理。

(5) 流量控制

通過滑動窗口的方式傳輸數據,效率是會提升的。

窗口越大,傳輸效率就會越大。(一份等待時間,等待的 ack 更多了,總的等待時間就更少了)

那么滑動窗口的窗口大小是設置的越大就越好嗎?

顯然不是的,提高效率的前提是保證可靠傳輸,如果因為傳輸的速度太快,接收方處理不過來,就會導致接收方出現丟包的情況,發送方還得重傳。

而流量控制,就是站在接收方的角度,反向制約發送方的傳輸速度。

發送方發送的速率,不應該超過接收方的處理能力。

那么如何知道接收方的處理能力是多少呢?

如圖,可以通過 接收方的接收緩沖區的剩余空間大小,來衡量處理能力的大小。

接收方每次收到數據之后,都會把接收緩沖區剩余空間大小通過 ack 返回給發送方,

發送方就會按照這個數值來調整下一輪的發送速度。

如圖:

(6) 擁塞控制

流量控制,考慮的是接收方的處理能力,

但是不僅僅要考慮到接收方的處理能力,還要考慮網絡通信過程中經過的節點(路由器/交換機)的處理能力,也就是說,還需要考慮整個通信的路徑,如果中間某個節點的傳輸速度達到了瓶頸,那么此時,也會對整體的傳輸產生影響。

擁塞控制,就是 考慮/衡量 通信過程中,中間節點的情況。

如圖:

但是關鍵的問題,在于怎么衡量中間節點。

之前接收方的處理能力,是很好衡量的。

由于中間節點,結構更復雜,更難以直接的進行量化。

因此可以使用 "實驗" 的方式,來找到合適的值。

可以讓發送方先按照比較低的速度開始發送數據(小窗口),如果數據傳輸過程非常順利,也沒有丟包,那就再嘗試使用更大的窗口,更高的速度進行發送(一點一點變化),隨著窗口不斷增大,達到一定程度,可能中間節點就會出現問題了,此時這個節點就可能會出現丟包。發送方發現丟包了,就把窗口大小再調整小,此時如果發現還是繼續丟包,那就繼續縮小。如果不丟包了,就繼續嘗試變大。

在這個過程中,發送方不停的調整自己的窗口大小,逐漸達成一個 "動態平衡".

這種做法,就相當于把 "中間節點" 視為一個整體,通過 "實驗" 的方式,來找到中間節點的瓶頸在哪里。

上述過程如圖:

流量控制和擁塞控制都是在限制發送方的發送窗口大小,

最終實際發送的窗口大小,是取?流量控制 和 擁塞控制 中的較小值。

(7) 延時應答

A 把數據傳給 B,B 就會馬上返回 ack 給 A (正常)。

也有的時候,A 傳輸給 B,此時 B 等一會再返回 ack 給 A (延時應答)。

本質上也是為了提升傳輸效率。

發送方的窗口大小,就是傳輸效率的關鍵。

流量控制這里,就是根據接收方的接收緩沖區的剩余空間,來控制發送方的發送速率的,

如果有辦法,能讓流量控制得到的窗口更大點,發送速率就更快點(大點的前提是,能讓接收方處理的過來)

通過延時返回 ack,給接收方更多的時間讀取接收緩沖區的數據,此時接收方讀了這個數據之后,緩沖區的剩余空間,就變大了,返回的窗口大小,也就更大了。

比如,初始情況下,緩沖區的剩余空間是 10kb,如果立即返回 ack,就返回了 10kb 這么大的大小窗口。如果延時個 200ms 再返回,那么在這 200ms 的過程中,接收方的應用程序,又讀了 2kb,此時,返回的 ack 就是返回 12kb 的窗口了。

延時應答,才促成了前面的四次揮手,能夠三次揮完。

(8) 捎帶應答

在延時應答的基礎上,進一步提高效率。

3. TCP 特性

TCP 的特性是:有連接,可靠傳輸,面向字節流,全雙工

面向字節流的特性是:

傳輸數據的時候可以非常靈活,可以一次傳輸一個字節,也可以一次傳輸多個字節。

但是這里存在一個問題:粘包問題(不是 tcp 獨有的,而是面向字節流的機制都有類似的情況)

這里的包指的是應用層數據包,如果同時有多個應用層數據包被傳輸過去,此時就容易出現粘包問題。

如圖:

那么該如何解決粘包問題呢?

核心思路:通過定義好應用層協議,明確應用層數據報之間的邊界。

1. 引入分隔符

2. 引入長度

比如使用 \n 作為分隔符:

引入長度:

4. 異常情況的處理

如果在使用 tcp 的過程中,出現意外,會如何處理?

1) 進程崩潰

進程崩潰,本質上就是進程沒了,進程終止了,那么文件描述符表就釋放了,也就相當于調用 socket.close() ,此時就會觸發 FIN,對方收到之后,自然也就會返回 ACK 和 FIN,這邊再進行 ACK,這里就是一個正常的四次揮手斷開連接的流程。

TCP 的連接,可以獨立于進程存在。(進程沒了,TCP 連接不一定沒)

2) 主機關機 (正常流程)

在進行關機的時候,就是會先觸發強制終止進程的操作(相當于 1)

此時就會觸發 FIN,對方收到之后,自然會返回 ACK 和 FIN。

此時,不僅僅是進程沒了,整個系統也關閉了。如果在系統關閉之前,對端返回的 ACK 和 FIN 到了,此時系統還是可以返回 ACK,進行正常的四次揮手的。如果系統已經關閉了,ACK 和 FIN 遲到了,就無法進行后續 ACK 的響應。站在對端的角度,以為是自己的 FIN 丟包了,就會重傳 FIN,連續重傳好幾次都沒有響應,最后對端就會放棄連接(把持有的對端信息刪除)。

3) 主機掉電 (非正常)

主機掉電,是一瞬間的事情,還來不及殺進程,也來不及發送 FIN,主機直接就停機了。

1. 如果對端是在發送數據(接收方掉電),發送的數據就會一直等待 ack,觸發超時重傳,重傳好幾次還是沒有響應,就會觸發 TCP 的連接重置功能,發起復位報文段(RST = 1),如果復位報文段發過去之后也沒有效果,此時就會釋放連接了。

2. 如果對端是在接收數據(發送方掉電),對端還在等待數據到達,等了半天沒消息,此時其實也無法區分,是發送方沒發消息,還是發送方掛了。

針對這種情況,TCP 提供了心跳包的機制,接收方也會周期性的給發送方發送一個特殊的,不攜帶業務數據的數據包,并且期望對方返回一個應答,如果對方沒有應答,并且重復了多次之后,仍然沒有,就視為對方掛了,此時就可以單方面釋放連接了。

4) 網線斷開

網線斷開和剛剛的主機掉電非常類似。

如何識別某個機器是否掛了,一般都是通過心跳來檢測的。

5. TCP 和 UDP 之間的對比

TCP 有連接,可靠傳輸,面向字節流,全雙工。

UDP 無連接,不可靠,面向數據報,全雙工。

TCP 的優勢是可靠傳輸,TCP 適用于絕大部分場景。

UDP 的優勢是更高效率,UDP 適合于對 "可靠性不敏感","性能敏感" 的場景,比如局域網內部(同一個機房)的主機之間的通信。

如果要傳輸比較大的數據包,TCP 優先。(UDP 有 64kb 的限制)

如果要進行 "廣播傳輸" ,優先考慮 UDP。UDP 天然支持廣播,TCP 不支持(得自己寫代碼實現)

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

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

相關文章

STM32使用RCC(Reset Clock Contorl,復位時鐘控制器)配置時鐘以及時鐘樹

RCC主要作用 設置系統時鐘SYSCLK(System Clock)頻率;設置AHB、APB2、APB1以及各個外設分頻因子,從而設置HCLK、PCLK2、PCLK1以及各個外設的時鐘頻率;控制AHB、APB2、APB1這三條總線時鐘以及每個外設的時鐘開啟&#xf…

安防視頻監控平臺Liveweb視頻匯聚管理系統管理方案

智慧安防監控Liveweb視頻管理平臺能在復雜的網絡環境中,將前端設備統一集中接入與匯聚管理。國標GB28181協議視頻監控/視頻匯聚Liveweb平臺可以提供實時遠程視頻監控、視頻錄像、錄像回放與存儲、告警、語音對講、云臺控制、平臺級聯、磁盤陣列存儲、視頻集中存儲、…

PostGIS的歷史發展

自從 GIS 軟件開發以來,ShapeFile等格式被廣泛用于存儲空間數據,但這些文件格式文件需要特殊的軟件才能讀取和寫入,并發用戶可能會導致數據損壞和速度變慢,并且復雜的問題需要復雜的軟件來處理。 因此,對多用戶的支持、…

【目標跟蹤】AntiUAV600數據集詳細介紹

AntiUAV600數據集的提出是為了適應真實場景,即無人機可能會隨時隨地出現和消失。目前提出的Anti-UAV任務都只是將其看做與跟蹤其他目標一樣的任務,沒有結合現實情況考慮。 論文鏈接:https://arxiv.org/pdf/2306.15767https://arxiv.org/pdf/…

“原批教育家”原批之星魯健的杰作——原批俱樂部

偉大的原批教育家——原批之星,名為魯健,是一位在南京郵電大學智能科學與技術專業中嶄露頭角的杰出人物。他不僅以其卓越的黑客技術和對網絡正義的執著而聞名,更是“遠古四神”之一,以其對原批之力的深刻理解和不同見解&#xff0…

IS-IS三

目錄 點到點鄰接關系建立 ISIS修改鏈路類型 isis ppp-negotiation 3-way only 僅才用三次握手建立鄰居 不向下兼容兩次握手 兩次握手 自身發送的(Hello報文)IIH 不攜帶 p2p adj TLV 不處理點到點鄰接狀態TLV 三次握手 …

Hadoop生態圈框架部署 偽集群版(四)- Zookeeper單機部署

文章目錄 前言一、Zookeeper單機部署(手動部署)1. 下載Zookeeper安裝包到Linux2. 解壓zookeeper安裝包3. 配置zookeeper配置文件4. 配置Zookeeper系統環境變量5. 啟動Zookeeper6. 停止Zookeeper在這里插入圖片描述 注意 前言 本文將詳細介紹Zookeeper的…

Spring的三層架構實現原理

Spring三層架構實現 三層架構 controller: 控制層,接受前端發送的請求,對請求進行處理并相應數據;service: 業務邏輯層,處理具體的業務邏輯;dao: 數據訪問層(Data Access Object) 持久層,負責數據訪問操作,包括數據的增、刪、改、查。controller 層: @RestContro…

《Java核心技術I》volatile字段

volatile字段 有多處理器的計算機能夠暫時在寄存器或本地內存緩存中保存內存值,其結果是,運行在不同處理器上的線程可能看到同一個內存位置上有不同的值。編譯器可以改變指令執行的順序以使吞吐量更大化,編譯器不會選擇可能改變代碼語義的順…

基于springboot+vue的車輛違章信息管理系統(全套)

一、系統架構 前端:vue | element-ui | html 后端:springboot | mybatis-plus 環境:jdk1.8 | mysql | maven | nodejs 二、代碼及數據庫 三、功能介紹 01. web端-首頁 02. web端-注冊 03. web端-登錄 04. web端-公告 05. web端-留言…

利用斷開的域管理員RDP會話提權

前言 當域內管理員登錄過攻擊者可控的域內普通機器運維或者排查結束后,退出3389時沒有退出賬號而是直接關掉了遠程桌面,那么會產生哪些風險呢?有些讀者第一個想到的肯定就是抓密碼,但是如果抓不到明文密碼又或者無法pth呢&#x…

【Unity 動畫】設置跟運動(Apply Root)模型跟著動畫產生位移

一、導入的動畫本身必須有跟隨動畫產生位移或者旋轉的效果 二、導入Unity后 在Unity中,根運動(Root Motion)是指動畫中角色根節點的移動和旋轉。根節點通常是角色的根骨骼(Root Bone),它決定了角色的整體…

輕松上手使用Vuex

Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式和庫。它主要用于管理應用程序中的全局狀態,提供一個集中式存儲庫,并且以可預測的方式來更新這些狀態。以下是 Vuex 的基本用法和一些關鍵概念: 1.安裝 Vuex 首先,需要在 Vue…

【設計模式】裝飾器模式 在java中的應用

文章目錄 1. 引言裝飾器模式的定義與設計目的裝飾器模式與其他設計模式的比較 2. 裝飾器模式的結構組件接口(Component)具體組件(ConcreteComponent)裝飾角色(Decorator)具體裝飾類(ConcreteDec…

vue npm install出現問題

報錯如下: ERR! code ERESOLVE npm ERR! ERESOLVE could not resolve npm ERR! npm ERR! While resolving: web-ifc-viewer1.0.218 npm ERR! Found: three0.149.0 npm ERR! node_modules/three npm ERR! peer three">0.126.1" from camera-controls…

爬蟲項目練手

python抓取優美圖庫小姐姐圖片 整體功能概述 這段 Python 代碼定義了一個名為 ImageDownloader 的類,其主要目的是從指定網站(https://www.umei.cc)上按照不同的圖片分類,爬取圖片并保存到本地相應的文件夾中。不過需要注意&…

對比json數據是否變化

在 JavaScript 中,你可以使用多種方法來對比兩個 JSON 數據是否發生變化。以下是幾種常見的方式: 1. 使用 JSON.stringify 最簡單的方法是將兩個 JSON 對象序列化為字符串,并比較這些字符串。但需要注意的是,這種方法對于對象屬…

C++設計模式:代理模式(Proxy)(附案例代碼)

什么是代理模式? 代理模式是一種結構型設計模式,主要用于為某個對象提供一個代理,以便在不直接訪問對象的情況下控制對其的訪問。代理可以在客戶端和目標對象之間起到一個中介的作用,添加一些額外的操作,例如權限控制…

【筆記】軟技能

硬技能:操控世界的能力,處理對象為【物】。軟技能:影響他人的能力,處理對象為【人】。軟技能包括一個人的情商、個性、社交禮儀、溝通、語言、個人習慣,還有解決問題的能力、領導能力、時間管理能力等一切非技術能力。…

uni-app簡潔的移動端登錄注冊界面

非常簡潔的登錄、注冊界面模板&#xff0c;使用uni-app編寫&#xff0c;直接復制粘貼即可&#xff0c;無任何引用&#xff0c;全部公開。 廢話不多說&#xff0c;代碼如下&#xff1a; login.vue文件 <template><view class"content"><view class&quo…