(五)深刻淺出TCPIP之TCP流量控制

目錄c++

TCP流量控制面試

滑動窗口算法

固定窗口和滑動窗口緩存

如何告知發送方窗口大小服務器

滑動窗口細節網絡

實例異步

注意流量控制和擁塞控制的區別:性能

連環發問spa


專欄其餘文章:

 

理論篇:操作系統

(一)深刻淺出TCPIP之理解TCP報文格式和交互流程

  (二)深刻淺出TCPIP之再識TCP,理解TCP三次握手(上)

  (三)深刻淺出TCPIP之再識TCP,理解TCP四次揮手(上)

  (四)深刻淺出TCPIP之TCP三次握手和四次揮手(下)的抓包分析

  (五)深刻淺出TCPIP之TCP流量控制

  (六)深刻淺出TCPIP之TCP擁塞控制

  (七)深刻淺出TCPIP之深刻淺出TCPIP之TCP重傳機制

 (八)深刻淺出TCPIP之TCP長鏈接與短鏈接詳解

 (九)深刻淺出TCPIP之網絡同步異步

 (十)深刻淺出TCPIP之網絡阻塞和非阻塞

(十一)深刻淺出TCPIP之TCP粘包問題

  (十二)深刻淺出TCPIP之Nagle算法

  (十三) 深刻淺出TCPIP之TCP套接字參數

  (十四)深刻淺出TCPIP之初識UDP理解報文格式和交互流程

  (十五)很是全面的TCPIP面試寶典-進入大廠必備總結

 (十六)深刻淺出TCPIP之Hello CDN

 ....

(二十)深刻淺出TCPIP之epoll的一些思考

實踐篇:

   深刻淺出TCPIP之實戰篇—用c++開發一個http服務器(二十一)

其餘實踐篇+遊戲開發中的網絡問題疑難雜症解讀 正在完善。。。

TCP流量控制

   咱們都知道TCP是一種可靠的,面向鏈接的傳輸層協議。咱們老是但願TCP可以傳輸的數據越快越好。若是存在這樣一種狀況,發送方數據發送的很是快,並且接收方耗盡本身的資源也根原本不及接收,那這些多餘的數據就會被丟棄,這就違背了TCP可靠的宗旨了。

   因此就須要引入一種流量控制的手段:讓發送方不要發送太快,既讓接收方可以順利接收數據,並且也不會形成網絡鏈路的阻塞。 

滑動窗口

爲了讓發送方不要發送的太快。那就讓接收方控制發送方的數據大小,每次應答的時候通知發送方本身還剩多少空間能夠接收數據。那麼滑動窗口相似一個窗口,是用來告訴發送方能夠發送數據的大小。也能夠說是窗口標記了接收方緩衝區的大小。窗口大小也就表示一次能發送多少數據量,並且這個窗口能夠滑動,滑動窗口所以得名。

固定窗口和滑動窗口

咱們能夠看下面一張圖來分析一下固定大小窗口有什麼問題。

   這裏咱們能夠看到假設窗口大小是1,也是就每次只能發送一個數據只有接收方對這個數據進行確認了之後才能發送第2個數據。咱們能夠看到發送每發送一個數據接收方就要給發送方一個ACK對這個數據進行確認。只有接收到了這個確認數據之後發送方纔能傳輸下個數據。這樣咱們考慮一下若是說窗口太小,那麼當傳輸比較大的數據的時候須要不停的對數據進行確認,這個時候就會形成很大的延遲。若是說窗口大小定義的過大。咱們假設發送方一次發送100個數據,但接收方只能處理50個數據。這樣每次都會只對這50個數據進行確認。發送方下一次仍是發送100個數據,可是接收方仍是隻能處理50個數據。這樣就避免不了沒必要要的數據來擁塞咱們的鏈路。因此咱們就引入了滑動窗口機制,窗口大小並非固定的而是根據咱們之間的鏈路的帶寬的大小,這個時候鏈路是否擁塞,接收方是否能處理這麼多數據了。

咱們看看滑動窗口是如何工做的,咱們看下面幾張圖

首先是第一次發送數據,這個時候的窗口的大小是根據鏈路帶寬的大小決定的。咱們假設這個時候窗口大小是3,這個時候接收方收到數據之後會對數據進行確認告訴發送方我下次但願收到的數據是多少。這裏咱們看到接收方發送的ACK = 3(這是發送方發送序列2的回答確認,下一次接收方指望接收的是3序列信號)。這個時候發送方收到這個數據之後就知道第一次發送的3個數據對方只接收了2個。就知道第3個數據對方沒有收到。下次在發送的時候就從第3個數據開始發,這時候窗口大小就變成了2

這個時候發送方發送2個數據

看到接收方發送的ACK是5就表示它下一次但願收到的數據是5,發送方就知道我剛纔發送的2個數據對方接收了,這個時候開始發送第5個數據。
這就是滑動窗口的工做機制,當鏈路變好了或者變差了,這個窗口還會發生變化,並非第一次協商好了之後就永遠不變了。

 

如何告知發送方窗口大小

如何通知發送方窗口大小呢?難道要從新發送一包數據告訴對方嗎,這顯然是不合理的。能夠巧妙的使用確認應答包。須要在三次握手時候,就告知對方。在原來的確認應答策略中,每一次發送數據,都須要Ack應答,在接收到Ack以後纔會發送下一個數據段,發送方沒有接收到Ack應答呢?這樣作的方式效率實在過低。使用了滑動窗口,能夠屢次發送數據,只要不要超過對方窗口大小。這樣就大大提升了效率。

 

滑動窗口細節

  1. 接收方將本身可以接收的緩衝區大小是在TCP首部中的「窗口大小」字段表示的,經過Ack通知發送方。
  2. 窗口大小是發送方能夠發送數據的,也就是說能夠不須要Ack應答,能夠發送屢次數據,前提發送總數據量不要超過窗口大小。
  3. 窗口大小大說明網絡的吞吐率高
  4. 操做系統內核維護了一塊接收緩衝區,只有Ack應答以後的數據才能從緩衝區中刪除。
  5. 接收方一旦發現本身的緩衝區快滿了,就會通知對方本身的窗口爲更小的值。
  6. 若是接收方發現本身的緩衝區滿了,就會將窗口的大小設置爲0,此時發送方將再也不發送數據,可是須要按期發送一個窗口探測數據段,使接收方把窗口大小告訴發送方 。(針對這一點重點說明下爲何須要按期發送窗口探針?能夠想象下,若是接收方緩衝區滿了,而後經過Ack告知發送方窗口大小爲0。發送方今後不會發送數據給接收方,接收方也沒辦法告知對方本身緩衝區能夠接收數據,就會出現「卡死」的狀況)                    

流量控制是端到端的控制,例如A經過網絡給B發數據,A發送的太快致使B無法接收(B緩衝窗口太小或者處理過慢),這時候的控制就是流量控制,原理是經過滑動窗口的大小改變來實現。

實例

A 向 B 發送數據。在鏈接創建時,B 告訴 A:「個人接收窗口 rwnd = 400(字節)。注意:圖中的箭頭上面大寫的ACK表示首部中的確認位ACK,小寫ack表示確認字段的值。

上面的過程是這樣的:

  1. A發送了數據序號1至100,還能發送300字節
  2. A發送了數據序號101至200,還能發送200字節
  3. A發送了數據序號201至300,可是丟失了數據
  4. B發送了ACK,同時通知A,容許A發送序號201至500,300字節
  5. A發送了數據序號301至400,還能發送100字節
  6. A發送了數據序號401至500,不能發送數據了
  7. A超時重傳舊的數據,但不能發送新數據
  8. B發送了ACK,同時通知A,容許A發送序號501至600,100字節
  9. A發送了數據序號501至600,不能發送數據了
  10. B發送了ACK,同時通知A,不容許A發送數據

注意流量控制和擁塞控制的區別:

流量控制是指點對點通訊的控制,作的是抑制發送端發送數據的速率,便於接收端來得及接收。
擁塞控制是防止過多的數據注入網絡中,使得網絡中路由器或鏈路不致過載,有一個前提是,網絡可以承受現有的網絡負荷,是一個全局性過程;

 

連環發問

一、TCP有幾個滑動窗口?

 這裏說明下,因爲TCP/IP支持全雙工傳輸,所以通訊的雙方都擁有兩個滑動窗口,一個用於接受數據,稱之爲接收窗口;一個用於發送數據,稱之爲擁塞窗口(即發送窗口)。指出接受窗口大小的通知咱們稱之爲窗口通告。

二、接收窗口的大小固定嗎?

在早期的TCP協議中,接受接受窗口的大小確實是固定的,不過隨着網絡的快速發展,固定大小的窗口太不靈活了,成爲TCP性能瓶頸之一,也就是說,在如今的TCP協議中,接受窗口的大小是根據某種算法動態調整的。

三、接受窗口越大越好嗎?

接受窗口若是過小的話,顯然這是不行的,這會嚴重浪費鏈路利用率,增長丟包率。那是否越大越好呢?答否,當接收窗口達到某個值的時候,再增大的話也不怎麼會減小丟包率的了,並且還會更加消耗內存。因此接收窗口的大小必須根據網絡環境以及發送發的的擁塞窗口來動態調整。

四、發送窗口和接受窗口相等嗎?

接收方在發送確認報文的時候,會告訴發送發本身的接收窗口大小,而發送方的發送窗口會據此來設置本身的發送窗口,但這並不意味着他們就會相等。首先接收方把確認報文發出去的那一刻,就已經在一邊處理堆在本身緩存區的數據了,因此通常狀況下接收窗口 >= 發送窗口。

相關文章
相關標籤/搜索