1. 滑動窗口
咱們都知道TCP是可靠的協議,而可靠性不少時候就是來自於TCP的確認重傳機制,在確認重傳的基礎上,就實現了滑動窗口協議,滑動窗口主要有兩個做用:python
保證TCP的可靠性;c++
提供TCP的流控特性;算法
1.1 滑動窗口保證可靠性
所謂窗口其實就是表示一段存放在發送緩衝區中的、能夠被髮送者發送的字節序列,它連續的一個範圍,咱們就稱爲窗口。而滑動則是隨着數據不斷的被髮送,那麼窗口就會在緩衝區中向前移動。 好比:編程
TCP創建鏈接後,B告訴A本身的接收窗口大小,好比是20;緩存
而後A發送了11個字節,發送窗口位置不變,B接收到了亂序數據;微信
只有當A成功發送了數據,而且接收到了B返回來的確認以後,纔會按順序向前移動發送窗口,這樣就避免了超時後數據的重複發送;網絡
注意:如果B未在規定時間返回確認,那麼A端會進行重複發送app
1.2 滑動窗口進行流控
流量控制方面主要有兩個要點須要掌握。一是TCP利用滑動窗口實現流量控制的機制;二是如何考慮流量控制中的傳輸效率。性能
1.2.1 流量控制
所謂流量控制,主要是接收方傳遞信息給發送方,使其不要發送數據太快,是一種端到端的控制。主要的方式就是返回的ACK中會包含本身的接收窗口的大小,而且利用大小來控制發送方的數據發送。spa
這裏面涉及到一種狀況,若是B已經告訴A本身的緩衝區已滿,因而A中止發送數據;等待一段時間後,B的緩衝區出現了富餘,因而給A發送報文告訴A個人rwnd大小爲400,可是這個報文不幸丟失了,因而就出現A等待B的通知||B等待A發送數據的死鎖狀態。爲了處理這種問題,TCP引入了持續計時器(Persistence timer),當A收到對方的零窗口通知時,就啓用該計時器,時間到則發送一個1字節的探測報文,對方會在此時迴應自身的接收窗口大小,若是結果仍未0,則重設持續計時器,繼續等待。
1.2.2 傳輸效率
一個顯而易見的問題是:單個發送字節單個確認,和窗口有一個空餘即通知發送方發送一個字節,無疑增長了網絡中的許多沒必要要的報文,因此咱們的原則是儘量一次多發送幾個字節,或者窗口空餘較多的時候通知發送方一次發送多個字節。對於前者咱們普遍使用Nagle算法,即:
若發送應用進程要把發送的數據逐個字節地送到TCP的發送緩存,則發送方就把第一個數據字節先發送出去,把後面的字節先緩存起來;
當發送方收到第一個字節的確認後(也獲得了網絡狀況和對方的接收窗口大小),再把緩衝區的剩餘字節組成合適大小的報文發送出去;
當到達的數據已達到發送窗口大小的一半或以達到報文段的最大長度時,就當即發送一個報文段; 對於後者咱們每每的作法是讓接收方等待一段時間,或者接收方得到足夠的空間容納一個報文段或者等到接收緩存有一半空閒的時候,再通知發送方發送數據。
2. 擁塞控制
計算機網絡中的帶寬、交換結點中的緩存、路由器等等都是網絡的資源,他們所能提供的可用資源都是有限的,若是某一時間,對網絡中某一資源的需求超過了它的可用部分,網絡的性能就會變壞,就像堵車同樣,車的數量過多超過了路段的負荷,就是出現擁堵,類比到網絡,就是擁塞控制。
注意:擁塞控制是一個全局性的過程,而滑動窗口中的流量控制則是點到點通訊量的控制,他們是有本質區別的。
TCP的擁塞控制由四個核心算法組成:慢開始、擁塞避免、快重傳、快恢復。
2.1 慢開始和擁塞避免
發送方維持一個叫作擁塞窗口的狀態變化,擁塞窗口的大小取決於網絡的擁塞程度,而且動態的在變化,而發送方的發送窗口可能等於擁塞窗口,也可能由於接收方的接收緩存不夠,那麼發送窗口就會小於擁塞窗口。
慢開始算法的思路是說,一開始先不發送大量的數據,須要先探測一下網絡的擁塞程度,由小變大的逐漸增長擁塞窗口的大小。
擁塞避免,則是在擁塞控制中還有個慢開始門限ssthresh狀態變量,假設擁塞窗口大小爲cwind,那麼有以下幾種狀況:
當cwind < ssthresh時,即執行慢開始算法,當使用當前擁塞窗口發送數據,收到屢次確認之後,將cwind加倍,繼續發送;
當cwind > ssthresh時,執行擁塞避免算法,將cwind+1,而後繼續發送數據;
當網絡發送擁塞時,把ssthresh更新爲擁塞前ssthresh值的一半,cwind從新設置爲1,按照以上兩種狀況繼續執行;
2.2 快重傳和快恢復
快重傳算法,其實就是要求發送方只要一連收到3個重複確認就當即重傳對方還沒有收到的報文段,而沒必要繼續等待設置的重傳計時器時間到。 快重傳配合使用的就是快恢復,有如下兩種狀況:
當發送方連續收到三個重複確認後,就執行乘法減少算法,把ssthresh減半,但並不執行慢開始算法;
另外一種狀況是,考慮到若是網絡出現擁塞的話,發送方可能收不到三個連續的重複確認,就會認爲網絡沒有出現擁塞,因此此時也不執行慢開始算法,而是將cwind大小設置爲ssthresh,執行擁塞避免算法;
從全局來說,TCP擁塞控制其實較好的保證了數據流之間的公平性,由於一旦出現丟包,就當即減半退避,能夠給其餘新建的數據流留有足夠的空間,從而保證整個的公平性。
3. 斷線重連
顧名思義,就是網絡斷了之後要進行重連,在網絡編程中,斷線重連機制是必需要有的,那麼怎麼設計一個斷線重連機制呢?
3.1 程序設置固定重連時間
有兩種狀況:
一是發現斷線後立馬重連一次,而後間隔2秒後重連,而後是4秒、6秒、8秒等;
二是2秒,4秒,6秒,8秒這樣去重連;
3.2 讓客戶設置
就是在斷線後,在界面上彈出窗口讓客戶本身設置重連間隔,這一點在許多桌面客戶端和移動app上都有體現。
3.3 監控網絡狀態
咱們能夠得到網絡狀況,若是是網絡斷開了,那麼咱們確定不會去重連,但若是網絡一旦好了,咱們就要立馬重連。
更多c++及python系列文章,請關注個人公衆號:晟夏的葉。
本文分享自微信公衆號 - cpp加油站(xy13640954449)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。