TCP可靠傳輸的實現
TCP的可靠性表現在:它向應用層提供的數據是 無差錯的、有序的、無丟失的,簡單的說就是:TCP最終遞交給應用層的數據和發送者發送的數據是一模一樣的。
TCP采用了流量控制、擁塞控制、連續ARQ等技術來保證它的可靠性。
PS:網絡層傳輸的數據單元為『數據報』,傳輸層的數據單元為『報文段』,但為了方便起見,可以統稱為『分組』。
停止等待協議(ARQ協議)
TCP保證其可靠性采用的是更為復雜的滑動窗口協議,但停止等待協議是它的簡化版,為了方便理解,這里先介紹停止等待協議。
ARQ(Automatic Repeat reQuest)自動重傳請求。
顧名思義,當請求失敗時它會自動重傳,直到請求被正確接收為止。這種機制保證了每個分組都能被正確接收。停止等待協議是一種ARQ協議。
停止等待協議的原理
無差錯的情況
A向B每發送一個分組,都要停止發送,等待B的確認應答;A只有收到了B的確認應答后才能發送下一個分組。
超時重傳(分組丟失和出現差錯)的情況
當分組丟失 或 出現差錯 的情況下,A都會超時重傳分組
發送者擁有超時計時器。每發送一個分組便會啟動超時計時器,等待B的應答。若超時仍未收到應答,則A會重發剛才的分組。
分組出現差錯:若B收到分組,但通過檢查和字段發現分組在運輸途中出現差錯,它會直接丟棄該分組,並且不會有任何其他動作。A超時后便會重新發送該分組,直到B正確接收為止。
分組丟失:若分組在途中丟失,B並沒有收到分組,因此也不會有任何響應。當A超時后也會重傳分組,直到正確接收該分組的應答為止。
應答丟失 和 應答遲到 的情況
TCP會給每個字節都打上序號,用於判斷該分組是否已經接收。
應答丟失:若B正確收到分組,並已經返回應答,但應答在返回途中丟失了。此時A也收不到應答,從而超時重傳。緊接着B又收到了該分組。接收者根據序號來判斷當前收到的分組是否已經接收,若已接收則直接丟棄,並補上一個確認應答。
應答遲到:若由於網絡擁塞,A遲遲收不到B發送的應答,因此會超時重傳。B收到該分組后,發現已經接收,便丟棄該分組,並向A補上確認應答。A收到應答后便繼續發送下一個分組。但經過了很長時間后,那個失效的應答最終抵達了A,此時A可根據序號判斷該分組已經接收,此時只需簡單丟棄即可。
停止等待協議的注意點
每發送完一個分組,該分組必須被保留,直到收到確認應答為止。
必須給每個分組進行編號。以便按序接收,並判斷該分組是否已被接收。
必須設置超時計時器。每發送一個分組就要啟動計時器,超時就要重發分組。
計時器的超時時間要大於應答的平均返回時間,否則會出現很多不必要的重傳,降低傳輸效率。但超時時間也不能太長。
滑動窗口協議(連續ARQ協議)
連續ARQ協議
ARQ協議發送者每次只能發送一個分組,在應答到來前必須等待。而連續ARQ協議的發送者擁有一個發送窗口,發送者可以在沒有得到應答的情況下連續發送窗口中的分組。這樣降低了等待時間,提高了傳輸效率。
累計確認
在連續ARQ協議中,接收者也有個接收窗口,接收者並不需要每收到一個分組就返回一個應答,可以連續收到分組之后統一返回一個應答。這樣能節省流量。
TCP頭部的ack字段就是用來累計確認,它表示已經確認的字節序號+1,也表示期望發送者發送的下一個分組的起始字節號。
發送窗口

發送窗口的大小由接收窗口的剩余大小決定。接收者會把當前接收窗口的剩余大小寫入應答TCP報文段的頭部,發送者收到應答后根據該值和當前網絡擁塞情況(選擇二者最小的值)設置發送窗口的大小。發送窗口的大小是不斷變化的。
發送窗口由三個指針構成:
p1
p1指向發送窗口的后沿,它左邊的字節表示已經發送且已收到應答。
p2
p2指向尚未發送的第一個字節。
p1-p2間的字節表示已經發送,但還沒收到確認應答。這部分的字節仍需保留,因為可能還要超時重發。
p2-p3間的字節表示可以發送,但還沒有發送的字節。
p3
p3指向發送窗口的前沿,它前面的字節尚未發送,且不允許發送。
發送者每收到一個應答,后沿就可以向前移動指定的字節。此時若窗口大小仍然沒變,前沿也可以向前移動指定字節。
當p2和前沿重合時,發送者必須等待確認應答。
接收窗口

接收者收到的字節會存入接收窗口,接收者會對已經正確接收的有序字節進行累計確認,發送完確認應答后,接收窗口就可以向前移動指定字節。
如果某些字節並未按序收到,接收者只會確認最后一個有序的字節,從而亂序的字節就會被重新發送。
超時重傳時間選擇
TCP采用自適應的算法, 對報文的往返時間(RTT) 進行加權平均, 得出平滑的往返時間, 並且, 對於報文重傳的情況: 這一次就不采用加權平均, 而是直接將重傳時間增大兩倍. 直到分組不重傳.
選擇確認SACK
在滑動窗口中, 我們提到: 可以將不按序的數據先存放在接收臨時窗口, 等連續了再交付,通過選擇確認來實現讓發送方知道那些序號,利用兩個指針來描述出缺失序號的起始位置和終點位置, 並將在即將返回的確認分組中添加這兩個指針的信息,這樣下一次發送方發送的就是這個缺失序號段的內容了.
連續ARQ的注意點
同一時刻發送窗口的大小並不一定和接收窗口一樣大。
雖然發送窗口的大小是根據接收窗口的大小來設定的,但應答在網絡中傳輸是有時間的,有可能t1時間接收窗口大小為m,但當確認應答抵達發送者時,接收窗口的大小已經發生了變化。
此外發送窗口的大小還隨網絡擁塞情況影響。當網絡出現擁塞時,發送窗口將被調小。
TCP標准並未規定未按序到達的字節的處理方式。但TCP一般都會緩存這些字節,等缺少的字節到達后再交給應用層處理。這比直接丟棄亂序的字節要節約帶寬。
TCP標准規定接收方必須要有累計確認功能。接收方可以對多個TCP報文段同時確認,但不能拖太長時間,一般是0.5S以內。
此外,TCP允許接收者在有數據要發送的時候捎帶上確認應答。但這種情況一般較少,因為一般很少有兩個方向都要發送數據的情況。
