3.1 概述和運輸層服務
運輸層協議為運行在不同主機上的應用進程之間提供了邏輯通信(logic communication)功能。
3.1.1 運輸層和網絡層的關系
網絡層提供了主機之間的邏輯通信,而運輸層為運行在不同的主機上的進程提供了邏輯通信。
3.1.2 因特網運輸層概述
Internet上提供TCP(傳輸控制協議) 和 UDP(用戶數據報協議)兩種
3.2 多路復用和多路分解
一個進程有一個或多個套接字(socket),它相當於從網絡向進程傳遞數據和從進程向網絡傳遞數據的門戶。
- 接收端將運輸層報文段中的數據交付到正確的套接字(即不同的進程)的工作稱為多路分解(demultiplexing)。
- 而在源主機中從不同套接字中收集數據塊,並為每個數據塊封裝上頭部信息從而生成報文段,然后將報文段傳遞到網絡層,所有這些工作稱為多路復用(multiplexing)。
1.無連接的多路復用與多路分解
在運輸層,無連接的網絡傳輸是通過UDP來實現的,一個UDP套接字是由一個含有目的IP地址和目的端口號的一個二元組來全面標識的。
主機收到UDP段后檢查段中的目的端口號,並將UDP段導向綁定在該端口號的Socket,因此如果兩個UDP報文段有不同的源IP地址/端口號,卻有相同的目的端口號,那么兩個報文段將通過相同的目的套接字被定向到相同的目的進程。
2.面向連接的多路復用與多路分解
在運輸層中面向連接的網絡傳輸多使用TCP,而TCP套接字和UDP套接字之間有一個細微的差別,TCP套接字是由一個四元組(源IP地址、源端口號,目的IP地址,目的端口號)來標識的。當一個TCP報文段從網絡到達一台主機時,主機會使用全部4個值來將報文段定向,即多路分解到相應的套接字。
3.3 無連接運輸 : UDP
UDP的優勢
- 應用層能更好發控制要發送的數據和發送時間。
- 無須建立連接。
- 無連接狀態。
- 分組首部開銷小。
3.3.1 UDP報文段結構
UDP報文段結構由RFC 768定義,UDP首部只有4個字段,每個字段由兩個字節組成。
- 源端口號: 本機(客戶端)的應用程序的套接字所對應的端口號,服務器端可利用此端口號向客戶端發送數據。
- 目的端口號: 服務端上的應用進程的套接字所對應的端口號,例如HTTP服務器的80端口。
- 長度:指明了首部和數據部分的UDP報文段的總長度,單位為字節,即首部+數據。
- 檢驗和: 提供了差錯檢測功能,即檢驗和用於確定當UDP報文段從源到達目的時,其中的比特是否發生了改變。
3.3.2 UDP 檢驗和
- 發送方
- 將段的內容視為16-bit整數
- 校驗和計算:計算所有整數的和,進位加在和的后面,將得到的值按位求反,得到校驗和
- 發送方將校驗和放入校驗和字段
- 接收方
- 計算所得到段的檢驗和,並將其余檢驗和字段進行比較。
- 如果不相等,則檢驗出錯誤,但若相等也可能有錯誤。
3.4 可靠數據傳輸原理
3.4.1 構造可靠數據傳輸協議
1.經完全可靠信道的可靠數據傳輸 :rdt 1.0
有限狀態機(FSM) 可以表示有限個狀態及在這些狀態之間的轉移和動作等行為的數學模型,下圖即表示發送方和接收方的有限狀態機,底層信道是完全可靠的,發送方和接收方有各自的FSM,每個FSM都只有一個狀態。
(圖解:FSM描述中的箭頭指示了協議從一個狀態變遷到另一個狀態。引起變遷的事件顯示在橫線的上方,事件發生時所采用的運動顯示在橫線的下方。FSM的初始狀態用虛線表示。)
- 因為信道可靠,接收方也不需要提供任何反饋信息給發送方
- 假定了接收方接收數據的速率能夠與發送方發送數據的速率一樣快,所以接收方也沒有必要請求發送方慢一點發送。
2.經具有比特差錯信道的可靠數據傳輸: rdt2.0
下圖為rdt 2.0 的有限狀態機描述圖,該數據傳輸協議(自動重傳請求協議)采用了差錯檢測、肯定確認與否定確認。
- 在發送端左邊的初始狀態中,發送端協議正等待來自較高層傳下來的數據。當觸發
rdt_send(data)
事件時:- 通過
sndpkt = make_pkt(data, checksum)
產生一個包含待發送數據且帶有校驗和的分組 - 然后將該分組通過
udt_send(sndpkt)
發送到信道中
- 通過
- 執行完上述的兩個動作后,發送端的狀態變遷為“等待接收接收端的 ACK 或 NAK 分組”。即轉變為右側狀態,接下來根據接收端的響應不同會有不同的變遷方案:
- 如果收到了一個 ACK 分組(
rdt_rcv(rcvpkt) && isACK(rcvpkt)
),那么發送方知道最近一個分組已經被正確接收,因此協議返回左邊狀態,繼續等待下一次由較高層傳下來的數據發送請求 - 如果收到了一個 NAK 分組(
rdt_rcv(rcvpkt) && isNAK(rcvpkt)
),那么發送端知道接收端接收到的分組是受損的,所以調用udt_send(sndpkt)
重新發送該分組,然后狀態不變,繼續等待接收接收端的 ACK 或 NAK 分組。
- 如果收到了一個 ACK 分組(
在上述協議中,當發送方處於等待ACK或NAK狀態時,它不能從上層獲得更多數據。這樣子的協議被稱為停等協議 (stop-and-wait)。
- rdt 2.0 的接收端仍然只有一個狀態。狀態變遷取決於收到的分組是否受損,有兩種方式:
- 如果收到的分組受損,即
rdt_rcv(rcvpkt) && corrupt(rcvpkt)
,則返回 NAK 分組 - 如果收到的分組完好,即
rdt_rcv(rcvpkt) && notcorrupt(rcvpkt)
,則返回 ACK 分組
- 如果收到的分組受損,即
- 處理完后仍然返回自身這個狀態,繼續等待下一次從底層接收分組並處理。
3.經具有比特差錯的丟包信道的可靠數據傳輸 rdt 3.0
在現實的網絡環境中,除了比特受損外,底層信道還會丟包;有很多可能的方法可以解決丟包問題,這里我們讓發送方負責檢測和恢復丟包工作。
假定發送端傳輸一個數據分組,該分組發生丟失 或者 接收端對該分組的 ACK 發生了丟失。在這兩種情況下,發送端都收不到應當到來的接收端的響應。所以,如果發送端願意等待足夠長的時間以確定該分組缺失已丟失,則它只需要重傳該數據分組即可。
從發送端的觀點來看,重傳是一個萬能靈葯。為了實現基於時間的重傳機制,需要一個倒數計時器 (countdown timer),在一個給定的時間量過期之后,可中斷發送方。發送方需要做到:1)每次發送一個分組(包括第一次分組和重傳分組)時,就啟動一個定時器;2)相應定時器中斷;3)終止定時器。
下圖是rdt 3.0
的發送方FSM,該協議運行在可能發生出錯和丟失的信道上。
rdt 2.2 協議中的接收端有限狀態機描述圖仍然適用於 rdt 3.0 協議,下面我仍然用文字來簡要描述一下上圖中的發送端發送分組流程:
- 首先由較高層觸發
rdt_send(data)
事件,通過sndpkt = make_pkt(0, data, checksum)
產生一個序號為 0,包含待發送數據且帶有校驗和的分組,接着通過udt_send(sndpkt)
將其發送到信道中並啟動定時器,然后狀態變遷為“等待接收接收端的 ACK 0” - 當發送端在“等待接收接收端的 ACK 0”的時候:
- 如果收到了受損的分組(即
corrupt(rcvpkt)
)或者收到了 ACK 1(即isACK(rcvpkt, 1)
,也就是收到了自己發送的上一個分組的 ACK),則直接忽略 - 如果定時器時間到,則由
udt_send(sndpkt)
重新發送該分組並重新啟動定時器 - 如果收到了完好的分組且 ACK 為 0,那么發送端知道接收端已經成功接收了剛才發送的序號為 0 的分組,直接停止定時器,此時發送端狀態變遷到等待較高層傳下來的數據發送請求
- 如果收到了受損的分組(即
- 注意在繼續等待從較高層傳下來的數據發送請求的過程中,如果收到了任何分組數據包,都直接忽略,因為它們一定是冗余的
3.4.2 流水線可靠數據傳輸協議
停等協議可能會限制底層網絡硬件所提供的能力
解決方法是:不使用停止等待方式,運行發送方發送多個分組而無需等待確認。由於許多從發送方向接收方輸送的分組可以被看成是填充到一條流水線中,因此這種技術被稱為流水線 (pipelining)。當然,流水線會增加協議的復雜度:
- 必須增加序號范圍
因為信道中的分組要有一個唯一的序號,會有多個分組在信道中未被確認。
- 協議的發送方和接收方必須緩存多個分組
發送方至少應該緩存已經發送卻還沒有被確認的分組。接受方也許應該緩存已經正確接收的分組。
- 所需的序號范圍和對緩存大小的要求取決於協議如何處理丟失、損壞及延時大的分組
解決流水線差錯錯誤的兩種基本思路:回退N步和選擇重傳。
3.4.3 回退N步
GBN 協議被稱為滑動窗口協議 (silding-window protocol)
3.4.4 選擇重傳
選擇重傳協議讓發送方僅重傳那些它懷疑在接收方出錯的分組,避免了不需要的重傳。
參考:
https://www.cnblogs.com/hithongming/p/9379397.html
https://www.cnblogs.com/oxspirt/p/6496434.html
https://www.cnblogs.com/huahuahu/p/liu-shui-xian-ke-kao-shu-ju-chuan-shu-xie-yi.html