1. 程式人生 > >20-TCP 協議(滑動視窗——基礎)

20-TCP 協議(滑動視窗——基礎)

相信大家都遇到過這樣的場景:

同學 Luffy 給你打電話,讓你記下一串手機號碼,可是你記憶力不太好,你跟 Luffy 約定,一次只最多隻能報 4 個數字,Luffy 念一遍,如果你聽到了就把他說的話重複一遍。接下來:

  • 你:你一次最多報 4 個數字,多了我記不住啊!
  • Luffy:139
  • 你:139 (Luffy 知道你聽到了)
  • Luffy:7548
  • 你:7538 (很明顯你聽錯了)
  • Luffy:不對,是7548
  • 你:7548
  • Luffy : 2669
  • 你:2669

最後,你接收到的完整的號碼就是 139-7548-2669.

1. 滑動視窗

上面的場景,你一次最多隻能接受 4 個數字,表示你的滑動視窗大小就是 4. 在 TCP 協議中,也有這樣的滑動視窗,它的大小表示目前還能接收多少位元組的資料。

TCP 每次收到對方發來的報文,都會檢查視窗大小欄位,見圖 1.


這裡寫圖片描述
圖1 TCP 首部中有一個欄位——16 位視窗大小

知道了對方的視窗大小後,就知道對方目前還能接收多少資料,接收的資料位元組序號是 TCP 段中的 ACK 的值到 ACK + 視窗大小,即 [ACK,ACK+).

比如,你給對方傳送了一個段攜帶位元組序號為 [400, 500) 的資料。對方回送了一個 TCP 段,ack = 500, win = 100,就表示,我已經收到 [400, 500) 的資料我還能接收位元組序號為 [500, 600) 之間的資料,見圖 2。


這裡寫圖片描述
圖2 滑動視窗

如果對方回送了一個 TCP 段,ack = 500, win = 0,就表示,我已經收到了 [400, 500) 的資料,但是我現在不能再接收資料了,你待會再發。


這裡寫圖片描述
圖3 對方回送 0 大小的視窗,接收端的反應

2. 滑動視窗的目的

回顧本文開頭給出的打電話的例子,為什麼你要告訴對方一次最多隻能報 4 個數字?原因在於你的接受能力有限,不是說你無法記憶很多數字,只是在短期內,你記不住,你需要一段一段的記憶(一段一段的將資料放入緩衝區)。

所以,在 TCP 中,滑動視窗是為了實現流量控制。如果對方傳送資料過快,接收方就來不及接收(你來不急記住),接收方就需要通告對方,減慢資料的傳送(圖 3)。

需要特別注意的是,在學習滑動視窗的時候,我們假設網路無限好,不擁塞。只要你傳送了資料,對方一定可以收到。

再解釋一下網路擁塞的含義,它是指你傳送的資料滯留在網路中,遲遲未到達接收方。

3. 滑動視窗模擬


這裡寫圖片描述
圖4 滑動視窗模擬

修正:圖4 中最後一個小圖修正一下文字,應該為『傳送方收到 ack=41, win=10, 知道對方希望接收序號為 [41, 51) 的資料』

  • 傳送方接收到了對方發來的報文 ack = 33, win = 10,知道對方收到了 33 號前的資料,現在期望接收 [33, 43) 號資料。傳送方連續傳送了 4 個報文段假設為 A, B, C, D, 分別攜帶 [33, 35), [35, 36), [36, 38), [38, 41) 號資料。
  • 接收方接收到了報文段 A, C,但是沒收到 B 和 D,也就是隻收到了 [33, 35) 和 [36, 38) 號資料。接收方傳送回對報文段 A 的確認:ack = 35, win = 10。
  • 傳送方收到了 ack = 35, win = 10,對方期望接收 [35, 45) 號資料。接著傳送了一個報文段 E,它攜帶了 [41, 44) 號資料。
  • 接收方接收到了報文段 B: [35, 36), D:[38, 41),接收方傳送對 D 的確認:ack = 41, win = 10. (這是一個累積確認
  • 傳送方收到了 ack = 41, win = 10,對方期望接收 [41, 51) 號資料。
  • ……

需要注意的是,接收方接收 tcp 報文的順序是不確定的,並非是一定先收到 35 再收到 36,也可能是先收到 36,37,再收到 35.

4. 總結

  • 理解滑動視窗的工作過程
  • 滑動視窗的目的是什麼?

下一篇文章,我們得抓個包來分析一下。