TCP中的數據是怎麼傳輸的?

交互式數據是怎麼傳輸的?

交互式數據指泛指每次傳遞的字節不多,好比Telnet,Rlogin

以Rlogin爲例,它每次傳到服務器的是一個字節的按鍵,而且要求服務器回顯客戶端輸入的字符。理論上完整的交互包括4個報文段:算法

  1. 客戶端發送交互的數據
  2. 服務端對交互的數據進行ack
  3. 服務端對數據進行會顯
  4. 客戶端對數據回顯進行確認

輸入字符 date\n 產生的數據流以下:緩存


能夠發現真實的數據流存在以下特色:服務器

  • 數據是一個一個字節的發送的
對應客戶端發送的序號爲 一、四、七、十、13,能夠看到字節長度都是1,其中13的回顯確認字節長度爲2是由於換行符包括兩個字符
  • 服務端存在數據捎帶ACK現象。即數據的發送和ACK混合在了一塊兒
以序號爲2的數據流爲例,服務端發送了數據,並進行了ack操做,也就是合併了數據回顯和客戶端數據發送的ack,數據交互理論上的4次在實際中只有3次報文交互
  • 客戶端發送ACK的實際時間差基本上是200ms的整數倍。這是由於TCP內部使用了200ms的定時器
ack發送時間序號對應三、六、九、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選項。tcp

一般狀況使用Nagle算法是在較慢的廣域網中,以便可以減小小報文的數目

成塊的數據是如何傳輸的?

成塊的數據好比電子郵件

tcp經過滑動窗口來控制成塊數據的流量,使得發送方在不須要每發送一個分組就等待確認,從而加快了數據的傳輸3d

什麼是滑動窗口?


上圖是滑動窗口的一個快照,以時間爲橫軸,其中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值變大的包,這種狀況是用來增長窗口的有邊沿,也稱做窗口更新。code

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

TCP實現了一個慢啓動算法,它爲發送方提供一個擁塞窗口,開始時只會發送1個報文段,而後等待ACKcdn


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

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


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

兩個ACK的到達使得擁塞窗口從2個報文段增長爲4個


4個ack到達增長爲8個


在時間點31以後的時間裏,發送方和接收方的管道都被填滿,此時不管擁塞窗口和通告窗口是多少,它都不能再容納更多的數據,此時放回路徑上老是能保持相同數量的ACK,也就是鏈接的理想穩定狀態

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

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

客戶端用來通知TCP在向服務器發送一個報文時,不要因等待額外數據而使已提交數據在緩存中滯留。服務器收到帶PUSH標識的TCP報文時,則當即將這些數據遞交給服務器進程。

TCP的緊急方式有什麼用?

它使得一端能夠告知另外一端有些具備某種方式的「緊急數據」已經放置在普通數據流中,接收方收到通知後能夠作相應處理。

以Telnet和Rlogin爲例。當服務器進入了緊急方式,此時服務器是沒法發送任何數據的,但服務器TCP會當即發送緊急指針和URG標誌,當客戶端TCP收到這個通知時,便會通知客戶端進程,因而客戶端能夠從服務器讀取其輸入、打開窗口使數據流動

如何設置TCP的緊急方式?

設置TCP首部的URG標誌爲1,而且一個16bit的緊急指針被置爲一個正的偏移量,次偏移量與TCP首部中的序號字段相加,便獲得緊急數據的最後一個字節的序號。

只要接收方當前讀取位置到緊急指針之間有數據存在,就認爲應用程序處於「緊急方式」
若是接收方在處理第一個緊急方式以前,發送方屢次進入緊急方式,接收方收到的舊緊急指針將會被新值覆蓋

附錄

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

相關文章
相關標籤/搜索