【計算機網絡原理】對傳輸層TCP協議的重點知識的總結

?????? write in front????????
?????????大家好,我是xiaoxie.希望你看完之后,有不足之處請多多諒解,讓我們一起共同進步????? . ?? ?xiaoxie?????????—CSDN博客
本文由xiaoxie??????????原創 CSDN?如需轉載還請通知?????
個人主頁:xiaoxie?????????—CSDN博客

系列專欄:xiaoxie的計算機網絡學習系列專欄——CSDN博客●'?'σσ??

"探索未來,掌握人工智能"🚀 點擊加入我們的AI學習之旅,讓技術變得有趣又易懂,點擊跳轉
我的目標:"團團等我💪( ??_?? ?)"?

(?????????? )歡迎各位→點贊👍 + 收藏?? + 留言📝?+關注(互三必回)!

目錄

?編輯??一.TCP協議

1.TCP協議的特點

2.TCP協議的格式

1.簡單介紹各個字段

3.TCP的十個重要的機制

1.確認應答

2.超時重傳

1.傳輸的數據出現丟包

2.ACK丟包

3.超時重傳的超時時間如何設定

?4.TCP的可靠性是如何保證的(面試題)

3.連接管理

1.三次握手

1.三次握手的意義是什么,解決了啥問題

2.TCP為啥要三次握手,兩次可以嗎,四次可以嗎

3.TCP三次握手的狀態和Socket api

2.四次揮手

1. 四次揮手是否可以像三次握手一樣,合并成三次揮手呢?

2.TCP四次揮手的狀態(重要)

?3.TCP狀態轉換的詳細圖片

4.滑動窗口

1. 滑動窗口出現丟包的情況:

情況一:數據包抵達了,ACK出現了丟包

情況二:數據包出現了丟包

?編輯

5.流量控制

6.擁塞控制

1.擁塞控制,擁塞窗口, 大小動態變化,具體是咋變的? 是否有規律??

7.延時應答

?8.捎帶應答

9.粘包問題

10.異常情況

?1.其中某一個進程崩潰

2.某個主機被關機(正常關機)

3.某個主機電源斷電(非正常關機)

4.網線斷開

4.如何使用UDP實現可靠性傳輸(面試題)

?編輯


??一.TCP協議

1.TCP協議的特點

1.有連接

在數據傳輸開始之前,TCP需要建立一個連接,這通常通過三次握手來完成。一旦連接建立,數據就可以在兩個端點之間雙向傳輸,直到連接被關閉。

2.可靠傳輸

TCP通過使用序列號、確認應答、數據重傳以及窗口機制等技術,確保數據的可靠傳輸。如果數據包在傳輸過程中丟失或損壞,TCP會重新發送丟失或損壞的數據包,直到接收端正確接收到所有數據。

3.面向字節流

TCP不像UDP那樣傳輸數據報,而是將數據視為連續的字節流。這意味著TCP不保留數據包邊界,它負責將整個數據流從一個端點傳輸到另一個端點。

4.全雙工

TCP允許通信雙方同時發送和接收數據,即數據傳輸是雙向的,并且雙方可以獨立控制數據的發送和接收速率。

2.TCP協議的格式

?

這里只是簡單的介紹一下 ,每一個字段表示的是什么意思,后續會結合具體的TCP機制和字段一起詳細的介紹

1.簡單介紹各個字段

  1. 源端口號(Source Port)16位,用于標識發送方的端口號。端口號用于區分同一IP地址上的不同服務或應用程序。

  2. 目的端口號(Destination Port)16位,用于標識接收方的端口號。端口號同樣用于區分不同服務或應用程序。

  3. 序列號(Sequence Number)32位,用于標識從發送方發送的數據字節的順序。序列號用于確保數據的有序傳輸,并允許接收方檢測丟包。

  4. 確認號(Acknowledgment Number)32位,用于期望從接收方接收的下一個字節的序列號。這是發送方期望接收的下一個字節,用于確認已成功接收數據。

  5. 數據偏移(Data Offset)4位,實際上表示頭部中數據起始處距離報文段開始處的字節數。因為TCP頭部最小長度是20字節,最大可以達到60字節(如果包含所有選項)。這個字段也被稱為“頭部長度”字段。

  6. 保留(Reserved)6位,目前未使用,必須設置為0。

  7. 標志位(Flags)6位,用于控制TCP的行為,具體包括:

    • URG(緊急指針有效 Urgent Pointer):當設置時,表明緊急指針字段有效,指示應優先處理報文段中的緊急數據。
    • ACK(確認號有效 Acknowledgment):當設置時,表明確認號字段包含有效的確認信息。
    • PSH(推 Push):當設置時,指示接收方應盡快將數據推送給應用程序,而不是緩沖。
    • RST(重置 Reset):當設置時,表明需要立即重置連接。
    • SYN(同步序列編號 Synchronize Sequence Numbers):當設置時,用于建立連接時的握手階段,同步雙方的序列號。
    • FIN(結束 Finish):當設置時,表明發送方沒有更多的數據要發送,請求釋放連接。
  8. 窗口大小(Window Size)16位,用于流量控制,指示接收方可以接收的字節數。窗口大小隨時間變化,取決于接收方的緩沖區容量。

  9. 校驗和(Checksum)16位,用于錯誤檢測。包含整個TCP報文段,包括頭部和數據,但不包括數據鏈路層的頭部。

  10. 緊急指針(Urgent Pointer)16位,僅當URG標志位被設置時使用,指示緊急數據的結束位置。

  11. 選項(Options):長度可變,用于各種用途,如:

    • 最大報文段大小(MSS - Maximum Segment Size):通常在連接建立時設置,指示發送方可以接收的最大TCP報文段大小。
    • 窗口縮放(Window Scale):允許使用更大的窗口大小,超過16位可以表示的范圍。
    • 選擇性確認(Selective Acknowledgment, SACK):允許接收方指示哪些數據段已經成功接收,有助于更有效地處理丟包。
  12. 填充(Padding):確保整個頭部是32位的倍數,如果必要的話。

  13. 數據(Data):實際傳輸的數據負載。數據字段的大小取決于頭部的長度和MSS。

TCP頭部的設計旨在提供一種可靠、有序、全雙工的數據傳輸方式,同時允許流量控制和擁塞控制,以適應不同的網絡條件。

3.TCP的十個重要的機制

1.確認應答

對于TCP協議來說,最重要的就是可靠性問題,注意這里的可靠性并不是說使用TCP傳輸數據,數據100%可以從發送方傳輸到接收方,而是TCP盡最大的努力使數據從接收方傳輸到接收方.這其中最重要的就是讓發送方知道,接收方是否收到數據.所以當發生方發生一個數據之后,接收方就會回復一個應答報文,表示自己接收到了信息.

?

那么如何知道這個報文是應答報文呢? 是通過TCP協議格式里的6位標志位來判斷該報文為應答報文的

?而應答 - > acknowledge - > ACK,即ACK這個標志位為1,即可用來表示該報文為應答報文.并且該報文段是一個對之前接收到的數據的應答。接收方使用這個應答來告知發送方它已經成功接收了特定的數據,并準備好接收接下來的數據。

上述單純的應答,如果是批量發送數據的時候,就會出現問題,例如下圖這個情況:

可以看到接收方的ACK并沒有按照順序到達發送方,而是出現了后發先至的效果,這種情況在網絡通信中是不可避免的,那我們該如何區分那個ACK是對應的發送方發送的數據的應答了,這個時候就需要對傳輸的數據進行編號,并且使應答報文的編號和發送的數據的編號對應起來,這個時候就需要用到TCP報頭格式的32位序號和32位確認序號

?TCP序號是按照字節來編號的,并且每個字節都有編號,例如第一個字節序號為1,第二個字節序號為2,字節的編號是連續遞增的,所以我們只要知道第一個字節的序號,剩下的字節的序號就明白了.注意序號不一定是由0或者1開始的,而是根據接收和發送雙方協商好的,(這個后續解釋)例:

如果 一個TCP數據報的載荷為1000字節那么它的序號就為1(這里只是為了簡單就設為1,真實情況可能為別的數,但是其連續遞增的性質不變);

它的確認序號就非常有意思了,它的取值就為要應答的數據的最后一個字節在 + 1;

也就是如果以上圖這個TCP數據報舉例,那么它的應答報文的確認序號就為1001,即:

其中的確認序號可以從兩個方面來理解:

1.對于接收方來說, < 1001 的數據已經確認收到了

2.接收方在向發送方索要從1001開始的數據.

這個序號和確認序號設計的非常精妙不僅完美的解決了網絡傳輸先發后至的問題,還未后續的機制帶來了很多遍歷.

2.超時重傳

TCP中最核心的就是可靠性傳輸,而可靠性傳輸主要就是依靠確認應答,但是如果出現,ACK或者數據在網絡傳輸的過程出現丟包的情況,這個是無法避免的,是客觀存在的,這個時候TCP就是使用超時重傳這個策略來應對這個情況的,可以說,超時重傳時確認應答的重要補充,TCP之所以可以可靠性傳輸,全靠,確認應答和傳輸重傳這兩個機制.

在網絡傳輸的過程中,有可能是傳輸的數據出現丟包的情況,也有可能是ACK應答報文出現丟包的情況.不同的情況,自然TCP解決的方式就不一樣了.

1.傳輸的數據出現丟包

正常情況下,TCP是依靠確認應答來確定接收方是否接收到發送方傳輸的數據.如果出現下圖的情況,即發送方發送的數據在網絡傳輸的過程中,出現丟包的情況,接收方沒有收到數據自然也就不會發送ACK應答報文了

而發送方就可以根據是否收到ACK,來判斷是否出現丟包的情況.正常情況下,發送方發送數據到接收方,到接收方發送ACK給發送方,在網絡傳輸可能會經歷一段時間的,但如果超過規定的超時時間的一個閾值(超時),發送方就會認為數據丟包了,就會重傳數據給接收方,注意:哪怕數據并沒有出現丟包,只是傳輸時間過長即超過閾值(這個是有可能發生的),也會被認為數據發生丟包.這個就是超時重傳機制.至于接收方會收到兩份相同的數據,不用擔心,接收方會有相應的策略進行數據的去重(后續介紹).

2.ACK丟包

傳輸的數據出現丟包,ACK自然也可能出現丟包的情況.如下圖所示:

?站在A的視角之中,它無法判斷是數據發生了丟包,還是ACK發生了丟包的情況,只要超過一定的時間之內,它就會重傳數據.這個時候B就會收到兩份相同的數據了,發生這種情況如果B沒有相應的策略的話,就會造成很嚴重的后果,就比如,你轉賬時,觸發了超時重傳機制就會發生重復轉賬的操作,所以TCP為了防止這個情況的發生,就設計了一個策略,通過序號對數據進行去重,那么是如何實現這個策略的呢;

在接收方操作系統的內核中,有一個數據結構 ->接收緩沖區 - > 優先級阻塞隊列;

B(接收方)在收到數據的時候層層分用,到了傳輸層的時候,就會把傳輸的數據先存儲到這個阻塞隊列中,再從阻塞隊列中以此的讀取數據.在放的過程中是阻塞隊列就會根據當前數據的序號來判斷當前這個數據是否存在過,如果存在就丟棄,不存在才放到隊列中.那么阻塞隊列是如何判斷數據是否存在過的呢,這個時候就要根據之前提到過的數據的序號是連續遞增的,如果當前數據出現和在隊首的數據的序號相同或者小于的情況就說明,當前數據曾經存在或者現在就在隊列中,就會把這個數據給丟棄掉.從而達到去重的效果.

由于隊首元素為1000,這個時候有個序號為500的數據想要加入隊列中,就會被丟棄,因為隊首元素的序號為1000就說明序號為500的數據曾經出現過,就不能重復傳輸了.

3.超時重傳的超時時間如何設定

首先需要明確,這個時間并不是固定的,而是動態變化的,也就是說,假設第一次的超時時間為 50ms(這個時間是操作系統規定,我這里是隨意寫的),等待50ms后沒有收到數據,觸發超時重傳,第二次的超時時間就為100ms如果還是沒有收到,就繼續重傳,這個時候超時時間就變成了150ms.當然這個時間并不一定是這樣增長的,具體的增長是由操作系統決定,總之,這個超時時間它是會動態增長的.而不是一直是固定某個數值,也不會縮短(畢竟發生多次丟包,后續成功的可能性也就越來越低了,縮短超時時間反而浪費系統資源).

注意:如果網絡出現故障,重傳多次后,依然不成功,達到一定的閾值之后,就會嘗試重置連接即觸發一個"復位報文"重置連接即6位標志位其中一位的"RST"這個時候就會把之前TCP連接傳輸的中間狀態給清空,例如接收緩沖區的數據都會清空.重新開始傳輸.這個時候如果還是無法傳輸的話,就會斷開連接

?4.TCP的可靠性是如何保證的(面試題)

這個時候就需要回答也只能回答依靠 確認應答機制和傳輸重傳機制不能多也不能少然后在回答具體的機制的內容即可.這里就不過多的贅述了.

3.連接管理

1.三次握手

TCP建立起連接就是,通過實現三次握手實現的,三次握手即,通信的雙方通過三次網絡交互,互相保存對方的信息,即為建立起了連接.

注意:第一次發起連接的 一定是客戶端,也就是說誰發起的誰就是客戶端,假如是服務端發起的,它就不是服務器了,而是客戶端了,同時這個在三次握手期間,發送的數據報是不攜帶任何業務數據的,也就是該數據的載荷部分是空的,只有TCP報頭,如果是同步報文,它的六位標志位其中的一位"SYN"為1.

?同時在上述建立連接的過程中,其實就是客戶端和服務端,互相給對方發送SYN,再各自給對方發送ACK,其實是四次交互,那為什么是三次握手呢,主要是因為在建立連接的過程中,傳輸的數據都沒有載荷,就可以把,中間過程的服務端向客戶端發送,ACK和SYN就可以合并,即在服務端給客戶端發送數據的TCP報頭的標志位中的"ACK"和 "SYN"的bit為1即可,實現合并操作就可以減少消耗,提高性能.

?這里解釋一下雙方為什么要向對方發送SYN:

首先我們要知道建立連接就是,通信雙方要互相保存對方的信息,也就是客戶端發送SYN給服務端,服務端收到SYN就保存了客服端的信息,并且給服務端發送ACK和?SYN,客服端接收到了ACK,就表明客服端的發送數據的能力沒問題,服務端的接收能力沒問題,并且客戶端接收到了服務端的SYN后,也就保存了服務端的信息,就返回ACK,服務端接收到ACK后就說明服務端的發送數據的能力沒問題,客戶端接收數據的能力沒問題,這樣通信雙方都保存了對方的信息,并且雙方的接收能力和發送的能力沒問題,就說明連接成功了.

1.三次握手的意義是什么,解決了啥問題

1.三次握手就是在正式傳輸數據之前,確認通信線路是否通暢,確保可以建立一個穩定的連接,相當于TCP可靠性傳輸的一個輔助機制,注意:如果如果在面試中被問到TCP如何保證可靠性傳輸,不可以回答三次握手,而是回答,確認應答和超時重傳即可.

2.通過三次握手來確認通信雙方,發送能力和接收能力都是正常的,這一點就不過多的解釋了.

3.三次握手的過程中還需要協商一些必要的參數,這里重點介紹一下,TCP通信時使用的序號就是在三次握手的過程中出來的,也就是說序號一般并不是從 0 /1 開始的,而是在通信雙方協商出來的,至于時如何協商的,協商出來的序號到底都是啥,比較復雜,再加上也不是重點,博主就不過多的解釋了,這里的重點是要明白,每一次建立連接協商的序號的差異往往非常大的,至于`為什么要這樣設計,這里重點解釋一下:

就是在通信的過程中,通信雙方先建立連接,進行數據交互,之后斷開連接,過了一會,又建立了連接,進行數據交互,假如在這個過程中,某個數據報在網絡傳輸的過程中花費的時間比較長? -> 等它傳輸到服務端的時候,這個服務端已經是斷開連接后,又重新建立一個新的連接了 - > 這個時候服務端接收到這個數據是該丟棄還是按照正常的邏輯執行呢 - > 自然是應該丟棄,因為客戶端和服務端斷開連接后,又重新建立連接,重新建立連接的服務端不一定是之前的服務進程了,即執行的業務就不相同了,自然就得丟棄.? - > 如何判斷這個數據報是之前的連接的數據報呢,自然是通過序號咯,如果是同一個連那么序號的差別就不大,不是一個連接序號的差別就非常大,這個時候就可以區分出來該數據報是否為前一個連接的數據報,這也就是為什么每一次連接協商的數據報的序號的起始差別要非常大的原因了.

通過序列號的機制,TCP協議可以防止舊的數據包干擾到新的連接,確保數據傳輸的準確性和可靠性。這確保了即使在網絡條件不穩定、連接頻繁斷開和重新建立的情況下,數據傳輸也能夠保持有序和正確。

2.TCP為啥要三次握手,兩次可以嗎,四次可以嗎

兩次不可以:服務端無法確保它的發送數據的能力和客戶端的接收能力,無法確保雙向通信的可靠性四次可以但不建議:如果把"ACK" 和 "SYN"改成分兩次發送是可以實現,但是這樣并不會提高傳輸數據的準確性,反而降低了性能,例如:網絡交互增加,消耗的網絡資源增加,還增加了丟包的可能性等等減低性能的缺點.

3.TCP三次握手的狀態和Socket api

Socket api 就不過多的解釋了,主要介紹一下三次握手過程中客戶端和服務端的狀態,?

listen: 只有服務端才會存在的狀態,也就是在服務端綁定端口成功后,就會進入 Listen 狀態,即為 監聽狀態,表示隨時都會有客戶端連接上來.

Established: 表明連接建立完成.

至于其他的狀態就不是很重要了.

2.四次揮手

斷開連接即通信的雙方把對方的信息給刪除掉,即四次揮手.同時注意三次握手,一定是客戶端發起第一次的,而四次揮手,通信雙方都可以都可以主動發起,這里就以客戶端主動發起為例:

在四次揮手過程中傳輸的數據也是一樣不攜帶任何業務數據,即TCP數據報的載荷為空,只有TCP報頭,其中的FIN結束報文,就是6位標志位的FIN位的bit位為1.

1. 四次揮手是否可以像三次握手一樣,合并成三次揮手呢?

答案是如能--- 在特殊情況下可以,一般情況下不能 為什么呢?

三次握手的ACK和 SYN的發送都是由系統內核控制的自動發送,也就是說他們的發送的時間是一至,所以就可以合并成一次`發送 ACK + SYN.

而四次揮手的ACK是由系統內核控制的,但是服務端的FIN(結束報文)卻是由應用程序代碼控制的,也就是說只有當代碼調用 close 的時候才會發送FIN(結束報文),通常在應用程序完成數據傳輸并調用close()函數時觸發,

所以這兩個數據報的觸發時間是不一樣的,所以難以合并,至于什么時候可以合并,

那就是當,TCP觸發延時應答機制的時候(要回復ACK,但是不是立即發送,而是稍等一會)這個情況就可以合并.

速關閉:如果客戶端和服務器幾乎同時決定關閉連接,并且他們的FIN包在網絡中相遇,那么接收方可以在回復對方的FIN時同時發送ACK和自己的FIN,這樣就減少了一次握手。

但畢竟是上述都是特殊情況,所以我們一般認為它就是進行四次揮手.

2.TCP四次揮手的狀態(重要)

1.Close_Wait?

就是被動的一方進入的狀態,等待代碼調用 close()方法,代碼調用close()越及時,就越不可能看到,假如我們在服務器中看到大量的 Close_Wait 狀態的時候 => 代碼可能忘調用close, 或者是 close 調用的不夠及時.

2.Time_Wait

Time_Wait狀態是TCP連接終止過程中的一個正常階段,它發生在主動關閉連接的一方(通常是客戶端)在發送完FIN包并接收到對方的FIN包后,進入的一個等待狀態,它主要是為了應對最后一個ACK丟包的情況.同時需要注意?Close_Wait 并不是一定為服務端的狀態,而是被動一方的狀態,Time_Wait也不一定是客戶端的狀態,而是主動一方的狀態

也就是當客戶端在收到服務端返回的FIN以及發送ACK的時候并不會立即釋放連接,就是為了服務端沒有收到客戶端的ACK(丟包)的情況,觸發重傳FIN,要是釋放了連接后,客戶端就無法返回ACK了,當然Time_Wait的持續時間是有限的,也就是說,客戶端在等待一般是 2 msL 之后這個時間足夠長,以確保所有可能的重傳數據包都被處理完畢就不在等待而是釋放連接了,默認服務端接收到了ACK了.當然也是有可能發送ACK又丟包的情況的,但是只要超過了限定的時間客戶端直接就斷開連接.

1.如果服務端出現大量的Time_Wait時該如何處理

服務端出現大量的Time_Wait就說明服務端在大量的主動斷開TCP連接,這顯然是不科學的,

代碼審查:檢查應用程序代碼,特別是與網絡通信相關的部分。

短連接模式:如果應用程序頻繁地創建和關閉連接,而不是重用連接,這將導致大量的TIME_WAIT

網絡問題:網絡波動或不穩定可能導致連接意外中斷,從而產生大量的TIME_WAIT

?3.TCP狀態轉換的詳細圖片

注意掌握博主之前提及的 四種狀態即可,其余的狀態遇到了,看一下這個圖即可.

4.滑動窗口

TCP除了保證可靠性傳輸之外,也希望能夠盡可能高效的完成數據傳輸,其中滑動窗口就是一種,TCP用來提高傳輸效率的機制.

不引入滑動窗口,數據傳輸的過程

對每?個發送的數據段, 都要給?個ACK確認應答. 收到ACK后再發送下一個數據報. 這樣做有一個比較大的缺點, 就是性能較差. 尤其是數據往返的時間較長的時候.
引入滑動窗口,數據傳輸的過程

引入滑動窗口后,就把一條一條發送數據 = > 批量發送數據,批量發送就把等待時間重疊了,就可以提高性能.同時注意雖然是批量發送,但還是需要等待ACK否則無法保證可靠性.

窗口大小:不等待ACK,批量發送數據的多少,就是窗口大小,這個值不是固定的,它是通過其他的機制,確定的,這個下文博主會介紹到.

上圖就表示,窗口大小為4,批量發送1001 - 5001這四組數據,同時等待這四組數據的ACK,此時如果收到?2001ACK,就說明1001 - 2000 這個數據就得到了確認,就標記為灰色了,此時就需要繼續等待2001-5001的ACK,于此同時,發送新的數據5001- 6001,依舊是四組數據.也就是說批量發送四組數據并不是要等到接收四組ACK后再繼續批量發送,而是收到一個ACK,就往后發一個新的數據,這個窗口就滑動起來了.

同時注意如果 收到的是3001的ACK,就說明 < 3001 的數據已經接收到了,窗口就會往后滑動兩個"格子".

1. 滑動窗口出現丟包的情況:

要保證可靠性

情況一:數據包抵達了,ACK出現了丟包

假如是 1001 這個ACK丟包了,這個時候并不需要做任何的處理,因為,即使1001 這個 ACK丟了,主機A在收到2001這個ACK的時候,就說明1-1000 , 1001 - 2000 的數據都收到了,就涵蓋了1001這個ACK起到的效果,所以只要數據包抵達了,ACK出現丟包的情況,并不需要做任何處理,也能保證可靠性.

情況二:數據包出現了丟包

?假如是1001 - 2000 這個數據包出現了丟包的情況,主機A依然會繼續向主機B往后發送數據,主機B? ?此時向主機A發3次重復的1001 ACK向主機A索要1001 - 2000 的數據包,如果主機A收到了3個同樣的ACK的話,就會進行重發操作,注意這里只重發 1001 - 2000 這個數據包,別的數據包并不會重發,當主機A收到了7001這個ACK后,就說明 1 - 6000 這些數據包都收到了,

上述這兩個丟包情況,就是通過快速重傳這個機制實現的,整個過程是十分高效的那么,快速重傳和 超時重傳是否存在沖突呢.

答案當然是不會咯,快速重傳就相當于超時重傳的在滑動窗口下的一個變種機制,本質上是一樣的.并且在傳輸的數據不多的時候是不會觸發滑動窗口機制的.這個時候發送丟包就需要用到超時重傳了.

注意:哪怕滑動窗口在牛逼,TCP在效率方面還是UDP更牛一些.

5.流量控制

滑動窗口中最關鍵的就是窗口大小,其中窗口大小是可變的,可以通過控制窗口大小從而控制發送方的發送速度,即窗口越大,發送的數據也就越多,效率也就越高,但是如果窗口過大,接收方處理不過來,就會導致丟包的情況,從而影響到可靠性,所以呢,應該要接收方要根據自己的處理能力,然后反制約于發送方,使雙方到達一個平衡.這就是流量控制.

給如何,衡量接收方的處理速度呢?

主要使根據接收方的接收緩沖區來衡量的

接收方的窗口大小就為未使用空間的大小.每次接收方接收到數據后,返回的ACK的報頭中,就包含了16位窗口大小,告知,接收方的數據處理能力,從而控制發送方的窗口大小

?注意16位窗口大小并不意外著,窗口最大為64kb而是更大,因為窗口大小并不僅僅和16位窗口大小有關,還和選項的窗口擴展因子有關,這里就不展開說明如何計算了,只需要記住窗口大小是可以非常大的.

發送方接收到這個ACK后就根據上述接收方指定的窗口大小來發送數據.

?當接收方的接收緩沖區滿了之后,接收方就會告訴發送方,停止發送數據,等過了一段數據后,接收方消費了一些數據后,接收緩沖區又有空閑空間了,但是發送方停止發送數據了,接收方自然就無法發送ACK告訴發送方了.那么該如何解決呢?

這個時候一旦發送方過了重發超時的時間,還沒有接收到接收方的ACK,就會向接收方發送一個不帶載荷的窗口探測包,詢問窗口大小,只要沒收到ACK或者沒收到窗口大小更新的通知,就會定時的發送.這個還是非常之精妙的.

6.擁塞控制

和流量控制一樣,擁塞控制也是用來和滑動窗口搭配的機制,也就是說擁塞控制也是控制窗口大小的.

流量控制是根據接收方的接受能力來反向制約發送方從而控制窗口大小.

擁塞控制考慮的則是考慮到發送方和接收方中間網絡通信節點的像設備,路徑等等之類的因素,然后把它們看做一個整體,通過實驗的方式,來確定窗口大小

動態的找到一個速度快并且可靠性高的窗口大小.

注意:流量控制可以控制窗口大小\,擁塞控制也可以控制窗口大小,那么具體的窗口大小到底是根據那個機制呢 => 那個機制確定的窗口小,就根據那個機制

1.擁塞控制,擁塞窗口, 大小動態變化,具體是咋變的? 是否有規律??

1.慢開始:剛開始以,比較小的窗口 來傳輸數據
2.按照指數方式擴大窗口(*2)
注意這里的“慢”說的是剛開始 窗口大小比較小,傳輸速度慢而不是窗口大小的變化速度慢 (指數增長非常快的)
3.指數增長過程中,達到某個閫值,就要變成線性增長.(+n)
線性增長,也是增長,發送速度越來越快增長到一定程度,就會出現丟包.當發送端檢測到丟包時(超時或者3個重復ACK)就開始縮小窗口(快速重傳)

縮小有兩種方式:
1.直接縮到底.(回到了最初慢啟動的時候)接下來指數增長-線性增長
現在已經廢棄了.(之前TCP的做法).

2.快速恢復:縮到出現丟包時窗口大小 一半 這樣的位置接下來線性增長.(目前使用的方法).
?

注意這里只是大體介紹了一下過程,具體過程的算法及公式什么的還是比較復雜的,這里就不過多的解釋了,感興趣的可以去查一下資料.

7.延時應答

ACK不會立即返回,而是延時一會再返回.TCP四次揮手在特殊情況下就是因為這個機制就可以變成三次揮手.(簡單提一下前面的知識).

為什么要延時應答呢,自然是為了提升效率,而TCP提升效率主要就是增加窗口大小,延時應答就是在保證可靠性的前提下,提高窗口大小.

舉個例子

假設當前接收緩沖區的空閑空間為5kb,當接收到發送方的2kb數據后,空閑空間就變成3kb,這個時候就要根據空閑空間來返回窗口大小.如果為我們是立即返回這個ACK的話,那么窗口大小就是3kb(不考慮窗口擴展因子),如果延時返回ACK,用于接收緩沖區里的數據是會被消費和讀取的啊,我空閑空間就會變大,也就是返回的窗口大小是大于 3kb的(具體多少不過多計算了)從而提高了效率.

注意:這里的延時時間主要是根據一定時間和接收的數據量結合來規定的,具體如何計算不多說.
?

?8.捎帶應答

建立在延時應答的基礎上的一個提升效率的機制.

在我們日常開發中,客戶端和服務端通常是"一問一答"這樣的模型

因為延時應答機制,ACK會延時一會,在返回,如果這個時候服務端剛好執行完業務邏輯要發送響應的時候,這個響應數據就會把TCP報頭的ACK標志位設為1,以及窗口大小等.就把這個ACK給合并了.這樣兩次傳輸,就變成一次傳輸,提高了效率.

9.粘包問題

TCP是一個面向字節流的協議,這意味著TCP不保證數據包的邊界。在TCP連接上發送的數據是按字節序列傳輸的,而TCP本身并不為每個消息添加開始和結束的標記。因此,如果應用程序發送了多個數據包,它們可能在接收端被“粘”在一起,變成一個更大的數據包,這就是所謂的“粘包”問題。

粘包問題可能導致接收方無法正確地識別單個消息的邊界,從而無法正確地處理接收到的數據。以下是一些可能導致粘包問題的情況:

  1. 發送多個小數據包:如果發送方連續發送多個小的數據包,它們可能在網絡中的某個點被合并為一個較大的數據包。

  2. 接收緩沖區大小:如果接收方的接收緩沖區足夠大,它可以一次性接收多個數據包,導致這些數據包被粘在一起。

  3. 網絡延遲:由于網絡延遲或擁塞,發送方發送的數據包可能在網絡中被延遲,導致它們到達接收方時被合并。

  4. 應用程序處理速度:如果接收方處理數據的速度比發送方慢,它可能來不及處理接收到的數據包,導致數據包在接收緩沖區中累積。

為了解決粘包問題,可以采取以下幾種策略:

  1. 固定長度消息:發送固定長度的消息,接收方可以根據消息長度來確定消息邊界。

  2. 消息邊界標記:在每個消息的末尾添加特殊的分隔符或標記,接收方可以通過查找這些標記來識別消息邊界。

  3. 消息長度字段:在每個消息的開頭添加一個表示消息長度的字段,接收方可以根據這個長度來確定消息邊界。

  4. 使用應用層協議:使用應用層協議(如HTTP、FTP等)來定義消息結構,這些協議通常有自己的消息邊界定義。

粘包問題不僅僅是在TCP中會出現,它可能出現在任何需要處理數據流的場合.,這個還是比較關鍵的,我們可以根據TCP的解決方法來解決其他協議或者是其他別的應用粘包問題

10.異常情況

?1.其中某一個進程崩潰

進程崩潰也好,正常結束也好,操作系統,都能夠回收釋放對應的 PCB,可以釋放里面的文件描述符表也就相當于調用 close.此時仍然會正常和對方進行四次揮手操作

2.某個主機被關機(正常關機)

對于這種正常流程的關機,操作系統會先嘗試強制結束所有的用戶進程,然后再進入關機流程這個過程也會和上面一樣,結束進程之后,進行四次揮手.

如果主動觸發 FIN 了之后的流程沒走完,系統就已經關機了:
A 和 B 建立 TCP 連接, A 這邊關機了A 關機之前給B發送FINB 這邊收到了 FIN, B 返回 ACK, 代碼進入下一階段流程B準備發送 FIN此時如果 A 已經關機了,意味著 B 接下里的 FIN 就會反復重傳幾次A就算沒有反應,B也會把保存A的信息給刪除A關機了自然就把B給刪除,這樣就斷開連接了.

3.某個主機電源斷電(非正常關機)

A 和 B 通信,A 突然掉電了:
A 無法做出任何反應,就關機了!
B 還傻傻的以為 A 還存在呢,這個時候又分兩種情況:
1.B 是發送數據方.
B 接下來發送給A的數據,都不會有 ack 了,這個時候B 就會觸發超時重傳,重傳幾次之后,發送復位報文 (RST).RST 也沒有響應,B 就會單方面刪除保存的 A 的信息
2.B 是接收方
接收方(被動一方),無法知道對方啥時候給我發數據當 A 沒有發送數據之后, B 也不知道 A 是暫時暫停一會,還是 A掛了B 在一定時間之內沒收到 A 的數據之后, 就會觸發 心跳包,
心跳包,就可以認為是一個 沒有載荷 的數據包只是為了觸發 ack
B 給 A 發了一個心跳包, 如果 A 正常, A 就會回應 ACK如果 A 掛了,B 不會收到任何回應.連續發了若干次,A 都沒有回應, 這個時候 B 就認為 A 掛了,于是單方面釋放連接.

注意:
tcp 雖然內置了心跳包,但是這個心跳包,周期比較長,依賴通過這個心跳發現對端掛了,往往需要 分鐘級別 這樣的時間在實際開發中,經常會實現應用層的心跳包,用更高頻率,更短周期發送心跳.(ping-pong)
A->B發-個 ping??B ->A 回復一個 pong 秒級/毫秒級~,一旦某個設備掛了,就可以更快速的發現問題

4.網線斷開

本質上就是第三種情況A 和 B 之間建立 TCP 連接,A 和 B 之間的網線斷開了
比如,A 是發送方,B 是接收方,A 的角度,就會觸發超時重傳, 觸發 RST, 單方面刪除信息,B 的角度,就會觸發 心跳包, 對方無響應,單方面刪除信息!

4.如何使用UDP實現可靠性傳輸(面試題)

這一題看似考的是UDP其實是考TCP如何保證可靠性傳輸,所以要使用UDP實現可靠性就要在應用層中引入確認應答,超時重傳等機制.具體內容就根據上述TCP機制來回答就可.

以上就算關于TCP的一些重點內容,要想了解更詳細的內容,博主推薦觀看<TCP/IP協議>這本書,感謝你的閱讀,祝你一天愉快.

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

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

相關文章

Spring Bean Map漫游:遍歷背后的生命周期奧秘

1. 引言 在Spring框架中&#xff0c;Bean的生命周期是一個復雜而精妙的過程。其中&#xff0c;遍歷存儲Bean實例的Map&#xff08;通常是DefaultSingletonBeanRegistry中的singletonObjects&#xff09;是這一過程中的重要環節。理解這個遍歷過程以及它在Bean生命周期中的作用…

桌面文件不見了怎么恢復?五種方法解決文件恢復難題,建議收藏

不小心誤刪除了桌面文件&#xff0c;導致文件丟失。事實上誤刪的文件并沒有被永久刪除&#xff0c;而是被移動到了回收站中&#xff0c;可以恢復這些文件。本文將分享多種方法&#xff0c;具體步驟如下。 方法一&#xff1a;從回收站中恢復 大多數操作系統都有回收站或垃圾桶的…

【C語言】結構體內存對齊:熱門面試話題

&#x1f525;引言 書接上文&#xff0c;我們了解關于結構體的基本知識&#xff0c;這篇將深入剖析結構體中一個重要的知識點:內存對齊 關于內存對齊是屬于熱門面試話題&#xff0c;對此單獨放在一篇來分享 &#x1f308;個人主頁&#xff1a;是店小二呀 &#x1f308;C語言筆記…

3D工業視覺

前言 本文主要介紹3D視覺技術、工業領域的應用、市場格局等&#xff0c;主要技術包括激光三角測量、結構光、ToF、立體視覺。 一、核心內容 3D視覺技術滿足工業領域更高精度、更高速度、更柔性化的需求&#xff0c;擴大工業自動化的場景。 2D視覺技術基于物體平面輪廓&#…

軟件無線電學習-第二代移動通信系統過程理解

本文知識內容摘自《軟件無線電原理和應用》 無線通信領域讓大家感受最深的是民用移動通信的快速發展。民用移動通信在短短的二十年時間里已發展了三代&#xff1a;20世紀80年代的模擬體制(TACS/AMPS)為第一代移動通信(簡稱1G)&#xff1b;20世紀90年代的數字體制(GSMCDMATDMA)…

Git提交和配置命令

一、提交代碼到倉庫 在軟件開發中&#xff0c;版本控制是一個至關重要的環節。而Git作為目前最流行的版本控制系統之一&#xff0c;為我們提供了便捷高效的代碼管理和協作工具。在日常開發中&#xff0c;我們經常需要將本地代碼提交到遠程倉庫&#xff0c;以便于團隊協作和版本…

2024電工杯數學建模B題思路模型代碼

完整內容更新見文末名片 B 題&#xff1a;大學生平衡膳食食譜的優化設計及評價 大學時代是學知識長身體的重要階段&#xff0c;同時也是良好飲食習慣形成的重要時期。這一特 定年齡段的年輕人&#xff0c;不僅身體發育需要有充足的能量和各種營養素&#xff0c;而且繁重的腦…

Java基礎教程 - 9 集合

更好的閱讀體驗&#xff1a;點這里 &#xff08; www.doubibiji.com &#xff09; 更好的閱讀體驗&#xff1a;點這里 &#xff08; www.doubibiji.com &#xff09; 更好的閱讀體驗&#xff1a;點這里 &#xff08; www.doubibiji.com &#xff09; 9 集合 什么是集合&…

【stm32/CubeMX、HAL庫】嵌入式實驗六:定時器(2)|PWM輸出

參考&#xff1a; 【【正點原子】手把手教你學STM32CubeIDE開發】 https://www.bilibili.com/video/BV1Wp42127Cx/?p13&share_sourcecopy_web&vd_source9332b8fc5ea8d349a54c3989f6189fd3 《嵌入式系統基礎與實踐》劉黎明等編著&#xff0c;第九章定時器&#xff0c…

愛普生TG5032SFN溫補晶振在機器人控制中的應用

機器人控制是機器人技術的核心組成部分&#xff0c;它涉及通過傳感器采集外部環境信息&#xff0c;然后經過信號處理、運動規劃和執行控制等步驟&#xff0c;最終實現機器人的運動控制和任務執行。在技術的不斷更選&#xff0c;機器人控制也在不斷進步和演變。智能化機器人具備…

cannot compute sizeof(off_t) when compile netcdf-fortran

export LD_LIBRARY_PATH/netcdf-c/lib:$LD_LIBRARY_PATH

Z緩沖技術在AI去衣中的關鍵角色

引言&#xff1a; 人工智能&#xff08;AI&#xff09;技術的飛速發展&#xff0c;為圖像處理領域帶來了革命性的變化。其中&#xff0c;AI去衣技術作為一種新興的應用&#xff0c;引起了廣泛關注。它不僅在多媒體內容的編輯、虛擬現實和增強現實等領域具有重要的應用價值&…

Jenkins 構建 Maven 項目:項目和服務器在一起的情況

bash.sh內容 #!/bin/bash#刪除歷史數據 rm -rf ruoyi-admin.jar# appname$1 appnamevideo.xxxxx.com #獲取傳入的參數 echo "arg:$appname"#獲取正在運行的jar包pid # pidps -ef | grep $1 | grep java -jar | awk {printf $2} pidps -ef | grep $appname | grep ja…

1673. 找出最具競爭力的子序列

題目 給定一個整數數組 nums 和一個正整數 k&#xff0c;返回長度為 k 且最具競爭力的 nums 子序列。 數組的子序列是從數組中刪除一些元素&#xff08;可能不刪除元素&#xff09;得到的序列。 在子序列 a 和子序列 b 第一個不相同的位置上&#xff0c;如果 a 中的數字小于…

mysql 刪除特殊字符 表中存了特殊字符 換行符 回車符 word字符 查詢不到

省流&#xff1a; UPDATE t1 SET f1 REPLACE(REPLACE( f1 , CHAR(10), ), CHAR(13), ); 用 replace() 函數將 換行符char(10) 和 回車符char(13) 替換為空字符串。 char(10)&#xff1a;換行 char(13)&#xff1a;回車 發現表里存進很多換行符&#xff0c;如下圖&#xff1a…

深入研究Qt Meta - Object System

目錄 先說RTTI 再說QMeta Object System 關于Q_OBJECT 這篇文章我打算研究一下QMetaObject System&#xff0c;也就是Qt自己構建起來的元對象系統。 先說RTTI 啥是RTTI&#xff1f;這是C編程里的一個常見術語&#xff0c;全稱是&#xff1a;運行階段類型識別&#xff08;Ru…

Chrome DevTools攻略

Chrome DevTools&#xff0c;也稱為Chrome開發者工具&#xff0c;是一套直接內置于Google Chrome瀏覽器的Web開發者工具。以下是一些使用Chrome DevTools的攻略和技巧&#xff1a; 打開DevTools&#xff1a; 右鍵點擊頁面上的任何元素&#xff0c;選擇“檢查”或“審查元素”。…

2024年華為OD機試真題-機場航班調度程序-C++-OD統一考試(C卷D卷)

題目描述: XX市機場停放了多架飛機,每架飛機都有自己的航班號CA3385,CZ6678,SC6508等,航班號的前2個大寫字母(或數字)代表航空公司的縮寫,后面4個數字代表航班信息。但是XX市機場只有一條起飛用跑道,調度人員需要安排目前停留在機場的航班有序起飛。為保障航班的有序起…

【webrtc】MediaEngine的實現CompositeMediaEngine創建VOE

m98音視頻的引擎是管理channel的看起來是外部強加給CompositeMediaEngine 管理的。CompositeMediaEngine :合成媒體引擎 G:\CDN\rtcCli\m98\src\media\base\media_engine.h// CompositeMediaEngine constructs a MediaEngine from separate // voice and video engine classes…

Python中文分詞工具庫之jieba使用詳解

概要 在自然語言處理(NLP)領域,中文文本的分詞是一個重要且基礎的任務。Python的jieba庫是一個廣泛使用的中文分詞工具,提供了豐富的功能,包括精準模式、全模式、搜索引擎模式等,適用于不同的應用場景。本文將詳細介紹jieba庫,包括其安裝方法、主要特性、基本和高級功能…