一篇帶你讀懂TCP之“滑動視窗”協議

Coder程式設計發表於2019-03-30

前言

你現在的努力,是為了以後有更多的選擇。

在上一篇文章通過“表白”方式,讓我們快速瞭解網路七層協議 瞭解了網路七層協議。 接下來我們要把重心放在網路傳輸的可靠性上面。一起來看TCP協議,它是如何解決網路傳輸不可靠的問題。這其中有個很關鍵的部分,就是我們的滑動視窗協議

從工程學角度上,我們來看一看滑動視窗協議,它到底解決了一個怎樣的問題?

滑動視窗協議:

  • TCP協議的使用
  • 維持傳送方/接收方緩衝區 緩衝區是 用來解決網路之間資料不可靠的問題,例如丟包,重複包,出錯,亂序

在TCP協議中,傳送方和接受方通過各自維護自己的緩衝區。通過商定包的重傳機制等一系列操作,來解決不可靠的問題。

問題一:如何保證次序?

提出問題:在我們滑動視窗協議之前,我們如何來保證傳送方與接收方之間,每個包都能被收到。並且是按次序的呢?

問題1
傳送方傳送一個包1,這時候接收方確認包1。傳送包2,確認包2。就這樣一直下去,知道把資料完全傳送完畢,這樣就結束了。那麼就解決了丟包,出錯,亂序等一些情況!同時也存在一些問題。問題:吞吐量非常的低。我們發完包1,一定要等確認包1.我們才能傳送第二個包。

問題二:如何提高吞吐量?

提出問題:那麼我們就不能先連發幾個包等他一起確認嗎?這樣的話,我們的速度會不會更快,吞吐量更高些呢?

改進方案
如圖,這個就是我們把兩個包一起傳送,然後一起確認。可以看出我們改進的方案比之前的好很多,所花的時間只是一個來回的時間。接下來,我們還有一個問題:改善了吞吐量的問題

問題三:如何實現最優解?

問題:我們每次需要發多少個包過去呢?傳送多少包是最優解呢?

我們能不能把第一個和第二個包發過去後,收到第一個確認包就把第三個包發過去呢?而不是去等到第二個包的確認包才去發第三個包。這樣就很自然的產生了我們"滑動視窗"的實現。

實現
在圖中,我們可看出灰色1號2號3號包已經傳送完畢,並且已經收到Ack。這些包就已經是過去式。4、5、6、7號包是黃色的,表示已經傳送了。但是並沒有收到對方的Ack,所以也不知道接收方有沒有收到。8、9、10號包是綠色的。是我們還沒有傳送的。這些綠色也就是我們接下來馬上要傳送的包。 可以看出我們的視窗正好是11格。後面的11-16還沒有被讀進記憶體。要等4號-10號包有接下來的動作後,我們的包才會繼續往下傳送。

正常情況

正常情況
可以看到4號包對方已經被接收到,所以被塗成了灰色。“視窗”就往右移一格,這裡只要保證“視窗”是7格的。 我們就把11號包讀進了我們的快取。進入了“待傳送”的狀態。8、9號包已經變成了黃色,表示已經傳送出去了。接下來的操作就是一樣的了,確認包後,視窗往後移繼續將未傳送的包讀進快取,把“待傳送“狀態的包變為”已傳送“。

丟包情況

有可能我們包發過去,對方的Ack丟了。也有可能我們的包並沒有傳送過去。從傳送方角度看就是我們沒有收到Ack。

丟包
發生的情況:一直在等Ack。如果一直等不到的話,我們也會把讀進快取的待傳送的包也一起發過去。但是,這個時候我們的視窗已經發滿了。所以並不能把12號包讀進來,而是始終在等待5號包的Ack。

如果我們這個Ack始終不來怎麼辦呢?

超時重發

這時候我們有個解決方法:超時重傳 這裡有一點要說明:這個Ack是要按順序的。必須要等到5的Ack收到,才會把6-11的Ack傳送過去。這樣就保證了滑動視窗的一個順序。

超時重發
這時候可以看出5號包已經接受到Ack,後面的6、7、8號包也已經傳送過去已Ack。視窗便繼續向後移動。

文末

從我們為了增加網路的吞吐量,想講資料包一起傳送過去,這時候便產生了“滑動視窗”這種協議。有了“滑動視窗”這個概念,我們又解決了其中出現的一些問題。例如丟包,我們又通過重發的機制去解決了。以上來自ccmouse老師教學視訊,作為學習記錄整理。

如果文章對你有用的話,歡迎關注公眾號:Coder程式設計 獲取最新原創技術文章和相關免費學習資料,隨時隨地學習技術知識!

在這裡插入圖片描述

相關文章