【網絡基礎】傳輸層
文章目錄
- 【網絡基礎】傳輸層
- 1、端口號
- 1.1 工具
- 2、UDP協議
- 2.1 協議端格式
- 2.2 UDP特點
- 2.3 傳輸數據報
- 2.4 緩沖區
- 2.5 基于UDP應用層協議
- 2.6 使用注意事項
- 3、TCP協議
- 3.1 協議段格式
- 3.2 ACK機制
- 3.3 超時重傳機制
- 3.4 連接管理機制
- 3.5 滑動窗口
- 3.6 流量控制
- 3.7 擁塞控制
- 擁塞窗口
- 3.8 延遲應答
- 3.9 捎帶應答
- 3.10 粘包問題
- 3.11 TCP異常
- 4、TCP/UDP對比
1、端口號
端口號(Port)標識了一個主機上進行通信的不同的應用程序

在TCP/IP協議中, 用 “源IP”, “源端口號”, “目的IP”, “目的端口號”, “協議號” 這樣一個五元組來標識一個通信(可以通過 netstat -n查看)


TCP/P或UDP/IP通信中通常采用5個信息來識別一個通信。它們是“源IP地址”、“目標IP地址”、“協議號”、“源端口號”、“目標端口號”。只要其中某一項不同,則被認為是其他通信。
如何確定端口號
在實際進行通信時,要事先確定端口號。確定端口號的方法分為兩種:
-
標準既定的端口號(靜態方法),它是指每個應用程序都有其指定的端口號。
像HTTP、TELNET、FTP等廣為使用的應用協議中所使用的端口號是固定的。這些端口號也被稱之為知名端口號(Well—Known Port Number ),0-1023。應用程序應該避免使用知名端口號進行既定目的之外的通信,以免產生沖突。
有些服務器是非常常用的, 為了使用方便, 人們約定一些常用的服務器, 都是用以下這些固定的端口號:
ssh服務器, 使用22端口
ftp服務器, 使用21端口
telnet服務器, 使用23端口
http服務器, 使用80端口
https服務器, 使用443
除知名端口號之外,還有一些端口號也被正式注冊,不過,這些端口號可用于任何通信用途。它們分布在1024到49151的數字之間。
-
時序分配法(動態分配法),此時,服務端有必要確定監聽端口號,但是接受服務的客戶端沒必要確定端口號。
在這種方法下,客戶端應用程序可以完全不用自己設置端口號,而全權交給操作系統進行分配。操作系統可以為每個應用程序分配互不沖突的端口號。例知,每需要一個新的端口號時,就在之前分配號碼的基礎上加1。這樣,操作系統就可以動態地管理端口號了。
根據這種動態分配端口號的機制,即使是同一個客戶端程序發起的多個TCP連接,識別這些通信連接的5部分數字也不會全部相同。動態分配的端口號取值范圍在49152到65535之間。
端口號與協議的關系
端口號由其使用的傳輸層協議決定。因此,不同的傳輸協議可以使用相同的端口號。例如,TCP與UDP使用同一個端口號,但使用目的各不相同。這是因為端口號上的處理是根據每個傳輸協議的不同而進行的。
數據到達IP層后,會先檢查IP首部中的協議號,再傳給相應協議的模塊。如果是TCP則傳給TCP模塊、如果是UDP則傳給UDP模塊去做端口號的處理。即使是同一個端口號,由于傳輸協議是各自獨立地進行處理,因此相互之間不會受到影響。
1.1 工具
netstat
(Network Statistics)是一個用于檢查和顯示網絡連接、路由表、網絡接口統計信息等的命令行工具。它在各種操作系統中都有版本,包括UNIX/Linux、Windows等。netstat
提供了有關系統網絡活動的實時或靜態信息,使管理員和用戶能夠監視和診斷網絡連接問題。
netstat
命令的基本用法是在命令行中輸入 netstat
,后面可以跟隨一些選項和參數來獲取不同類型的網絡信息。以下是一些常見的用法和選項:
netstat -a
:顯示所有活動的網絡連接和監聽端口。netstat -t
:顯示TCP協議相關的網絡連接信息。netstat -u
:顯示UDP協議相關的網絡連接信息。netstat -n
:以數字形式顯示網絡地址和端口號,而不解析為域名和服務名。netstat -r
:顯示路由表信息。netstat -i
:顯示網絡接口統計信息。netstat -p
:顯示與每個連接關聯的進程信息(需要管理員權限)。
在UNIX/Linux系統中,netstat
命令可能會被一些新的工具和命令替代,如 ss
(Socket Statistics)和 ip
命令。這些工具提供更強大和詳細的網絡信息,并且通常比傳統的 netstat
更快和更準確。
pidof
是一個用于查找正在運行的進程的命令行工具,通常用于返回與指定進程名相關聯的一個或多個進程的PID(進程標識符)。這個命令在許多UNIX/Linux系統中都可用,可以通過命令行終端或腳本來使用。
基本語法:
pidof [選項] 進程名
常見選項:
-s
:以單個PID的形式輸出結果。如果有多個進程匹配進程名,只返回其中一個PID。-o
:只返回最老的進程PID。-x
:返回與指定進程名完全匹配的PID。
示例:
pidof sshd
:返回與進程名 “sshd” 相關聯的一個或多個PID。pidof -s sshd
:返回一個與 “sshd” 相關的PID,如果有多個匹配,只返回其中一個。pidof -o -s sshd
:返回最舊的一個與 “sshd” 相關的PID。
pidof
可以幫助你快速找到正在運行的特定進程的PID,方便進行進程管理和操作。請注意,有時候進程名可能是帶有路徑的可執行文件名,所以在使用 pidof
時要確保輸入的進程名正確匹配目標進程。
2、UDP協議
2.1 協議端格式
UDP(User Datagram Protocol)是一種無連接的、無狀態的傳輸層協議,通常用于在計算機網絡上以盡量少的開銷進行數據傳輸。UDP協議段(也稱為UDP數據報)的格式如下:
- 源端口號(16位):指示發送方的應用程序使用的端口號。
- 目標端口號(16位):指示接收方的應用程序期望接收的數據的端口號。
- 長度(16位):表示UDP數據報的總長度,包括報頭和數據。
- 校驗和(16位):提供簡單的錯誤檢測,用于驗證數據報是否在傳輸過程中出現了錯誤。
以下是UDP協議段的簡要格式:

需要注意的是,UDP協議不提供像TCP一樣的可靠性和流量控制,因為它不支持連接的建立、維護和斷開。UDP只是簡單地將數據從發送方傳輸到接收方,并且不會對數據包的順序或丟失進行處理。這使得UDP非常適合那些對實時性要求高、可以容忍丟失少量數據的應用,例如音頻和視頻傳輸、在線游戲等。
2.2 UDP特點
-
無連接性 (Connectionless): UDP協議是無連接的,這意味著發送方不需要事先與接收方建立連接。就像你寄信一樣,只要知道收信人的地址,你就可以直接把信寄出去,而不需要預先通知收信人。
-
不可靠性 (Unreliable): UDP不提供數據包的確認機制和重傳機制。一旦發送數據,UDP就不會等待接收方的確認信號,也不會重新發送數據包,無論數據包是否成功到達目的地。這就類似于寄信時,寄出后你不會收到寄信局的確認,也不會知道是否郵件丟失。
-
面向數據報 (Datagram-Oriented): UDP以數據報的形式傳輸數據,每個數據報是獨立的、完整的數據單元。這意味著發送方將數據分割成數據報,然后將它們發送到目的地。接收方則根據數據報的邊界解析數據。這就類似于你將信件分成小片,寄出后這些小片可能以不同的順序到達,接收方需要按照標記重新組裝信件。
雖然UDP不提供像TCP那樣的可靠性和流量控制,但正是因為這些特點,UDP在某些場景下非常有用。它適用于那些對實時性要求高、可以容忍一些數據丟失的應用,例如在線游戲、音頻和視頻傳輸,以及一些網絡探測工具等。但在需要確保數據完整性和可靠傳輸的情況下,TCP更適合,因為它提供了連接的建立、數據包確認和重傳等機制。
2.3 傳輸數據報
在UDP協議中,應用層將報文交給UDP的時候,UDP會將報文原樣地發送,不會對報文進行拆分或合并。這意味著如果應用層發送100個字節的數據,UDP將會以這100個字節的數據報文進行發送。
接收端需要調用與發送端發送數據時對應次數的recvfrom
來接收數據。如果發送端一次性發送了100個字節,接收端也必須調用一次recvfrom
來接收這100個字節,而不能循環調用多次recvfrom
來嘗試接收數據。UDP沒有數據流的概念,每次接收都是基于數據報的,因此接收端需要在每次接收時保證正確地處理整個數據報。
這是因為UDP的無連接特性。在無連接協議中,每個數據報都是獨立的,沒有前后關系,所以接收端需要根據數據報的邊界來解析和處理數據。如果需要將應用層的數據劃分成更小的塊并進行循環接收,你可能需要在應用層自行處理這個分塊邏輯,然后分別發送多個UDP數據報。
2.4 緩沖區
-
發送緩沖區和接收緩沖區:UDP確實沒有像TCP那樣的真正的發送緩沖區,而是將數據直接交給內核,然后內核會將數據傳遞給網絡層協議進行后續的傳輸動作。另一方面,UDP具有接收緩沖區,用于存儲接收到的數據報。但是,與TCP不同,UDP的接收緩沖區不會根據數據報的順序自動排序,因此在處理接收數據時,應用層需要自行處理數據報的順序問題。
-
報文順序和丟失:UDP不保證數據報的順序和發送順序一致。這就意味著如果應用層發送了多個UDP數據報,它們在傳輸過程中可能會以不同的順序到達接收端。此外,UDP也沒有任何機制來確保數據的完整性,因此在網絡擁塞或丟包的情況下,UDP數據報可能會丟失。
-
全雙工通信:全雙工是一個重要概念。UDP套接字是全雙工的,這意味著它可以在同一時間進行讀取和寫入操作。這使得應用程序能夠同時發送和接收數據,而不需要切換上下文。全雙工通信對于需要實時性和快速數據交換的應用非常有用,例如實時游戲和視頻通話等。
2.5 基于UDP應用層協議
-
NFS(Network File System):NFS是一種用于在網絡上共享文件系統的協議。它允許計算機通過網絡訪問遠程主機上的文件和目錄,就像是本地文件系統一樣。NFS常用于UNIX和Linux系統之間共享文件和數據。
-
TFTP(Trivial File Transfer Protocol):TFTP是一種簡單的文件傳輸協議,用于在計算機之間傳輸文件。與FTP(文件傳輸協議)相比,TFTP更簡單,功能較少,適用于一些場景,如無盤設備的啟動過程中的固件傳輸。
-
DHCP(Dynamic Host Configuration Protocol):DHCP是一種用于自動分配IP地址和其他網絡配置信息的協議。當計算機加入網絡或者重新連接到網絡時,DHCP允許它自動獲取IP地址、子網掩碼、默認網關、DNS服務器等信息,從而簡化了網絡配置過程。
-
BOOTP(Bootstrap Protocol):BOOTP是一個用于無盤設備啟動的協議。它類似于DHCP,但更早出現,用于為無盤設備(如磁盤less的工作站或終端)分配IP地址等配置信息。
-
DNS(Domain Name System):DNS是一個用于將人類可讀的域名(如www.example.com)映射到IP地址的系統。它使得在瀏覽器中輸入域名時,能夠找到正確的服務器IP地址,從而實現了互聯網上的域名解析。
這些協議在計算機網絡中發揮著重要的作用,使得網絡通信和配置更加方便和高效。
2.6 使用注意事項
UDP協議頭中的長度字段是16位,這意味著一個UDP數據報(包括UDP頭部)的最大長度是64K(65535字節)。然而,盡管在某些情況下這可能會被認為是一個相對較小的限制,但UDP的設計初衷并不是用于大量數據的傳輸,而是注重低延遲和實時性。
當需要傳輸超過64K的數據時,需要在應用層手動進行分包。這通常涉及將大的數據分割成較小的塊,然后逐個發送。接收端需要根據應用層的邏輯來接收和拼裝這些分開的數據塊,以重新構建完整的數據。
盡管UDP在處理大量數據時需要應用層更多的控制和處理,但在某些情況下它仍然有優勢,比如在實時性和速度方面。如果數據完整性和可靠性對于應用非常重要,而且數據量較大,那么考慮使用TCP可能會更合適,因為TCP提供了連接的建立、流量控制、數據確認和重傳等機制。
選擇UDP還是TCP取決于應用需求,例如是否需要實時性、是否容忍數據丟失以及數據的大小等。
3、TCP協議
3.1 協議段格式

TCP(Transmission Control Protocol)是一種在計算機網絡中常用的傳輸層協議,它負責在通信的兩個端點之間提供可靠的、面向連接的數據傳輸。TCP報文段的格式由多個字段組成,每個字段都有特定的作用。以下是TCP報文段的各個組成部分及其作用:
- 源端口號(Source Port):16位字段,用于標識發送方的端口號。
- 目標端口號(Destination Port):16位字段,用于標識接收方的端口號。
這兩個字段一起確定了數據通信的源和目標應用程序。
-
序號(Sequence Number):32位字段,用于標識發送方發送的數據字節在整個數據流中的序列位置。用于實現數據的有序傳輸。
-
確認號(Acknowledgment Number):32位字段,僅在ACK標志位被設置時有效。表示接收方期望接收的下一個字節的序列號,用于實現可靠的數據傳輸。
-
數據偏移(Data Offset):4位字段,指示TCP頭部的長度,以32位字為單位。由于TCP頭部的長度是可變的,這個字段確定了數據部分的起始位置。
-
保留(Reserved):6位字段,保留未來使用,目前置為0。
-
控制位(Flags):TCP頭部包含多個標志位,用于控制TCP連接的不同方面,例如:
- URG(Urgent):表示緊急指針字段是否有效。
- ACK(Acknowledgment):表示確認號字段是否有效。
- PSH(Push):表示接收方應盡快將數據交給應用層。
- RST(Reset):用于重置連接。
- SYN(Synchronize):用于建立連接。
- FIN(Finish):用于關閉連接。
-
窗口大小(Window Size):16位字段,表示接收方的可用緩沖區大小,用于流量控制,以確保發送方不會發送過多的數據導致接收方緩沖區溢出。
-
校驗和(Checksum):16位字段,用于檢測TCP頭部和數據部分的錯誤。通過校驗和,接收方可以驗證數據在傳輸過程中是否發生了損壞。
-
緊急指針(Urgent Pointer):16位字段,僅在URG標志位被設置時有效。指示緊急數據的末尾位置,用于實現緊急數據傳輸。
-
選項(Options):可變長度的字段,包含一些可選的參數,如最大段大小(MSS)、時間戳、窗口縮放因子等。
-
數據(Padding):用于保證TCP頭部的長度為32位字的整數倍,以對齊數據。
這些組成部分共同構成了TCP報文段,通過它們,TCP協議實現了可靠的、面向連接的數據傳輸。
3.2 ACK機制
確認應答(ACK,Acknowledgment)機制是TCP協議中的一個重要特性,用于實現可靠的數據傳輸。在TCP連接中,接收方通過發送ACK報文段來確認已經正確接收到發送方發送的數據。以下是確認應答機制的工作原理:
-
發送方發送數據:發送方將數據劃分為一個個的數據段,每個數據段都會被分配一個序列號。發送方將這些數據段按順序發送給接收方。
-
接收方接收數據:接收方接收到數據后,會將數據緩存起來,然后發送一個ACK報文段給發送方。ACK報文段中的確認號字段表示接收方期望接收的下一個數據段的序列號。
-
發送方等待確認:發送方在發送數據段后,會等待接收到對應的ACK報文段。如果一段時間內未收到ACK,發送方會認為數據可能已經丟失或損壞,因此會觸發超時重傳機制,重新發送相應的數據段。
-
接收方去重:接收方可能會收到重復的數據段,或者亂序的數據段。接收方會根據序列號來判斷是否是重復數據,并根據序列號將亂序的數據重新排序。然后,接收方只會向上層應用傳遞正確順序的數據,避免重復處理。
-
確認號的使用:ACK報文段中的確認號表示接收方期望接收的下一個數據段的序列號。這使得發送方可以知道哪些數據已經被正確接收,從而可以繼續發送下一批數據。
-
確認號的累積確認:接收方可以一次性確認多個數據段,只需在ACK報文段中設置確認號為期望接收的下一個數據段的序列號。這樣,發送方知道在這個序列號之前的所有數據都已經成功接收。
通過確認應答機制,TCP協議可以保證數據的可靠傳輸。發送方可以根據接收到的ACK報文段來調整數據發送的速率,而接收方可以確保只有正確的數據被傳遞給應用程序。這種機制使得TCP在不可靠的網絡環境中能夠實現高效的數據傳輸。


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

每一個ACK都帶有對應的確認序列號, 意思是告訴發送者, 我已經收到了哪些數據; 下一次你從哪里開始發
3.3 超時重傳機制
超時重傳的超時是指在重發數據之前,等待確認應答到來的那個特定時間間隔。如果超過了這個時間仍然為收到確認應答,發送端將會重發數據。那么這個數據是如何確定的呢?
最理想就是找到一個最小時間,它能保證確認應答一定能在這個時間內返回。但是這個時間長短隨著數據包途徑的網絡環境的不同會有所變化。
TCP要求不論處在何種網絡環境下都要提供高性能通信,而且無論網絡擁堵的情況發生如何改變,都必須保持這一特性。為此,它在每次發包時都會計算往返時間及其偏差,將這個往返時間和偏差相加重發超時的時間,就是比這個綜合要稍微大一點的值。

數據被重發以后若還是收不到應答,就會進行再次發送,此時,等待確認應答的時間將會以2倍,4倍的指數函數延長
不過,數據也不會無限,反復的重發。當達到一定的重發次數之后,如果仍然沒有任何確認應答返回,就會判斷為網絡或對端主機發生異常,強制關閉連接。
3.4 連接管理機制
TCP的三次握手以及TCP的四次揮手!
三次握手: 建立一個TCP連接時,需要客戶端和服務端總共發送3個包以確認連接的建立, 在Socket編程中,這一過程由客戶端執行connect來觸發,具體流程圖如下:
- 第一次握手:Client將標志位SYN置為1,隨機產生一個值seq=J,并將該數據包發送給Server, Client進入SYN_SENT狀態,等待Server確認。
- 第二次握手:Server收到數據包后由標志位SYN=1知道Client請求建立連接,Server將標志位 SYN和ACK都置為1,ack=J+1,隨機產生一個值seq=K,并將該數據包發送給Client以確認連接請求 ,Server進入SYN_RCVD狀態。
- 第三次握手:Client收到確認后,檢查ack是否為J+1,ACK是否為1,如果正確則將標志位ACK 置為1,ack=K+1,并將該數據包發送給Server,Server檢查ack是否為K+1,ACK是否為1,如果正確則 連接建立成功,Client和Server進入ESTABLISHED狀態,完成三次握手,隨后Client與Server之間可以 開始傳輸數據了。
四次揮手: 終止TCP連接,就是指斷開一個TCP連接時,需要客戶端和服務端總共發送4個包以確認連接的斷開。 在Socket編程中,這一過程由客戶端或服務端任一方執行close來觸發,具體流程圖如下:
- 第一次揮手:Client發送一個FIN,用來關閉Client到Server的數據傳送,Client進入 FIN_WAIT_1狀態
- 第二次揮手:Server收到FIN后,發送一個ACK給Client,確認序號為收到序號+1(與SYN相同, 一個FIN占用一個序號),Server進入CLOSE_WAIT狀態。
- 第三次揮手:Server發送一個FIN,用來關閉Server到Client的數據傳送,Server進入LAST_ACK 狀態。
- 第四次揮手:Client收到FIN后,Client進入TIME_WAIT狀態,接著發送一個ACK給Server,確認序號為收到序號+1,Server進入CLOSED狀態,完成四次揮手。 另外也可能是同時發起主動關閉的情況:
另外還可能有一個常見的問題就是:為什么建立連接是三次握手,而關閉連接卻是四次揮手呢? 答:因為服務端在LISTEN狀態下,收到建立連接請求的SYN報文后,把ACK和SYN放在一個報文里 發送給客戶端。而關閉連接時,當收到對方的FIN報文時,僅僅表示對方不再發送數據了但是還 能接收數據,己方也未必全部數據都發送給對方了,所以己方可以立即close,也可以發送一些 數據給對方后,再發送FIN報文給對方來表示同意現在關閉連接,因此,己方ACK和FIN一般都會 分開發送。
TCP狀態轉移圖:

3.5 滑動窗口
每一個發送的數據段, 都要給一個ACK確認應答. 收到ACK后再發送下一個數據段. 這樣做有一個比較大的缺點, 性能較差. 尤其是數據往返的時間較長的時候
既然這樣一發一收的方式性能較低, 那么我們一次發送多條數據, 就可以大大的提高性能(其實是將多個段的等待時間重疊在一起了)
TCP移動窗口(Sliding Window)是一種流量控制機制,用于在TCP連接中管理發送方和接收方之間的數據流。它允許發送方在不等待每個數據段的確認情況下連續發送多個數據段,從而提高數據傳輸的效率。
移動窗口的核心思想是,發送方可以發送一定數量的數據段(也稱為窗口大小)而無需等待確認,只要這個窗口內的數據都在接收方正常接收。接收方會通過ACK報文段來確認接收到的數據,并更新窗口的大小。這樣,發送方可以根據窗口的大小來控制發送數據的速率,避免過快地發送數據導致接收方緩沖區溢出。
TCP移動窗口的一些關鍵概念和機制:
-
窗口大小(Window Size):窗口大小是一個動態調整的值,表示接收方緩沖區中還可以容納多少字節的數據。發送方根據窗口大小來決定可以連續發送多少個數據段。
-
發送窗口:發送方的窗口大小,表示可以發送但尚未收到確認的數據的最大大小。發送方只能在發送窗口內發送數據,一旦發送窗口內的數據被確認,窗口將向前滑動。
-
接收窗口:接收方的窗口大小,表示可以緩存但尚未被確認的數據的最大大小。接收方根據已經接收到的數據和緩沖區的剩余空間來調整接收窗口大小。
-
窗口滑動:當發送方收到一定數量的ACK報文段時,表示接收方已經成功接收了一部分數據,此時發送方會將窗口向前滑動,允許發送更多的數據。
-
快速重傳:如果發送方連續發送的數據段沒有被正確接收(接收方未收到或丟失),接收方會重復發送ACK報文段來請求缺失的數據,從而實現快速重傳。
-
窗口調整:接收方可以通過調整窗口大小來告知發送方自己的緩沖區狀態。如果接收方的緩沖區較大,窗口大小可以增加,允許發送方發送更多數據。如果接收方的緩沖區較小,窗口大小會減小,限制發送方的數據流量。
通過移動窗口機制,TCP協議可以實現流量控制,使得發送方和接收方之間的數據傳輸可以根據網絡狀況和接收方的處理能力進行動態調整,從而實現更高效的數據傳輸和更好的網絡性能。
3.6 流量控制
流量控制(Flow Control)是TCP協議中的一項關鍵功能,它確保發送端不會過快地發送數據,從而避免接收端的緩沖區溢出、丟包、數據重傳以及其他不必要的問題。
TCP的流量控制主要通過使用移動窗口機制來實現。接收端會通過發送窗口大小來告知發送端自己的可用緩沖區空間。發送端根據接收端的窗口大小來調整自己的發送速率,確保不會發送超過接收端緩沖區能力的數據量。
流量控制的工作過程如下:
-
初始階段:在連接建立時,發送端和接收端會協商初始的窗口大小。這個窗口大小可以根據接收端的緩沖區大小和其他因素來確定。
-
動態調整:隨著數據的傳輸,接收端會根據自己的緩沖區狀態動態調整窗口大小。如果接收端的緩沖區越來越滿,它會減小窗口大小,通知發送端降低發送速率。
-
發送窗口滑動:一旦接收端確認了已經接收到的數據,它會更新窗口大小,并通過ACK報文段通知發送端。發送端收到ACK后,可以將窗口滑動,允許發送更多的數據。
-
限制發送速率:發送端根據接收端的窗口大小來限制自己的發送速率,確保不會超出接收端的處理能力。
通過流量控制,TCP協議可以在發送和接收之間維持一種動態平衡,以確保數據的穩定傳輸。這有助于避免網絡擁塞、數據丟失以及不必要的重傳,從而提供了可靠且高效的數據傳輸機制。
3.7 擁塞控制
擁塞控制(Congestion Control)是TCP協議中的另一個重要特性,用于在網絡中避免過多的數據流量引起的擁塞現象。擁塞控制機制旨在確保網絡資源被合理利用,避免數據丟失、延遲增加以及網絡性能下降等問題。
擁塞控制的關鍵目標是在發送端和接收端之間保持一個均衡的數據流,使得網絡能夠穩定運行,不超過其負荷能力,同時也能最大化地利用網絡資源。以下是擁塞控制的一些核心概念和機制:
-
擁塞的原因:擁塞可能發生在網絡中的某些路由器、鏈路或節點負載過重,導致數據包堆積、延遲增加和數據丟失。
-
擁塞檢測:擁塞控制需要檢測網絡是否處于擁塞狀態。發送方和接收方可以通過觀察數據包的延遲、丟失情況以及ACK報文段的反饋來判斷是否發生了擁塞。
-
擁塞信號:當發送方和接收方都觀察到網絡擁塞的跡象時,會通過特定的擁塞信號來觸發擁塞控制機制。例如,發送方可能會減少發送速率。
-
慢啟動(Slow Start):擁塞控制的一個階段,用于在連接初始階段逐漸增加發送速率。發送方從較小的窗口大小開始,然后每次接收到一個ACK報文段,窗口大小會指數級增加,從而逐漸加快發送速率。
-
擁塞避免:在慢啟動階段之后,發送方會進入擁塞避免階段。在這個階段,窗口大小的增長會變得線性,以避免突然增加的數據流量導致擁塞。
-
快重傳和快恢復:如果接收方連續收到相同的序列號的ACK報文段,表明網絡中的某個數據段可能丟失,發送方會快速重傳該數據段,而不是等待超時。快重傳通常與快恢復機制一起使用,以便在恢復后適當增加發送速率。
-
超時重傳:如果發送方在超時時間內沒有收到ACK報文段,會假定數據丟失,并重傳相應的數據段。
擁塞窗口
在TCP的擁塞控制機制中,擁塞窗口數量是一個重要的概念,通常稱為"CWND"(Congestion Window)。擁塞窗口數量表示在一個擁塞控制周期內可以發送的數據段的最大數量。擁塞窗口的大小會根據網絡的擁塞狀態進行動態調整,以避免引起網絡擁塞。
以下是擁塞窗口數量在不同階段的變化情況:
-
慢啟動階段(Slow Start):
- 初始階段,擁塞窗口大小為1個數據段(通常稱為MSS,最大段大小)。
- 在每次收到一個確認的ACK報文段后,擁塞窗口大小會翻倍,即指數級增加。
- 該過程會持續,直到擁塞窗口達到慢啟動門限(ssthresh)。
-
擁塞避免階段(Congestion Avoidance):
- 一旦擁塞窗口大小達到慢啟動門限(ssthresh),就會進入擁塞避免階段。
- 在擁塞避免階段,擁塞窗口大小會逐漸線性增加,而不是指數級增加。
- 擁塞窗口的增長速率較慢,以防止過快增加數據流量引起擁塞。
-
快重傳和快恢復機制:
- 如果網絡中出現數據丟失,發送方可能會收到連續的重復ACK報文段,表示接收方已經接收到某個數據段之前的所有數據。
- 在這種情況下,發送方會認為某個數據段可能已經丟失,并執行快重傳和快恢復機制。
- 擁塞窗口會減半,并設置慢啟動門限為當前擁塞窗口大小的一半。
-
動態調整:
- 擁塞窗口的大小會根據接收到的ACK報文段、網絡的延遲情況和數據丟失情況動態調整。
- 當網絡出現擁塞時,擁塞窗口會減小,以降低發送速率,避免加劇擁塞。
擁塞窗口的動態變化是擁塞控制機制的核心,它可以根據網絡的狀態來自適應地調整數據的發送速率,以實現穩定的數據傳輸和避免過度擁塞。
3.8 延遲應答
“延遲應答”(Delayed Acknowledgment)是指在某些情況下,TCP接收方在接收到數據后,不會立即發送確認(ACK)報文段,而是會延遲一段時間才發送確認。這個延遲可以在一定程度上優化網絡性能和減少網絡負載。
延遲應答的原因和優勢包括以下幾點:
-
減少ACK報文段數量:如果每接收到一個數據段就立即發送一個ACK報文段,會導致網絡中的ACK報文段增多,從而可能造成網絡擁塞。通過延遲應答,可以將多個確認合并在一個ACK報文段中,減少了網絡上的控制信息。
-
提高帶寬利用率:將多個確認合并在一個ACK報文段中可以有效地減少控制信息的開銷,從而提高了實際可用帶寬的利用率,讓更多的帶寬用于傳輸數據。
-
防止不必要的ACK洪水:如果發送端連續發送大量的數據段,接收端可能會為每個數據段都發送一個ACK報文段。這可能會導致接收端發送過多的ACK報文段,浪費網絡資源。通過延遲應答,可以避免不必要的ACK洪水。
-
適應延遲較大的網絡:在一些高延遲的網絡環境中,立即發送ACK可能會導致額外的延遲。通過延遲應答,可以減少ACK報文段的數量,降低了在高延遲網絡中的延遲增加。
然而,延遲應答也可能帶來一些潛在的問題:
-
數據段丟失的確認延遲:如果數據段丟失,發送方可能需要等待更長的時間才能收到確認,從而觸發超時重傳機制,影響數據傳輸的速度和可靠性。
-
流控制的影響:延遲應答可能會影響發送方的流控制機制,使得發送方不能及時了解接收方的可用緩沖區大小。
盡管有一些潛在的問題,TCP延遲應答的優勢通常在大部分情況下是明顯的。不同的TCP實現可能在延遲應答方面有不同的策略和算法,以在各種網絡條件下實現最佳的性能和可靠性平衡。
3.9 捎帶應答
“捎帶應答”(Piggyback Acknowledgment)是一種優化的TCP確認機制,它允許在發送數據的同時,在數據段中捎帶確認信息,從而減少確認報文段的數量,提高網絡利用率和性能。
通常情況下,TCP接收方收到數據后會發送確認報文段(ACK),以告知發送方已經成功接收數據。而在捎帶應答機制下,接收方會嘗試將ACK信息捎帶到它自己發送的數據段中,從而在一個數據段中同時包含數據和確認。
這種機制的優勢在于:
-
減少ACK報文段數量:通過將ACK與數據段捎帶在一起,可以減少網絡上的確認報文段數量,從而提高了網絡的利用率。
-
優化網絡性能:較少的確認報文段可以減少網絡的控制信息開銷,使得更多的帶寬可以用于實際數據傳輸,從而優化了網絡性能。
-
避免ACK洪水:在高速傳輸環境中,頻繁發送ACK報文段可能會導致ACK洪水現象,從而影響網絡效率。捎帶應答可以一定程度上避免這個問題。
需要注意的是,捎帶應答并非在所有情況下都適用。它在以下情況下可能會受到一些限制:
-
延遲敏感的應用:捎帶應答可能會引入額外的延遲,因為接收方需要等待合適的時機將ACK捎帶在數據段中。
-
小數據段的情況:如果發送的數據段很小,放入ACK可能會使數據段過小,從而增加了網絡開銷。
-
亂序的數據段:如果數據段在傳輸過程中發生亂序,可能會導致ACK無法準確與特定數據段捎帶,從而引入一些問題。
捎帶應答是一個在性能和延遲之間權衡的機制,它可以在適當的情況下提供一種有效的方式來減少網絡控制信息的開銷。
3.10 粘包問題
粘包問題(Packet Pasting Problem)是在數據通信中常見的一個現象,它指的是在發送數據時,多個數據包(通常是短小的數據包)可能會被合并成一個大的數據包發送,或者一個大的數據包可能會被分割成多個小的數據包發送,從而導致數據在接收端的處理出現混亂或錯誤。
粘包問題發生的主要原因是因為底層網絡協議的不可靠性和數據傳輸的異步性,導致數據在傳輸過程中的大小和邊界信息可能會丟失或混亂。以下是粘包問題發生的一些典型情況:
-
TCP協議的緩沖區機制:TCP協議為了提高傳輸效率,會將多個小的數據包合并成一個大的數據包進行傳輸。這可能導致接收端一次性收到多個數據包,從而引發粘包問題。
-
UDP協議的不可靠性:UDP協議不提供可靠的數據傳輸,數據包可能在傳輸過程中被丟失、重復或亂序。這可能導致接收端無法準確地判斷數據包的邊界。
-
網絡擁塞或延遲:網絡擁塞或延遲可能導致數據包的傳輸時間不確定,從而導致數據包在接收端的處理出現混亂。
解決粘包問題的方法包括:
-
消息邊界標志(Message Delimiters):在數據包中添加特定的邊界標志,例如換行符、特定字符序列等,用于標識數據包的邊界。接收端可以根據邊界標志來正確分割數據包。
-
固定長度消息(Fixed-Length Messages):將要發送的數據包固定為特定的長度,不足部分用填充字符補齊。接收端可以按照固定長度來正確解析數據包。
-
消息長度前綴(Length Prefix):在每個數據包的前面添加表示數據包長度的前綴。接收端首先讀取前綴,然后根據長度讀取相應的數據。
-
使用應用層協議:在應用層設計自定義的消息協議,包括數據包的結構、邊界標志和長度等信息,使得發送端和接收端可以根據協議正確解析數據。
-
使用流量控制和擁塞控制:TCP協議的流量控制和擁塞控制機制可以一定程度上減輕粘包問題,確保數據逐個傳輸。
不同情況下適用不同的解決方案,根據具體的應用場景和數據通信需求,選擇合適的方法來解決粘包問題。
3.11 TCP異常
情況和處理 TCP 異常:
-
進程終止、機器重啟: 當進程終止或機器重啟時,TCP 連接會被關閉。正常的關閉過程涉及發送 FIN 報文段,而關閉的一方會發送 ACK 報文段作為確認。這樣,另一端收到 ACK 后也會發送自己的 FIN 報文段來完成連接關閉。
-
機器掉電/網線斷開: 如果連接的一方在接收到數據后突然掉電或者網絡斷開,TCP 的另一端可能會一直等待確認,因為沒有收到確認報文段。為了處理這種情況,TCP 實現了一個保活定時器,發送探測報文段以確認連接的存活性。如果在一定時間內沒有收到回復,連接就會被認為是異常的,并被關閉。此外,如果連接一方確實發送了數據,但另一方沒有回應,也會根據超時情況來判斷連接是否還存在。
-
應用層協議檢測: 像 HTTP 長連接、QQ 等應用也會在底層 TCP 的基礎上實現自己的連接狀態檢測機制,以確保連接的正常運行。這樣的檢測可以是定期發送特定的探測數據,如果沒有得到預期的回應,就會判斷連接狀態異常并采取相應的處理措施。
總之,TCP 協議在面對各種異常情況時,采取了多種機制來盡量保證連接的可靠性和正常關閉。應用層也可以根據自身需求實現額外的檢測和處理機制來保障連接的穩定性。
4、TCP/UDP對比
- 基于連接與無連接;
- 對系統資源的要求(TCP較多,UDP少);
- UDP程序結構較簡單;
- 流模式與數據報模式 ;
- TCP保證數據正確性,UDP可能丟包,TCP保證數據順序,UDP不保證。