出現差錯或丟失的時候,發送方會將本身備份的副本再重傳一次,直到收到接收的確認信息。當接收方收到重複的數據時,會直接丟棄,可是會給發送方請確認本身已經收到了。html
上面的中止等待協議每發送一組數據就必須等到接收方回覆確認後,再發起第二組數據,若是出現超時重傳的話,效率更低。所以爲了提升傳輸的效率,改進了等待傳輸協議。算法
連續ARQ協議和滑動窗口協議的機制是以接收方回覆確認爲單位,每次連續發送一個滑動窗口指定的數據組。示例圖以下:緩存
滑動窗口是由發送方維護的相似指針的變量,在每收到一個接收方的確認消息後,該指針向前移動併發送數據,到窗口指定大小的數據組時停下,等待接收方的確認。示意看圖:網絡
發送方不對收到的分組逐個發送確認,而是對按序到達的最後一個分組發送確認,這樣就表示:到這個分組爲止的全部分組都已正確收到了。併發
優勢:容易實現,即便確認丟失也沒必要重傳。性能
缺點:不能向發送方反映出接收方已經正確收到的全部分組的信息。spa
爲了解決上述同一窗口中數據組不能完整確認的問題,連續ARQ協議採用了回退機制。好比說:發送方發送了前 5 個分組,而中間的第 3 個分組丟失了。這時接收方只能對前兩個分組發出確認。發送方沒法知道後面三個分組的下落,而只好把後面的三個分組都再重傳一次。這就叫作 Go-back-N(回退 N),表示須要再退回來重傳已發送過的 N 個分組。3d
結論:當通訊線路質量很差時,連續 ARQ 協議會帶來負面的影響。可能還不如傳統的中止等待協議。指針
滑動窗口是面向字節流的,爲了方便記住每一個分組的序號,下面的圖解以一個分組假設100個字節,爲了方便畫圖表示,將分組進行編號簡化表示,如圖所示,可是要記住,每個分組的序號是多少。htm
TCP通訊時,若是發送序列中間某個數據包丟失,TCP會經過重傳最後確認的分組後續的分組,這樣原先已經正確傳輸的分組也可能重複發送,下降了TCP性能。SACK(Selective Acknowledgment,選擇確認)技術,使TCP只從新發送丟失的包,不用發送後續全部的分組,並且提供相應機制使接收方能告訴發送方哪些數據丟失,哪些數據已經提早收到等。在創建 TCP 鏈接時,就要在 TCP 首部的選項中加上「容許 SACK」的選項,而雙方必須都事先商定好。原來首部中的「確認號字段」的用法仍然不變。只是之後在 TCP 報文段的首部中都增長了 SACK 選項,以便報告收到的不連續的字節塊的邊界。
選擇性確認最多表示4個邊界:因爲首部選項的長度最多隻有 40 字節。須要一個字節指明是SACK選項,另外一個字節指明佔多少字節。而指明一個邊界就要用掉 4 字節。在選項中最多隻能指明 4 個字節塊的邊界信息。因4個字節塊共8個邊界信息。
抓包分析:
重傳機制是 TCP 中最重要和最複雜的問題之一。TCP 每發送一個報文段,就對這個報文段設置一次計時器。只要計時器設置的重傳時間到但尚未收到確認,就要重傳這一報文段。那麼這個重傳時間到底應該設置多少呢?這裏面有學問。如下是我截取的「手抄報」,暫時看不懂。建議跳過。
TCP 保留了 RTT 的一個加權平均往返時間 RTTS(這又稱爲平滑的往返時間)。第一次測量到 RTT 樣本時,RTTS 值就取爲所測量到的 RTT 樣本值。之後每測量到一個新的 RTT 樣本,就按下式從新計算一次 RTTS:
流量控制(flow control)就是讓發送方的發送速率不要太快,既要讓接收方來得及接收,也不要使網絡發生擁塞。利用滑動窗口機制能夠很方便地在 TCP 鏈接上實現流量控制。
流量控制舉例說明:
考慮上面的例子中,當A發送的數據已經到達B的接收窗口上限,此時A就必須等待B處理了部分數據後,待接收窗口有空閒的時候,再次發送數據,那麼A是怎麼知道B的接收窗口什麼時候有空閒呢?這時就用到了持續計時器。
TCP 爲每個鏈接設有一個持續計時器。只要 TCP 鏈接的一方收到對方的零窗口通知,就啓動持續計時器。若持續計時器設置的時間到期,就發送一個零窗口探測報文段(僅攜帶 1 字節的數據),而對方就在確認這個探測報文段時給出瞭如今的窗口值。若窗口仍然是零,則收到這個報文段的一方就從新設置持續計時器。若窗口不是零,則死鎖的僵局就能夠打破了。
關於TCP的傳輸效率問題,須要從三方面來考慮,1.什麼時候發送;2.少字節發送數據問題;3.糊塗窗口綜合症問題
3.1 TCP報文的發送時機:
第一種機制是 TCP 維持一個變量,它等於最大報文段長度 MSS。只要緩存中存放的數據達到 MSS 字節時,就組裝成一個 TCP 報文段發送出去。
第二種機制是由發送方的應用進程指明要求發送報文段,即 TCP 支持的推送(push)操做。
第三種機制是發送方的一個計時器期限到了,這時就把當前已有的緩存數據裝入報文段(但長度不能超過 MSS)發送出去。
3.2 少許字節發送數據問題:
問題描述:若是應用程序一次產生一字節數據,這樣會致使網絡因爲太多的包而過載。如:從鍵盤輸入的一個字符,佔用一個字節,可能在傳輸上形成41字節的包,其中包括1字節的有用信息和40字節的標題數據。
解決方案(NAGLE算法):發送端的應用進程將欲發送的數據逐個字節地送到TCP緩存,則發送端就將第一個字符先發送出去。將後面到達的字符都緩存起來。當接收端收到對第一個字符確認後,再將緩存中的全部字符裝成一個報文段發送出去,同時繼續對隨後到在的字符進行緩存。只有在收到對前一個報文段確認後才繼續發送下一個報文段。
3.3 糊塗窗口綜合症問題:
問題描述:設想一種狀況:接收端緩存已滿,而交互式的應用進程一次只從緩存中讀取一個字符,而後向發送端發送確認,並將窗口設置1個字節。接着發送端又發來1個字符。接收端發回確認,仍然將窗口設置爲1個字節。這樣下去,網絡效率很是低。
解決方案:接收端等待一段時間,使得緩存已有足夠空間容納;或者緩存已有一半空的空間,再向發送端發送確認。