TCP中的資料是怎麼傳輸的?

爬蜥發表於2019-02-26

互動式資料是怎麼傳輸的?

互動式資料指泛指每次傳遞的位元組很少,比如Telnet,Rlogin

以Rlogin為例,它每次傳到伺服器的是一個位元組的按鍵,並且要求伺服器回顯客戶端輸入的字元。理論上完整的互動包括4個報文段:

  1. 客戶端傳送互動的資料
  2. 服務端對互動的資料進行ack
  3. 服務端對資料進行會顯
  4. 客戶端對資料回顯進行確認

輸入字元 date
產生的資料流如下:

TCP中的資料是怎麼傳輸的?

可以發現真實的資料流存在如下特點:

  • 資料是一個一個位元組的傳送的

對應客戶端傳送的序號為 1、4、7、10、13,可以看到位元組長度都是1,其中13的回顯確認位元組長度為2是因為換行符包括兩個字元

  • 服務端存在資料捎帶ACK現象。即資料的傳送和ACK混合在了一起

以序號為2的資料流為例,服務端傳送了資料,並進行了ack操作,也就是合併了資料回顯和客戶端資料傳送的ack,資料互動理論上的4次在實際中只有3次報文互動

  • 客戶端傳送ACK的實際時間差基本上是200ms的整數倍。這是因為TCP內部使用了200ms的定時器

ack傳送時間序號對應3、6、9、12等,值分別是 139.9ms、539.9ms、940.1ms、1339.9ms,其時間間隔為 400ms,400.2ms,399.8ms

側面反應TCP傳送資料最大的等待時延也就是200ms

  • 服務端不存在經受時延的ACK。經受時延的ack是指如果TCP等待資料傳送的200ms之內還沒有收到資料,就單獨傳送一個ack,不帶資料。

資料到達和回顯的時間間隔為序號1-2,4-5,7-8等,值為16.5ms 16.3ms 16.5ms,也就是在200ms定時器溢位之前,都有資料到達

單個位元組傳送的缺點是什麼?

每次只傳送一個位元組的資料,那麼在網路中很有可能充斥這許多41位元組長的分組(20的IP包首部,20的TCP包首部,1位元組的資料),過多的這種小分組則會增加擁塞的可能性

Nagle演算法是如何解決單位元組傳送缺點的?

  1. TCP連線上最多隻有一個未被確認的未完成的小分組
  2. 未完成確認的小分組確認之前,不能傳送其它的小分組
  3. 在確認到達之前收集少量的分組,在確認到達之後以一個分組的方式傳送出去

關閉Nagle演算法的場景有哪些?

如果應用場景使得使用者能夠感覺到明顯的延遲,那麼就可以選擇關閉Nagle選項。

通常情況使用Nagle演算法是在較慢的廣域網中,以便能夠減少小報文的數目

成塊的資料是如何傳輸的?

成塊的資料比如電子郵件

tcp通過滑動視窗來控制成塊資料的流量,使得傳送方在不需要每傳送一個分組就等待確認,從而加快了資料的傳輸

什麼是滑動視窗?

TCP中的資料是怎麼傳輸的?

上圖是滑動視窗的一個快照,以時間為橫軸,其中1-11表示傳送方傳送的位元組的標號。

視窗是指資料處理方【傳送方和接收方】維護的一個序列,在TCP協議中可以看做是報文片段序列,所謂滑動視窗則是描述隨著時間的推移,原始的報文已經被處理,可從視窗中移除,並開始去處理新加入視窗的報文序列。

滑動視窗本身可以看做是一個協議,適合於資料傳輸過程中要求有嚴格順序處理的場景

上圖中,滑動視窗將時間軸上的資料分成了4個部分:

A:標識所在表示當前快照產生時,1-3個位元組已經被接收方所處理,並且傳送方確認了ack; 

B:標識所在表示快照下的滑動視窗內傳送方已經傳送了3個位元組,但是接收方還沒確認;

C:標識標識接收方當前的可用視窗大小,也是傳送方能夠傳送的資料量;

D:標識標識當前快照下,接收方無法再接收資料了,空間不足,傳送方無法傳送;

視窗是如何運動的?

  • 當視窗左邊沿向右邊沿靠近時,稱作視窗合攏。這種現象發生在資料被髮送和確認時;
  • 當視窗右邊沿向右移動時,稱作視窗張開。這種現象發生在另一端接收程式讀取已經確認的資料並釋放TCP的接收快取時;
  • 當右邊沿向左移動時,稱作視窗收縮。不建議使用這種方式,但是TCP需要實現這種場景
  • 視窗的左邊沿一般不可能向左移動,如果接收到左邊沿向左移動的ACK,則會被認為是重複的ACK,並被丟棄

左邊沿到達右邊沿稱為零視窗,此時傳送方不能傳送任何資料

如何理解TCP報文中的win?

報文中的win用來描述視窗的大小。接收方視窗的大小可以通過接收方來實現控制,預設情況下4.3BSD中視窗大小為4096個位元組,如果視窗中有還沒來得及被應用程式讀取的資料,那麼返回報文中的win就會相應減小,當視窗中資料被處理之後,可能會出現攜帶ack但不確認任何資料,而win值變大的包,這種情況是用來增加視窗的有邊沿,也稱作視窗更新。

如果傳送方和接收方之間存在多個路由器和較慢的鏈路時,TCP協議傳送方是如何處理的?

TCP實現了一個慢啟動演算法,它為傳送方提供一個擁塞視窗,開始時只會傳送1個報文段,然後等待ACK

TCP中的資料是怎麼傳輸的?

圖中顯示的是離散的時間單元,時間點1、2、3表示報文段從左向右移動一個時間單元,時間4接收方讀取報文段併產生一個確認,時間點5、6、7表示ACK傳輸給傳送方,整個過程經歷了一個8個時間單元的RTT(Round-Trip Time)

收到ACK後,進而傳送兩個報文段

TCP中的資料是怎麼傳輸的?

時間點12和時間點13產生的兩個ack之間的間隔和報文段之間的間隔一樣,被稱為TCP的自計時(self-clocking)行為。實際運用過程中,返回路徑上的排隊會改變ACK的到達率

兩個ACK的到達使得擁塞視窗從2個報文段增加為4個

TCP中的資料是怎麼傳輸的?

4個ack到達增加為8個

TCP中的資料是怎麼傳輸的?

在時間點31之後的時間裡,傳送方和接收方的管道都被填滿,此時無論擁塞視窗和通告視窗是多少,它都不能再容納更多的資料,此時放回路徑上總是能保持相同數量的ACK,也就是連線的理想穩定狀態

擁塞視窗是傳送方使用的流量控制,通告視窗是接收方使用的流量控制;傳送方的傳送上限為擁塞視窗和通告視窗的最小值。

TCP報文中的PUSH標識是幹什麼用的?

客戶端用來通知TCP在向伺服器傳送一個報文時,不要因等待額外資料而使已提交資料在快取中滯留。伺服器收到帶PUSH標識的TCP報文時,則立即將這些資料遞交給伺服器程式。

TCP的緊急方式有什麼用?

它使得一端可以告知另一端有些具有某種方式的“緊急資料”已經放置在普通資料流中,接收方收到通知後可以做相應處理。

以Telnet和Rlogin為例。當伺服器進入了緊急方式,此時伺服器是無法傳送任何資料的,但伺服器TCP會立即傳送緊急指標和URG標誌,當客戶端TCP收到這個通知時,便會通知客戶端程式,於是客戶端可以從伺服器讀取其輸入、開啟視窗使資料流動

如何設定TCP的緊急方式?

設定TCP首部的URG標誌為1,並且一個16bit的緊急指標被置為一個正的偏移量,次偏移量與TCP首部中的序號欄位相加,便得到緊急資料的最後一個位元組的序號。

只要接收方當前讀取位置到緊急指標之間有資料存在,就認為應用程式處於“緊急方式”

如果接收方在處理第一個緊急方式之前,傳送方多次進入緊急方式,接收方收到的舊緊急指標將會被新值覆蓋

附錄

把書讀薄(TCP/IP詳解 卷一 第十九章 第二十章)

相關文章