可靠資料傳輸(Reliable Data Transfer 簡稱rdt)
資料可靠度是網路傳輸中非常大的問題之一。在TCP抽象服務的模型中(也算是理想狀態),每個應用程式的訊息都透過網路上可靠的通道來傳輸,然而現實中的困難是 可靠傳輸協定的下層是不可靠。也就是說,現實中存在著許多狀況,例如資料位元錯誤、封包遺失等等 造成資料的不可靠,必須建立有效傳輸協定。
1、rdt1.0
rdt的模型主要是用FSM(Finite State Machine-有限狀態機器)來定義狀態與操作方式。
rdt1.0是假設使用最可靠的通道情況。主要有傳輸端與接收端兩個部分,資料傳輸方式很單純,傳輸端等待上層傳資料進來,收到上面的資料以後裝成封包送出去。
接收端收到封包以後,將封包解開,把訊息往上送。
2、rdt2.0
2.0考慮到了資料錯誤的情形,當接收端收到資料,會有ACK(相當於OK)與NAK(相當於Send Again)兩種訊息,當資料接收到以後確認無誤,會送ACK給來源已確定資料無誤。當偵測到錯誤時 會傳回NAK通知來源端再送一次。
3、rdt2.1
2.1新增了sequence number,同樣使用ACK與NAK來確認訊息,封包的號碼可以用來確認是否重新傳輸封包。
例如接收端在等待編號0的封包,結果收到封包1,此時會回傳ACK1給來源端,而正在等候ACK0的來源端收到ACK1 表示封包0可能遺失,所以會再重送封包0。
4、rdt2.2
一次使用兩種確認訊息 處理起來比較費力,因此2.2中移除NAK的訊息,在ACK中加入編號 就可以達到確認與否認的效果。
5、rdt3.0
3.0同時考慮到封包遺失與資料錯誤的情形,除了使用ACK機制,另外在傳送端多了倒數計時器,封包送出去如果超過時間仍未收到ACK或是收到不正確編號的ACK,則再送出封包一次。
6.
Stop-and-Wait 與 Pipelined Protocol
rdt3.0雖然確保了資料的可靠性,可是它採用Stop-and-Wait機制,效能方面無法讓人接受,因為送出封包後必須等待對方回應才能繼續傳送,假如連線Delay太長,整體效率會嚴重低落。
為解決這問題,後來發展出 Pipelined Protocol,可以讓傳送端同時傳送多個封包不需等待確認相對的,傳輸端與接收端都必須增加封包的暫存空間與序號碼。當其中的封包出現錯誤時有不同的回覆方法,主要有Go-Back-N(GBN)與Selective Repeat(SR)兩種方法。
Go-Back-N(GBN)
傳輸多個封包 必須有個暫存的地區,暫存的地區中存在著窗格大小(Window Size) N,存放著各種封包(已確認、已送出但未收到ACK、未送出的封包等等)。
接收端也會開啟窗格來接收封包,會記著目前收到封包的編號,假設收到順序不對的封包N+1(等待接收第N個,下一個傳來的卻是第N+1號),會將N以後的封包全部丟棄,此時傳送端一直沒收到ACK(N),會把N號以後的封包全部重新傳送出去。
Selective Repeat(SR)
GBN的傳送方法往往會造成不必要的重複,因此SR的傳送方法就是只針對未收到的封包做重新傳輸的動作。首先規划出大小為N的窗格來限制大小,窗格的基底會停留在最近一個尚未收到ACK的封包地區,當封包時間逾時會重新送出封包,直到收到該封包的ACK 窗格基底才會往前移動。
7.
Flow Control(流量控制)
雖然TCP接收端有緩衝區,但有時候應用程式讀取訊息的速度小於傳輸端傳送訊息的速度,假如緩衝區滿了還繼續傳資料過來,會造成緩衝區溢位的情況,為避免此狀況,設了一個"receive window(接收窗格簡寫成rcvWindow)"變數,用來記錄緩衝區剩餘的空間有多少。
當接收端收到訊息後,會回傳給傳送端rcvWindow的數值,如果rcvWindow=0,傳送端會停止傳輸資料但這個方法會造成問題,假設停止後 接收端一直沒訊息通知傳送端,此時傳送端不會運作,而接收緩衝區也是空的,資料傳輸停止。
因此當接收端rcvWindow=0時,傳送端會持續傳送一個1byte的區段給接收端 以確認緩衝區可否繼續接收資料。