UDP / TCP 協議

目錄

一、前言:

?數據封裝與分用:?

二、網絡協議分層模型:

三、UDP / TCP 協議

?UDP 協議:

1、UDP 協議段格式:

2、UDP 的特點:

TCP 協議:

1、TCP?協議段格式:

2、TCP 協議的十大核心機制:

1、確認應答:

2、超時重傳:

3、連接管理:

4、滑動窗口:

5、流量控制:

6、擁塞控制:

7、延時應答:

8、捎帶應答:

9、面向字節流:

10、異常情況:


一、前言:

? ? ? ? 網絡通信是一個很復雜事情,在這個過程中會涉及到很多細節的問題。如果只使用一個協議來約定上述的所有細節,那這個協議就會非常復雜。

? ? ? ? 所以,我們可以將一個功能復雜繁瑣的協議,拆分成多個功能更單一的協議。拆分,是為了管理復雜程度,對協議進行 “分類” 、“分層”,每個部分負責一個功能,使結構更清晰明。

????????協議分層,就是把很多協議,按照功能分成不同的層級,每個層級都有對應的任務。下層協議會給上層協議提供服務,上層協議會調用下層協議的功能。

下層協議會給上層協議提供服務,具體體現在:

????????例如,傳輸層(TCP)依賴網絡層(IP)提供的“盡力而為”的路由能力,TCP 在其基礎上增加可靠性(如重傳機制)。

上層協議會調用下層協議的功能,具體體現在:

????????應用層開發者無需關心 UDP 如何實現傳輸,只需調用?socket.send()?接口發送數據。(這個我之前文章實現回顯服務器出現過這個代碼)。

?數據封裝與分用:?

????????發送方(封裝):數據從上層向下傳遞時,每層添加自己的頭部信息(Header)。
示例:應用層數據 → 添加 TCP / UDP 頭 → 添加 IP 頭 → 添加以太網頭 → 物理信號。

????????接收方(分用):數據從下層向上傳遞時,逐層剝離頭部并處理。
示例:物理信號 → 解析以太網頭 → 解析 IP 頭 → 解析 TCP / UDP 頭 → 交付應用數據。

二、網絡協議分層模型:

? ? ? ? 在網絡通信中,可以分為五層模型:

????????

上到下分為:

應用層 -> 傳輸層 -> 網絡層 -> 數據鏈路層 -> 物理層

其中,不同的網絡設備涉及到的層級也是不一樣的:

? ? ? ? 1、對于一臺主機,他的操作系統內核實現了從傳輸層到物理層的內容,也就是 TCP / IP 五層模型的下四層。(如果考慮主機的應用程序,五層都會涉及到)。

? ? ? ? 2、對于一臺路由器,他實現了從網絡層到物理層,也就是 TCP / IP 五層模型的下三層

? ? ? ? 3、對于一臺交換機,他實現了從數據鏈路層到物理層,也就是 TCP / IP 五層模型的下兩層

并且,不同的層有著不同的協議:

?下面我們討論的就是傳輸層的UDP / TCP 協議。

三、UDP / TCP 協議

?UDP 協議:

1、UDP 協議格式:

源端口號:

? ? ? ? 占 2 個字節,他標識了發送端應用程序所使用的端口號。

目的端口號:

? ? ? ? 占 2 個字節,用于指定接受端接收數據的應用程序端口號。這是 UDP 數據包能夠正確交付到目標應用程序的關鍵標識。

UDP 長度:

????????占 2 個字節。表示整個 UDP 數據包(?UDP 首部和 UDP 數據)的長度。因為這個字段是 16 位,所以它能夠表示的最大值 65535。這就限定了 UDP 數據包在理論上能夠達到的最大長度為 65535 字節,即64KB。

UDP 校驗和:

????????占 2 個字節。用于檢測數據包在傳輸過程中是否出現錯誤。它是對 UDP 首部和 UDP 數據部分進行計算得到的一個數值,接收方可以通過重新計算校驗和來驗證數據包的完整性,如果校驗和出錯,就會直接丟棄這個數據包。

????????校驗和出錯,是因為網絡數據包傳輸過程中有可能會出現比特翻轉。因為在傳輸介質周圍,存在各種電磁信號,如附近的電力線路、無線通信設備、工業設備等產生的電磁波。這些電磁波會對網絡信號產生疊加干擾,使傳輸的信號發生畸變。在數字信號中,這種畸變可能導致某些比特位的值發生改變,即出現比特翻轉。

????????

2、UDP 的特點:

1、無連接:

? ? ? ? UDP 傳輸的過程類似于寄信,知道接收方的 IP 和 端口號就可以直接傳輸,不需要建立連接。

2、不可靠:

? ? ? ? 沒有確認機制,沒有重傳機制,如果因為網絡故障該數據包沒有發送給到對方(也稱為丟包),UDP 協議層也不會給應用層返回任何錯誤信息。

3、面向數據報:

? ? ? ? 不能夠靈活的控制讀寫數據的次數和數量。

????????在傳輸數據時,會嚴格按照應用層交付給它的報文進行原樣發送。這意味著 UDP 不會對應用層傳來的報文進行任何拆分或合并操作。例如,應用層交給 UDP 一個長度為 100 字節的報文,UDP 就會將這 100 字節作為一個完整的數據報封裝并發送出去,不會因為任何原因將其拆分成多個小的數據報,也不會將它與其他應用層報文合并成一個更大的數據報。

????????在接收數據時,UDP 要求接收端的操作與發送端相對應。如果發送端通過一次sendto函數發送了 100 個字節的數據,那么接收端就必須通過一次recvfrom函數來接收這 100 個字節的數據。這是因為 UDP 數據報是一個獨立的、不可分割的整體,接收端必須以完整的數據報為單位進行接收。不能通過循環調用 10 次recvfrom,每次接收 10 個字節來獲取發送端發送的 100 個字節數據。如果這樣做,可能會導致以下問題:首先,除了第一次recvfrom可能接收到完整的數據報外,其余 9 次recvfrom可能會因為 UDP 緩沖區中沒有新的數據報而阻塞,直到有新的數據報到達;其次,即使后續有新的數據報到達,每次接收 10 個字節也無法保證能夠正確地組合成發送端發送的原始 100 字節數據,因為 UDP 數據報在網絡傳輸過程中可能會亂序,這樣的接收方式會破壞數據的完整性和正確性。

????????如果需要傳輸的數據量超過了 64K,就會面臨數據無法一次性完整傳輸的問題,此時就需要在應用層手動進行分包和拼裝操作。

TCP 協議:

1、TCP?協議段格式:

源端口號:

? ? ? ? 占 2 字節,標識了發送端應用程序所使用的端口號。

目的端口號:

????????占 2 個字節,用于指定接受端接收數據的應用程序端口號。這是 TCP 數據流能夠正確交付到目標應用程序的關鍵標識。

32位序號:

????????TCP 將發送的數據看成是一連串的字節流,32 位序號用來標識每個字節在這個字節流中的位置。比如,一個 TCP 報文段的序號是 1000,數據長度是 1000 字節,那就表示這個報文段里的數據是從字節流的第 1000 號字節開始,到第 1999 號字節結束。這樣接收方就可以按照序號把收到的報文段重新組裝成正確順序的數據,即使報文段在網絡中亂序到達,也能還原出原始的數據序列。

32位確認序號:

????????確認序號是接收方告訴發送方,希望收到的下一個字節的序號。例如,接收方收到了序號為 1 - 1000 的字節數據,并且都正確無誤,那么它返回的確認號就是 1001,表示希望發送方接下來發送序號為 1001 及以后的字節數據。通過確認號,發送方可以知道哪些數據已經被接收方成功接收,哪些數據還需要重發。

? ? ? ? 總的來說,32 位序號起到保證數據流順序,而32 位確認號保證數據有沒有接收到。

4位首部長度:

????????明確TCP頭部的大小,從而讓接收方準確找到數據部分的起始位置。假如首部長度值為8(即頭部占8 × 4 = 32字節),接收方會跳過前32字節,從第33字節開始讀取數據。這樣確保接收方能準確區分頭部與數據。

六位標志位:??

????????URG:緊急指針是否有效。

? ? ? ? ACK:確認號是否有效。

? ? ? ? PSH:提示接收端應用程序即將從TCP緩沖區把數據讀走。

? ? ? ? RST:對方要求重新建立連接,我們將攜帶RST標識的報文段稱為復位報文段。

? ? ? ? SYN:請求建立連接,我們把攜帶SYN標識的報文段稱為同步報文段。

? ? ? ? FIN:通知對方,本端要關閉了,我們稱攜帶FIN的報文段稱為結束報文段。

16位窗口大小:

????????占 2 字節。用于流量控制,它表示接收方當前愿意接收的數據量,以字節為單位。發送方根據接收方通告的窗口大小來調整自己的發送速率,避免發送過快導致接收方緩存溢出。當接收方的處理能力較強,能夠快速處理接收到的數據時,接收方會增大通告窗口的大小,發送方收到后會相應地增加發送數據的速率,從而充分利用網絡帶寬。反之,當接收方處理能力下降時,通告窗口變小,發送方也會降低發送速率,避免數據在網絡中堆積。

16位校驗和:

????????占 2 字節,用于檢測 TCP 報文段在傳輸過程中是否發生了錯誤。計算包括 TCP 首部,也包括 TCP 數據部分。

????????校驗和有問題時,接收方丟棄報文段且不發送ack,通過超時重傳或快速重傳機制讓發送方重新發送該報文段,以此保證數據的可靠傳輸。

16位緊急指針:

????????當 TCP 報文段中的 URG 標志位被置為 1 時,表明該報文段中有緊急數據,其作用是標識報文段中緊急數據的結束位置,以便接收方能快速定位并優先處理緊急數據。例如,序號為1000,緊急指針為 50 ,則緊急數據范圍為?1000~1049(共 50 字節)。

選項:

????????實現了協議的功能擴展和性能增強,比如,可以實現窗口縮放,將 16 位窗口大小字段擴展為 30 位(通過左移?0~14?位),支持高速網絡的大容量數據傳輸。

2、TCP 協議的十大核心機制:

1、確認應答:

????????確認應答是 TCP 協議實現可靠數據傳輸的關鍵機制之一,通過接收方對已收到數據的確認,讓發送方能夠確定數據是否成功傳輸。

????????當接收方成功接收到發送方發送的數據后,會向發送方發送一個確認應答(ACK)報文段。這個報文段是有確認序號的,這個 ACK 報文段就像是接收方給發送方的一個 “收據”,告訴發送方數據已經收到了。發送方只有收到接收方的 ACK 后,才會認為數據成功傳輸,然后繼續發送下一批數據。如果發送方在一定時間內沒有收到 ACK,就會認為數據傳輸出現問題,進而觸發重傳機制,重新發送未被確認的數據。

? ? ? ? 確認序號表示接收方期望收到的下一個字節的序號,也就意味著接收方已經成功接收了該序號之前的所有數據。例如,發送方發送了序號為 1000、長度為 1000 字節的數據,接收方正確接收后,會在 ACK 中把確認序號設置為 2000,告訴發送方下一次請從 2000 號字節開始發送數據。

2、超時重傳:

? ? ? ? 超時重傳是確認應答機制的重要補充。是針對丟包的場景的。

? ? ? ? 這里存在兩種丟包情況,一是發送方的數據包丟失,二是接收方返回的ack丟失。

? ? ? ? 發送方發送的數據報丟包:????????

????????如果主機A在一個特定時間間隔內沒有收到B發來的確認應答,就會進行重發。

接收方返回的 ack 丟包:

? ? ? ? ?這里就會出現主機B收到重復的數據,那么 TCP 協議就需要能識別出哪些包是重復的包,并且把重復的包丟棄。這時候我們就可以利用前面提到的序列號,從而達到去重的效果。

? ? ? ? TCP 在接收數據的時候,會在操作系統內核中,會在內存空間維護一個 “接收緩沖區” ,如果又收到同一個數據,此時就可以根據數據的序號來在接收緩沖區中進行 “去重” 的操作。當應用程序對數據進行讀取,數據就會從緩沖區刪除,如果下次接收的數據序號在已經被應用程序讀取的數據序號之前,接收方會直接丟棄這個數據包。

那么,超時重傳的超時時間是如何確定的?

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

?????????TCP為了保證無論在任何環境下都能比較高性能的通信,因此會動態計算這個最大超時時間。超時以 500 ms 為一個單位進行控制,每次判定超時重發的超時時間都是 500 ms 的整數倍。比如,如果重發一次后仍然得不到回應,等待2*500ms后再進行重傳。如果仍然得不到回應,等待4*500ms后再進行重傳。如果還是得不到回應,以此類推,以指數形式遞增。

? ? ? ? 并且,重傳次數 和 總的重傳時間是存在上限的。當累計到一定的重傳次數,重傳還沒有成功, TCP 就會認為網絡或者對端主機出現異常,并強制關閉連接。

3、連接管理:

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

三次握手:

三次握手由客戶端發起。?

????????

第一次握手(客戶端發送SYN):

? ? ? ? 客戶端像服務器發送一個 SYN (同步)報文段,就像一個人拿起電話,撥通對方號碼后說 “我想和你通話,你準備好了嗎”,此時客戶端只是發出了請求,還不知道服務器是否能正常接收和處理信息。

第二次握手(服務器發送SYN + ack):

????????服務器收到客戶端的 SYN 報文段后,發送一個 SYN + ack(同步確認)報文段。這相當于對方在電話里回答 “我準備好了,你也準備好接收我的信息了嗎”,服務器通過這個報文段不僅確認了自己可以接收客戶端的信息,同時也詢問客戶端是否準備好接收自己發送的信息。

第三次握手(客戶端發送 ack ):

????????客戶端收到服務器的 SYN + ack 報文段后,發送一個 ack(確認)報文段。這就如同打電話的人回應 “好的,我們可以開始通話了”,客戶端通過這個報文段告知服務器,自己已經準備好接收服務器發送的信息,至此雙方都確認了彼此的狀態,可以開始正式的數據傳輸,就像兩個人開始正式通話一樣。

三次握手的意義:

? ? ? ? 1、相當于 “投石問路” ,驗證通信鏈路是否暢通。

? ? ? ? 2、驗證通信雙方發送能力和接收能力是否正常。

? ? ? ? 3、TCP 建立連接的過程中,有一個信息是需要協商的,就是 TCP 數據的起始序號,每次建立連接協商出來的起始序號都是不同的。例如,假設上一次連接的序號范圍是 1 - 1000,由于某些原因,一個序號為 500 的數據包在網絡中延遲了。當下一次連接建立時,協商出的起始序號是 10000,那么即使序號為 500 的舊數據包后來到達,接收方一看序號就知道它不屬于當前連接,不會將其納入本次連接的數據處理流程,也就不會出現 “前朝的劍斬本朝的官” 這種錯誤情況,保證了新連接數據的準確性和完整性。

那么,兩次 / 四次握手可以嗎?

兩次握手:

? ? ? ? 可以看到,如果只有兩次握手,客戶端可以明確自身的 “接受能力” 和 “發送能力”是完善的,但服務器只能確定自己可以收到客戶端發送的數據,無法確定客戶端是否能收到自己發出的數據。因此,只有兩次握手是不可以的。

四次握手:

四次握手可以,但沒有必要,會降低效率。因為三次握手就能確定建立連接了,何必四次握手?

四次揮手:

四次揮手可以是客戶端發起,也可以是服務器端發起。在這里,定義發起斷開連接的一方為客戶端。

第一次揮手(客戶端發送 FIN ):

????????客戶端向服務器發送一個 FIN(結束)報文段,就像在電話里說 “我說完了,我準備掛電話了”,此時客戶端不再發送數據,但還可以接收服務器的數據。

第二次揮手(服務器發送 ack ):

????????服務器收到客戶端的 FIN 報文段后,發送一個 ack 報文段作為確認。這就好比對方在電話里回答 “我知道你說完了,我還沒說完,你先別掛,我繼續說”,服務器通過這個確認告知客戶端,已經收到關閉請求,但自己還有數據要發送。

第三次揮手(服務器發送 FIN ):

????????當服務器完成數據發送后,向客戶端發送一個 FIN 報文段,表示 “我也說完了,我也準備掛電話了”,此時服務器也不再有數據要發送。

第四次揮手(客戶端發送 ack ):

????????客戶端收到服務器的 FIN 報文段后,發送一個 ack 報文段進行確認。這就像是回答 “好的,那我們掛電話吧”,客戶端發送完這個 ack 報文段后,會進入 TIME - WAIT 狀態,等待一段時間以確保服務器能收到 ack 報文,然后才真正關閉連接,就像雙方確認后才真正掛掉電話一樣。

在某些情況下,四次揮手可能會合并成三次。

????????服務器端收到客戶端的 FIN 報文后,由于服務器端開啟了 TCP 延遲確認機制且此時沒有數據要發送,所以不會立即發送 ack 報文進行確認。而是等待一段時間,看是否有數據需要發送給客戶端。如果在延遲等待期間,服務器端依然沒有數據要發送,那么服務器端會將原本需要分開發送的 ack 和 FIN 報文合并成一個報文發送給客戶端。這個報文既確認了客戶端的 FIN 請求,又表示服務器端也準備關閉連接。

四次揮手過程中的兩個狀態,CLOSE - WAIT 和 TIME - WAIT 狀態:

CLOSE - WAIT :

????????當被動關閉方(一般是服務器)收到主動關閉方發送的 FIN 報文后,發送 ack 報文進行確認,然后就進入 CLOSE - WAIT 狀態。

? ? ? ? 持續時間:

????????從進入該狀態開始,直到被動關閉方處理完所有剩余數據,并準備好關閉連接時結束。這個時間取決于被動關閉方應用程序處理數據的速度。

? ? ? ? 作用:

????????為被動關閉方提供處理剩余數據的時間,保證數據完整性。在此期間,被動關閉方會繼續處理應用層數據,完成后才會發送 FIN 報文給主動關閉方,以完成連接的最終關閉。

TIME - WAIT :

????????在四次揮手的最后階段,當主動關閉方(一般是客戶端)發送出最后一個 ack 確認報文后,就會進入 TIME - WAIT 狀態。

? ? ? ? 持續時間:

????????通常會在此狀態停留 2 倍的 MSL(報文最大生存時間)。Linux 系統通常默認 MSL 為 30 秒,那么 TIME - WAIT 狀態持續時間就是 60 秒。

? ? ? ? 作用:

????????保證被動關閉方能夠收到最后一個 ack 報文。若被動關閉方未收到該 ack(可能是丟包了),會重發 FIN 報文,處于 TIME - WAIT 狀態的主動關閉方能夠重新發送 ack ,并且 TIME - WAIT 狀態的計時器會重新計時,確保連接正常釋放。

4、滑動窗口:

? ? ? ? 我們之前討論的確認應答機制,對每一個發送的數據段,都要給一個 ack 確認應答,收到 ack 后再發送下一個數據段,這樣做有一個比較大的缺點,就是傳輸性能較差,尤其是數據往返的時間比較長的時候。

?????????既然像那樣一收一發的方式性能較低,那么我們可以一次發送多條數據,就可以大大的提高性能。(將多個數據段的等待時間重疊到一起,節省時間)。

滑動窗口的工作原理:????????

? ? ? ? ?1、滑動窗口的窗口大小指的是無需等待確認應答而可以繼續發送數據的最大值,上圖的窗口就是4000個字節(四個段)。

? ? ? ? 2、發送前四個段的時候,不需要等待任何的?ack ,直接發送。

? ? ? ? 3、收到第一個 ack 后,滑動窗口向后移動,繼續發送第五個段的數據,以此類推。

? ? ? ? 4、操作系統內核為了維護滑動窗口,發送方需要開辟 發送緩沖區?來記錄當前還有哪些數據沒有應答。只有確認應答過的數據才能從緩沖區刪除。

? ? ? ? 5、滑動窗口的接收方會有接收緩沖區,接收方的接收緩沖區用于暫存接收到的數據。當數據到達接收方時,會先進入接收緩沖區,即使應用程序暫時沒有讀取這些數據,數據也不會丟失。

? ? ? ? 6、窗口越大,則網絡的吞吐量就越高。

滑動窗口的滑動過程:

?

如果滑動的過程出現了丟包,怎么處理?

這里分為兩種丟包情況討論,一種數據段到達,返回的 ack 丟包,另一種是數據包丟包。

數據段到達,返回的 ack 丟包:

????????如果只是 ack 丟包,不需要特殊處理。因為 TCP 是基于累積確認的,只要后續有正確的 ack? 到達,發送方就可以知道哪些數據已經被接收方成功接收。

????????例如,發送方發送了序號為 1 - 1000、1001 - 2000、2001 - 3000 的數據段,接收方收到了所有數據段,但返回的第一個 ack(下一個是 1001)丟失了,而發送方收到了第二個 ACK(下一個是 2001),這就說明 1 - 1000 的數據段已經被接收方成功接收,發送方可以正常滑動窗口并繼續發送數據。

特殊情況:如果最后一個 ack 丟失,怎么辦?

? ? ? ? 這是說明批量傳輸已經結束了,已經由超時重傳接管了,如果使用 TCP 傳輸較大量的數據時,自然會觸發滑動窗口,快速重傳(滑動窗口下的重傳機制,相當于超時重傳的變種)機制。如果使用 TCP 傳輸較少量的數據,此時任然是按照確認應答和超時重傳的機制。

? ? ??

數據包丟包:

????????當發送方發現數據包丟包時,會采用快速重傳機制。如果發送方連續收到三次相同的 ack 應答,就會將對應的數據進行重新發送。

????????例如,接收方沒有收到序號為 1001 - 2000 的數據段,就會一直給發送方發送 ack(下一個是 1001),當發送方連續三次收到這個相同的 ACK 時,就會意識到該數據段丟失,從而重新發送 1001 - 2000 的數據段。接收方收到重傳的數據段后,會發送新的 ack 應答,告知發送方數據已成功接收,發送方可以繼續滑動窗口發送后續數據。?

????????這個時候收到了1001之后,再次返回的 ack 就是7001了,因為 2001 -?7000 接收端其實已經收到了,被放到了接收端的接收緩沖區中。

? ? ? ? 就像是這樣:

????????就像拼圖丟失了一塊,只要把原本缺失的那一塊拼上,之后的就可以正常傳輸數據了,接下來就可以從隊列最后一個數據的序號繼續往后索要。

5、流量控制:

????????接收端處理數據的速度是有限的,如果發送端發送的太快,或者接收方應用程序處理緩沖區的數據比較慢,就會導致接收端的緩沖區滿了,這個時候如果繼續發送數據,就會造成?丟包,繼而引起一系列連鎖反應~

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

? ? ? ? 1、接收端將自己可以接收的緩沖區大小放到 TCP 首部的 “16位窗口大小” 字段,通過 ack 端通知發送端。(?16位數字最大可表示65535,但并不代表TCP窗口最大是65535字節,即64kb。實際上,TCP首部40字節選項中還包含了一個窗口擴大因子M,實際窗口大小是窗口字段的值左移M位。左移一位相當于 * 2,通過這種方式,TCP 窗口的實際大小能夠遠超 65535 字節,從而適應高速網絡和長距離網絡的需求,提高數據傳輸的效率。

? ? ? ? 2、窗口越大,說明網絡吞吐量越高。

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

? ? ? ? 4、發送端收到這個窗口之后,就會減慢自己的發送速度。

? ? ? ? 5、如果接收端緩沖區滿了,就會將窗口設置為 0,這時發送端無法再發送數據。但發送端會定期發送一個窗口探測數據段,使接收端把窗口大小告訴發送端,當窗口大小不為0則可以繼續發送。

6、擁塞控制:

????????擁塞指的是網絡中間鏈路出現丟包的情況,一次性傳輸太多的數據可能會造成擁塞。雖然TCP有了滑動窗口這個“大殺器”,能夠高效可靠的發送大量數據。但是如果在剛開始階段就發送大量的數據,仍然可能引發問題。因為網絡上有很多計算機,可能當前的網絡狀態就比較擁堵,如果這個時候發送大量數據,可能會讓本就擁堵的網絡狀態雪上加霜,造成丟包

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

這里有個概念:擁塞窗口

????????擁塞窗口是發送端維護的一個狀態變量,它表示發送端在當前網絡狀況下能夠安全發送的數據量。其大小會根據網絡的擁塞程度動態調整,目的是在不引起網絡擁塞的前提下,盡可能高效地利用網絡帶寬進行數據傳輸。

擁塞控制流程:

? ? ? ? 剛開始發送的時候,定義擁塞窗口的大小為1,每收到一個ACK應答,擁塞窗口大小加1(可以理解為每一輪擁塞窗口是上一輪的 2 倍)。每次發送數據包的時候,將擁塞窗口和接收端主機反饋的窗口大小對比,取較小的值作為實際發送的窗口。擁塞窗口的增長速度是指數級的,雖然啟動速度慢,但是增長很快

? ? ? ? 當指數增長到一定程度(達到閾值),指數增長變成線性增長,主要是防止指數增長某一次翻倍,導致超出上限太多。當線性增長到一定程度,終究會觸發丟包(網絡的承載能力到達上限了)。

? ? ? ? 出現丟包后,一種方式是回到最初慢啟動窗口大小,接下來重復上述的流程;另一種方式是重新計算閾值(丟包的窗口大小 / 2),從閾值開始作為新的擁塞窗口,繼續線性增長(這種方式較常見)。

總結:

? ? ? ? 少量的丟包,我們僅僅是觸發超時重傳;大量的丟包,我們就認為此時網絡擁塞。當TCP通信開始后,網絡吞吐量(窗口)會逐漸上升;隨著網絡發送擁堵,吞吐量會立即下降。 擁塞控制歸根結底就是 TCP協議 想盡可能快的把數據傳輸給對方,但是又要避免速度太快給網絡造成太大壓力的折中方案。

7、延時應答:

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

?????????假如接收端緩沖區大小為 1M。收到了 500K 的數據,如果此時立即應答,返回的窗口大小就是 500K;但實際上處理端處理的速度可能很快,10ms之內應用程序就把500K的數據從緩沖區消費掉了。在這種情況下,接收端處理能力還遠遠沒有到達自己的極限,即使窗口再大一點,也能處理。如果接收端稍微等待一會再應答(應用程序很快就把接收緩沖區的數據讀取消并除了),那么這個時候返回的窗口大小就會更大。窗口越大,網絡的吞吐量越大,傳輸效率越高。通過延時應答機制可以盡可能的提高窗口大小。

? ?

但并不是所有的包都可以延時應答,延時應答也是有限制的:?

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

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

8、捎帶應答:

?????????在 TCP 通信里,當接收方收到發送方的數據后,需要發送 ack(確認應答)報文來告知發送方數據已成功接收。通常而言,接收方可能會有自己的響應數據要發送給發送方(接收方要發送的響應數據一般需要較多時間處理)。

????????捎帶應答就是指接收方在有響應數據要發送給發送方時,不單獨發送 ack ,而是等響應數據要發送的時候,把 ack 也帶上,一起發送給發送方。

? ? ? ? 由于延時應答的存在,ack 不一定立即返回,可以讓 ack 稍等一會(這里涉及到了延時應答),等待響應數據一起返回,這樣可以通過把兩次傳輸合并在一起,提高效率。

9、面向字節流:

? ? ? ? TCP 將應用層交付的數據看作無結構的字節序列,不關心數據的具體含義、格式和邊界,只負責準確且按序地在收發兩端傳輸字節。例如,對于一個視頻文件,TCP 只把它當作一連串的字節進行處理。數據傳輸像水流一樣連續,發送方不斷將數據字節寫入 TCP 連接,接收方持續接收,TCP 保證字節順序,即便網絡中數據包亂序,接收端也會重新排序。

? ? ? ? 所以這里引發了一個問題:粘包問題

? ? ? ? 例如,發送端連續發多個數據包,接收端可能無法準確區分數據包邊界,多個數據包粘連成一個連續字節流,難以正確分割。例如,發送 “Hello”“World” 兩個數據包,接收端可能收到 “HelloWorld”,無法確定兩個數據包的起止位置。主要原因有兩個?一,發送方數據發送快,接收方讀取慢,多個數據包在接收緩沖區積累,導致粘包。如發送方短時間內發送多個小數據包,接收方還沒來得及讀取,它們就會在緩沖區粘連。二,應用層發送和接收數據時,沒正確處理數據邊界,如未按規定格式發送或未正確解析數據長度信息,使接收方無法區分數據包。

所以,如何避免 “粘包問題”呢?歸根結底就一點:明確兩個包之間的邊界

????????對于定長的包,保證每次都按固定大小讀取即可。

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

????????對于變長的包,還可以在包和包之間使用明確的分隔符(分隔符不能和正文沖突)。

? ? ? ? 但是,實際開發中,很多時候是基于一些現成的框架 / 庫 進行開發的(粘包問題就已經被框架 / 庫 解決了)。

?????????

10、異常情況:

異常情況指的是那些偏離正常流程、可能干擾系統穩定運行和數據準確傳輸的狀況。

進程終止 :

????????當進程正常終止時,通常會按照 TCP 協議的規范來關閉連接。它會向對端發送 FIN 包,此包用來表示自己不再發送數據,這是 TCP 連接關閉流程中的主動關閉操作。對端收到 FIN 包后,會返回 ack? 確認,然后對端也可以發送自己的 FIN 包,主動關閉方向對端返回 ack? 確認,這樣就完成了 TCP 連接的四次揮手過程,連接正常關閉。

主機關機:

????????在主機關機時,操作系統會進行一系列的清理操作。對于正在進行的 TCP 連接,操作系統會嘗試有序地關閉它們。這意味著操作系統會模擬進程正常終止時的行為,向對端發送 FIN 包,然后等待對端的響應,完成四次揮手過程。在這個過程中,操作系統會確保已經發送出去的數據都能得到確認,并且盡量讓對端正常關閉連接。

主機掉電 / 網線斷開:

????????主機掉電 / 網線斷開是一種突發的、不可預測的情況。

? ? ? ? 如果掉電 / 網線斷開的一方是接收方。發送方是不知道的,會繼續發送數據包,但接收方不會返回 ack ,發送發會觸發超時重傳,重傳到一定次數,還是沒有收到接收方的 ack ,就會斷開當前連接。

???????在正常情況下,發送方會按照設定的固定頻率向接收方發送心跳包,同時也會發送業務數據。心跳包的作用是讓接收方能夠實時了解發送方的運行狀態,確認發送方是否正常在線并能夠進行數據傳輸。接收方在收到心跳包后,會根據約定的規則進行相應的處理,例如更新發送方的狀態信息,表示發送方處于活躍狀態。如果掉電 / 網線斷開的一方是發送方。發送方無法再向接收方發送心跳包和其他數據。接收方會根據心跳包機制來判斷發送方的狀態。接收方內部設有一個定時器,每次收到發送方的心跳包時,定時器會被重置。如果在設定的時間內沒有收到心跳包,定時器就會超時。當連續多個心跳周期都出現定時器超時的情況,即連續多個心跳周期都沒有收到心跳包時,接收方就會認為與發送方的連接出現了問題。從而斷當前的連接。

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

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

相關文章

Python 實現的運籌優化系統數學建模詳解(動態規劃模型)

相關代碼鏈接:https://download.csdn.net/download/heikediguoshinib/90713747?spm1001.2014.3001.5503 一、引言 在計算機科學與數學建模的廣闊領域中,算法如同精密的齒輪,推動著問題的解決與系統的運行。當面對復雜的優化問題時&…

langfuse本地安裝

目錄 安裝命令項目準備用openai測試 安裝命令 本地(docker compose):使用 Docker Compose 在你的機器上于 5 分鐘內運行 Langfuse。 # 獲取最新的 Langfuse 倉庫副本 git clone https://github.com/langfuse/langfuse.git cd langfuse# 運行 …

每天學一個 Linux 命令(35):dos2unix

每天學一個 Linux 命令(35):dos2unix 命令簡介 dos2unix 是一個用于將 Windows/DOS 格式的文本文件轉換為 Unix/Linux 格式的實用工具。它主要處理行尾符的轉換(將 CRLF 轉換為 LF),同時也能處理編碼問題和字符集轉換。這個命令在跨平臺文件共享、代碼遷移和系統管理場…

第6章 Python 基本數據類型詳解(int, float, bool, str)細節補充

文章目錄 Python 基本數據類型深入解析(int, float, bool, str)一、整型(int)的底層機制二、浮點型(float)的陷阱與解決方案三、布爾型(bool)的底層本質四、字符串(str)的不可變性與優化五、類型間的隱式轉換與陷阱六、性能優化與工具總結:關鍵細節與最佳實踐Python…

19. LangChain安全與倫理:如何避免模型“幻覺“與數據泄露?

引言:當AI成為企業"數字員工"時的責任邊界 2025年某金融機構因AI客服泄露用戶信用卡信息被罰款2300萬美元。本文將基于LangChain的安全架構與Deepseek-R1的合規實踐,揭示如何構建既強大又安全的AI系統。 一、AI安全風險矩陣 1.1 2025年最新威…

Java快速上手之實驗六

1. 編寫ItemEventDemo.java,當選中或取消選中單選鈕、復選鈕和列表框時顯示所選的結果。 2.編寫GUIExample.java,當選中或取消選中單選鈕、復選鈕時在標簽中顯示相應結果。 import javax.swing.*; import java.awt.*; import java.awt.event.…

QT6 源(72):閱讀與注釋單選框這個類型的按鈕 QRadioButton,及各種屬性驗證,

&#xff08;1&#xff09;按鈕間的互斥&#xff1a; &#xff08;2&#xff09;源碼來自于頭文件 qradiobutton . h &#xff1a; #ifndef QRADIOBUTTON_H #define QRADIOBUTTON_H#include <QtWidgets/qtwidgetsglobal.h> #include <QtWidgets/qabstractbutton.h>…

【算法滑動窗口】 將x減到0的最小操作數

將x減到0的最小操作數 個人總結的八步歸納AI的歸納**8步歸納法&#xff08;極簡直白版&#xff09;**1. 問題本質2. 問題特征3. 切入點4. 解決流程5. 每步目標與操作6. 注意事項7. 最終目標8. 整體總結 代碼對照&#xff08;逐行解析&#xff09;舉個栗子&#x1f330;**一句話…

RISC-V GPU架構研究進展:在深度學習推理場景的可行性驗證

一、新型算力架構的突圍戰 在英偉達CUDA生態主導的GPU市場中&#xff0c;RISC-V架構正以?開源基因?和?模塊化設計?開辟新賽道。當前主流GPU架構面臨兩大痛點&#xff1a; 指令集封閉性?&#xff1a;NVIDIA的SASS指令集與AMD的GCN/RDNA架構均采用私有指令編碼&#xff0c…

LVGL -滑動條

1 滑動條 LVGL 的滑動條(Slider)是一個非常有用的控件,允許用戶通過拖動滑塊或點擊滑條來選擇一個值。 1.1 基本定義 滑動條允許用戶在一個預定義的數值范圍內選擇一個特定的值。它通常由一個軌道(track)和一個滑塊(thumb)組成。用戶可以通過點擊或拖動滑塊來調整數值。…

ROS2學習筆記|Python實現訂閱消息并朗讀的詳細步驟

本教程將詳細介紹如何使用 ROS 2 實現一個節點訂閱另一個節點發布的消息&#xff0c;并將接收到的消息通過 espeakng 庫進行朗讀的完整流程。以下步驟假設你已經安裝好了 ROS 2 環境&#xff08;以 ROS 2 Humble 為例&#xff09;&#xff0c;并熟悉基本的 Linux 操作。 注意&…

WPF封裝常用的TCP、串口、Modbus、MQTT、Webapi、PLC通訊工具類

WPF封裝常用通訊工具類 下面我將為您封裝常用的TCP、串口、Modbus、MQTT、WebAPI和PLC通訊工具類,適用于WPF應用程序開發。 一、TCP通訊工具類 using System; using System.Net.Sockets; using System.Text; using System.Threading.Tasks;public class TcpClientHelper : …

npm pnpm yarn 設置國內鏡像

國內鏡像 常用的國內鏡像&#xff1a; 淘寶鏡像 https://registry.npmmirror.com 騰訊云鏡像?? https://mirrors.cloud.tencent.com/npm/ 華為云鏡像?? https://repo.huaweicloud.com/repository/npm/ CNPM&#xff08;阿里系&#xff09; ?? https://r.cnpmjs.org/ 清華…

P4552 [Poetize6] IncDec Sequence 題解

P4552 [Poetize6] IncDec Sequence - 洛谷 差分貪心 根據題目&#xff1a;一段區間都加1或減1 &#xff0c; 可以想到差分 構建差分數組&#xff1a;sub 我們要讓除了sub[1] , 其他全是0 我們可以的操作是&#xff1a;l1 , r-1 or l-1 , r1 or 一個數1 / -1 所…

Power Query精通指南2:數據轉換——透視/逆透視/分組、橫向縱向合并數據、條件判斷、處理日期時間

文章目錄 七、常見數據轉換7.1 逆透視7.1.1 逆透視操作7.1.2 重建透視表&#xff0c;更新數據7.1.3 三種逆透視方式&#xff08;逆透視列等價于逆透視其他列&#xff09; 7.2 透視7.3 拆分列7.3.1 將列拆分為多列7.3.2 將列拆分為多行7.3.3 拆分到列后逆透視&#xff08;保留列…

使用線性表實現通訊錄管理

目錄 &#x1f680;前言&#x1f99c;任務目標&#x1f31f;順序表實現&#x1f40d;鏈表實現 &#x1f680;前言 大家好&#xff01;我是 EnigmaCoder。 本文介紹線性表的實驗&#xff0c;使用順序表和鏈表實現通訊錄管理&#xff0c;包含初始化、插入、刪除、查詢、輸出。 &a…

firewall docker 沖突問題解決(親測有效)

# 關閉iptables&#xff0c;使用firewall systemctl disable iptables # 禁用服務 systemctl stop iptables # 關閉服務 systemctl status iptables # 查看服務狀態 systemctl enable firewalld # 設置防火墻開機自啟動 systemctl start firewalld # 開啟服務 systemctl s…

[250428] Nginx 1.28.0 發布:性能優化、安全增強及新特性

目錄 Nginx 1.28.0 穩定版發布主要亮點包括&#xff1a;功能增強&#xff1a;安全性改進&#xff1a;其他&#xff1a; Nginx 1.28.0 穩定版發布 Nginx 官方于 4 月 24 日發布了最新的 1.28.0 穩定版本。此版本基于之前的 1.27.x 主線分支&#xff0c;整合了多項新功能、性能優…

昇騰的CANN是什么?跟英偉達CUDA的有什么聯系和區別?【淺談版】

昇騰的CANN&#xff08;Compute Architecture for Neural Networks&#xff09;是華為專門為AI場景設計的異構計算架構&#xff0c;類似于英偉達的CUDA&#xff0c;但它針對的是華為自家的昇騰AI處理器&#xff08;Ascend系列&#xff09;。簡單來說&#xff0c;CANN的作用是連…

C++ STL vector高級特性與實戰技巧

引言 各位小伙伴們好&#xff01;上一篇博客我們介紹了vector的基礎知識和常見操作&#xff0c;今天我們將更深入地探討vector的高級特性、內存管理細節以及實戰應用技巧。 想象一下vector就像一輛能自動變長的公交車&#xff0c;我們上一篇講了如何上下車&#xff08;添加刪…