自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

TCP重傳的的兩種方式

網(wǎng)絡(luò) 通信技術(shù)
在 TCP 的正常通信過程中,也會出現(xiàn)錯誤,這種錯誤可能是由于數(shù)據(jù)包丟失引起的,也可能是由于數(shù)據(jù)包重復引起的,甚至可能是由于數(shù)據(jù)包失序引起的。

沒有永遠不出錯誤的通信,這句話表明著不管外部條件多么完備,永遠都會有出錯的可能。所以,在 TCP 的正常通信過程中,也會出現(xiàn)錯誤,這種錯誤可能是由于數(shù)據(jù)包丟失引起的,也可能是由于數(shù)據(jù)包重復引起的,甚至可能是由于數(shù)據(jù)包失序引起的。

[[401946]]

TCP 的通信過程中,會由 TCP 的接收端返回一系列的確認信息來判斷是否出現(xiàn)錯誤,一旦出現(xiàn)丟包等情況,TCP 就會啟動重傳操作,重傳尚未確認的數(shù)據(jù)。

TCP 的重傳有兩種方式,一種是基于時間,一種是基于確認信息,一般通過確認信息要比通過時間更加高效。

所以從這點就可以看出,TCP 的確認和重傳,都是基于數(shù)據(jù)包是否被確認為前提的。

TCP 在發(fā)送數(shù)據(jù)時會設(shè)置一個定時器,如果在定時器指定的時間內(nèi)未收到確認信息,那么就會觸發(fā)相應(yīng)的超時或者基于計時器的重傳操作,計時器超時通常被稱為重傳超時(RTO)。

但是有另外一種不會引起延遲的方式,這就是快速重傳。

TCP 在每次重傳一次報文后,其重傳時間都會加倍,這種"間隔時間加倍"被稱為二進制指數(shù)補償(binary exponential backoff) 。等到間隔時間加倍到 15.5 min 后,客戶端會顯示

  1. Connection closed by foreign host. 

TCP 擁有兩個閾值來決定如何重傳一個報文段,這兩個閾值被定義在 RFC[RCF1122] 中,第一個閾值是 R1,它表示愿意嘗試重傳的次數(shù),閾值 R2 表示 TCP 應(yīng)該放棄連接的時間。R1 和 R2 應(yīng)至少設(shè)為三次重傳和 100 秒放棄 TCP 連接。

這里需要注意下,對連接建立報文 SYN 來說,它的 R2 至少應(yīng)該設(shè)置為 3 分鐘,但是在不同的系統(tǒng)中,R1 和 R2 值的設(shè)置方式也不同。

在 Linux 系統(tǒng)中,R1 和 R2 的值可以通過應(yīng)用程序來設(shè)置,或者是修改 net.ipv4.tcp_retries1 和 net.ipv4.tcp_retries2 的值來設(shè)置。變量值就是重傳次數(shù)。

tcp_retries2 的默認值是 15,這個重試次數(shù)的耗時大約是 13 - 30 分鐘,這只是一個大概值,最終耗時時間還要取決于 RTO ,也就是重傳超時時間。tcp_retries1 的默認值是 3 。

對于 SYN 段來說,net.ipv4.tcp_syn_retries 和 net.ipv4.tcp_synack_retries 這兩個值限制了 SYN 的重傳次數(shù),默認是 5,大約是 180 秒。

Windows 操作系統(tǒng)下也有 R1 和 R2 變量,它們的值被定義在下方的注冊表中

  1. HKLM\System\CurrentControlSet\Services\Tcpip\Parameters 
  2. HKLM\System\CurrentControlSet\Services\Tcpip6\Parameters 

其中有一個非常重要的變量就是 TcpMaxDataRetransmissions,這個 TcpMaxDataRetransmissions 對應(yīng) Linux 中的 tcp_retries2 變量,默認值是 5。這個值的意思表示的是 TCP 在現(xiàn)有連接上未確認數(shù)據(jù)段的次數(shù)。

快速重傳

我們上面提到了快速重傳,實際上快速重傳機制是基于接收端的反饋信息來觸發(fā)的,它并不受重傳計時器的影響。所以與超時重傳相比,快速重傳能夠有效的修復丟包情況。當 TCP 連接的過程中接收端出現(xiàn)亂序的報文(比如 2 - 4 - 3)到達時,TCP 需要立刻生成確認消息,這種確認消息也被稱為重復 ACK。

當失序報文到達時,重復 ACK 要做到立刻返回,不允許延遲發(fā)送,此舉的目的是要告訴發(fā)送方某段報文失序到達了,希望發(fā)送方指出失序報文段的序列號。

還有一種情況也會導致重復 ACK 發(fā)給發(fā)送方,那就是當前報文段的后續(xù)報文發(fā)送至接收端,由此可以判斷當前發(fā)送方的報文段丟失或者延遲到達。因為這兩種情況導致的后果都是接收方?jīng)]有收到報文,但是我們卻無法判斷到底是報文段丟失還是報文段沒有送達。因此 TCP 發(fā)送端會等待一定數(shù)目的重復 ACK 被接受來決定數(shù)據(jù)是否丟失并觸發(fā)快速重傳。一般這個判斷的數(shù)量是 3,這段文字表述可能無法清晰理解,我們舉個例子。

如上圖所示,報文段 1 成功接收并被確認為 ACK 2,接收端的期待序號為 2,當報文段 2 丟失后,報文段 3。失序到達,但是與接收端的期望不匹配,所以接收端會重復發(fā)送冗余 ACK 2。

這樣,在超時重傳定時器到期之前,接收收到連續(xù)三個相同的 ACK 后,發(fā)送端就知道哪個報文段丟失了,于是發(fā)送方會重發(fā)這個丟失的報文段,這樣就不用等待重傳定時器的到期,大大提高了效率。

SACK

在標準的 TCP 確認機制中,如果發(fā)送方發(fā)送了 0 - 10000 序號之間的數(shù)據(jù),但是接收方只接收到了 0 -1000, 3000 - 10000 之間的數(shù)據(jù),而 1000 - 3000 之間的數(shù)據(jù)沒有到達接收端,此時發(fā)送方會重傳 1000 - 10000 之間的數(shù)據(jù),實際上這是沒有必要的,因為 3000 后面的數(shù)據(jù)已經(jīng)被接收了。但是發(fā)送方無法感知這種情況的存在。

如何避免或者說解決這種問題呢?

為了優(yōu)化這種情況,我們有必要讓客戶端知道更多的消息,在 TCP 報文段中,有一個 SACK 選項字段,這個字段是一種選擇性確認(selective acknowledgment)機制,這個機制能告訴 TCP 客戶端,用我們的俗語來解釋就是:“我這里最多允許接收 1000 之后的報文段,但是我卻收到了 3000 - 10000 的報文段,請給我 1000 - 3000 之間的報文段”。

但是,這個選擇性確認機制的是否開啟還受一個字段的影響,這個字段就是 SACK 允許選項字段,通信雙方在 SYN 段或者 SYN + ACK 段中添加 SACK 允許選項字段來通知對端主機是否支持 SACK,如果雙方都支持的話,后續(xù)在 SYN 段中就可以使用 SACK 選項了。

這里需要注意下:SACK 選項字段只能出現(xiàn)在 SYN 段中。

偽超時和重傳

在某些情況下,即使沒有出現(xiàn)報文段的丟失也可能會引發(fā)報文重傳。這種重傳行為被稱為偽重傳(spurious retransmission) ,這種重傳是沒有必要的,造成這種情況的因素可能是由于偽超時(spurious timeout),偽超時的意思就是過早的判定超時發(fā)生。造成偽超時的因素有很多,比如報文段失序到達,報文段重復,ACK 丟失等情況。

檢測和處理偽超時的方法有很多,這些方法統(tǒng)稱為檢測算法和響應(yīng)算法。檢測算法用于判斷是否出現(xiàn)了超時現(xiàn)象或出現(xiàn)了計時器的重傳現(xiàn)象。一旦出現(xiàn)了超時或者重傳的情況,就會執(zhí)行響應(yīng)算法撤銷或者減輕超時帶來的影響,下面是幾種算法,此篇文章暫不深入這些實現(xiàn)細節(jié):

  • 重復 SACK 擴展- DSACK
  • Eifel 檢測算法
  • 前移 RTO 恢復 - F-RTO
  • Eifel 響應(yīng)算法

包失序和包重復

上面我們討論的都是 TCP 如何處理丟包的問題,我們下面來討論一下包失序和包重復的問題。

包失序

數(shù)據(jù)包的失序到達是互聯(lián)網(wǎng)中極其容易出現(xiàn)的一種情況,由于 IP 層并不能保證數(shù)據(jù)包的有序性,每個數(shù)據(jù)包的發(fā)送都可能會選擇當前情況傳輸速度最快的鏈路,所以很有可能出現(xiàn)發(fā)送了 A - > B -> C 的三個數(shù)據(jù)包,到達接收端的數(shù)據(jù)包順序是 C -> A -> B 或者 B -> C -> A 等等。這就是包失序的一種現(xiàn)象。

在包傳輸中,主要分為兩種鏈路:正向鏈路(SYN)和反向鏈路(ACK)。

如果失序發(fā)生在正向鏈路,TCP 是無法正確判斷數(shù)據(jù)包是否丟失的,數(shù)據(jù)的丟失和失序都會導致接收端收到無序的數(shù)據(jù)包,造成數(shù)據(jù)之間的空缺。如果這種空缺不夠大的話,這種情況影響不大;但是如果空缺比較大的話,可能會導致偽重傳。

如果失序發(fā)生在反向鏈路,就會使 TCP 的窗口前移,然后收到重復而應(yīng)該被丟棄的 ACK,導致發(fā)送端出現(xiàn)不必要的流量突發(fā),影響可用網(wǎng)絡(luò)帶寬。

回到我們上面討論的快速重傳,由于快速重傳是根據(jù)重復 ACK 推斷出現(xiàn)丟包而啟動的,它不用等到重傳計時器超時。由于 TCP 接收端會對接收到的失序報文立刻返回 ACK,所以網(wǎng)絡(luò)中任何一個失序到達的報文都可能會造成重復 ACK。假設(shè)一旦收到 ACK,就會啟動快速重傳機制,當 ACK 數(shù)量激增,就會導致大量不必要的重傳發(fā)生,所以快速重傳應(yīng)該達到重復閾值(dupthresh)再觸發(fā)。但是在互聯(lián)網(wǎng)中,嚴重的失序并不常見,因此 dupthresh 的值可以設(shè)置的盡量小,一般來說 3 就能處理絕大部分情況。

包重復

包重復也是互聯(lián)網(wǎng)中出現(xiàn)很少的一種情況,它指的是在網(wǎng)絡(luò)傳輸過程中,包可能會出現(xiàn)傳輸多次的情況,當重傳生成時,TCP 可能會出現(xiàn)混淆。

包的重復可以使接收端生成一系列的重復 ACK,這種情況可以使用 SACK 協(xié)商來解決。 

 

責任編輯:趙寧寧 來源: 程序員cxuan
相關(guān)推薦

2009-06-25 13:43:00

Buffalo AJA

2010-10-21 16:24:18

sql server升

2010-08-06 09:38:11

Flex讀取XML

2023-03-29 13:06:36

2011-03-03 10:26:04

Pureftpd

2010-07-27 15:03:37

Flex ArrayC

2010-05-10 18:19:00

負載平衡技術(shù)

2011-03-23 11:22:14

oracle dbli

2024-09-20 11:32:28

.NET內(nèi)存管理

2010-07-14 10:30:26

Perl多線程

2011-04-02 09:48:38

深拷貝

2016-11-07 09:02:02

Malloc內(nèi)存syscall

2011-06-16 10:02:08

JAVA靜態(tài)載入

2010-07-15 14:38:55

Perl eval函數(shù)

2009-09-08 15:22:20

Spring依賴注入

2010-08-03 13:27:04

FlexBuilder

2024-02-04 09:24:45

MyBatisSQL語句Spring

2010-10-20 15:48:56

SQL Server許

2021-12-08 10:47:35

RabbitMQ 實現(xiàn)延遲

2010-09-07 11:09:59

點贊
收藏

51CTO技術(shù)棧公眾號