1. 程式人生 > 其它 >TCP可靠性

TCP可靠性

TCP可靠性

      TCP採用的可靠性技術主要包括差錯控制流量控制擁塞控制

TCP差錯控制

     TCP的差錯控制包括檢測損壞的報文段,失序的報文段、丟失的報文段和重複的報文段,並進行糾正。應用程式將資料流交給TCP後,就依靠TCP將整個資料流按順序且沒有損壞的傳給另一個程式。TCP中的差錯檢測和差錯糾正的方法有校驗和、確認和重傳

1.校驗和

    資料損壞可以通過TCP的校驗和檢測出來。每一個報文段都包括校驗和欄位,用來檢查受損的報文段。若報文段遭到破壞,就由接收方TCP將其丟棄,並且被認為丟失了。

2.確認

     TCP採用確認來證實收到了報文段。控制報文段不攜帶資料,但消耗一個序列號。控制報文段也需要被確認。只有ACK報文段永遠不需要被確認。目前ACK的確認機制最常用的規則有以下幾種。(主要根據報文段中的序列號)

          (1)ACK報文段不需要確認,也不消耗序列號。

       (2)傳送資料時儘量包含(捎帶)確認,給出對方所期望接收的下一個序列號,以減少通訊量。

       (3)如果接收方沒有資料要傳送,並且收到了按序到達的報文段,同時前一個報文段也已經確認了,那麼接收端就推遲傳送確認報文段,直到另一個報文段到達,或再經過了一段時間(通常是500 ms)。

       (4)當具有所期望的序列號的報文段到達時,同時前一個按序到達的報文段還沒有被確認,那麼接收端就要立即傳送ACK報文段。任何時候不能有兩個以上的按序的未被確認的報文段,以避免不必要的重傳而導致網路的擁塞。

      (5)當收到一個序列號比期望序列號還大的報文段時,立即傳送ACK報文段,讓對方快速重傳任何丟失的報文段。

      (6)當收到丟失的報文段,立即傳送ACK報文段,告知對方已經收到了丟失的報文端。

      (7)當收到重複的報文段,立即傳送ACK報文段進行確認。這就解決了ACK報文段丟失所帶來的問題。

3.重傳

       差錯控制機制的核心就是報文段的重傳。當一個報文段損壞、丟失或者被延遲了,就要重傳。目前的TCP實現中,有以下兩種報文段重傳機制。

     1)超時重傳

           TCP為每一個傳送的報文段都設定一個超時重傳(Retransmission Time Out,RTO)計時器。計時器時間一到,就認為相應的報文段損壞或者丟失,需要重傳。注意僅攜帶ACK的報文段不設定超時計時器,因而也就不重傳這種報文段

           在TCP中RTO的值根據報文段的往返時間(Round Trip Time, RTT)動態更新。RTT是一個報文段到達終點和收到對該報文段的確認所需的時間。由於在Internet中傳輸延遲變化範圍很大,因此從發出資料到收到確認所需的往返時間是動態變化的,很難確定。TCP的重傳定時值也要不斷調整,並通過測試連線的往返時間對重傳定時值進行修正。

     2)快重傳

           如果RTO值不是太大,上述超時重傳比較可行。但是,有時一個報文段丟失了,而接收方會收到很多的失序報文段以致無法儲存它們(緩衝區空間有限)。要解決這個問題,現在一般採用三個重複的ACK報文段之後重傳的規則。也就是說,傳送方收到了3個重複的ACK報文段之後,立即重傳這個丟失的報文段。需要注意的是,不消耗序列號的報文段不進行重傳,特別是對ACK段不進行重傳。

4.失序報文段的處置

       當一個報文段推遲到達、丟失或被丟棄,在這個報文段後面的幾個報文段就是失序到達。最初的TCP設計是丟棄所有的失序報文段,這就導致重傳丟失的報文段和後續的一些報文段。現在大多數的實現是不丟棄這些失序的報文段,而是把這些報文段暫時儲存下來,並把它們標誌為失序報文段,直到丟失的報文段到達。注意失序的報文段並不交付到程序。TCP保證資料必須按序交付到程序。

5.重複報文段的處置

      重複的報文段一般是由超時重傳造成的,接收方可以根據序列號判斷是否是重複報文段,對於重複報文段只需要簡單丟棄即可。TCP的確認和重傳技術對每一個報文段都有唯一的序列號,這樣當對方收到了重複的報文段後很容易區分,報文段丟失後也容易定位重傳的報文段的序列號。

TCP流量控制

     TCP在傳輸層上實現端到端的流量控制,為接收方對傳送方傳送資料進行控制,以避免傳送端傳送大量的資料而接收端來不及接收導致接收方癱瘓,這是通過滑動視窗機制來實現的。利用滑動視窗機制可以很方便地在TCP連線上實現對傳送方的流量控制。

1.滑動視窗機制

     在面向連線的傳輸過程中,收發雙方在傳送和接收報文時要協調一致。如果傳送方不考慮對方是否確認,一味地傳送資料,則有可能造成網路擁塞或因接收方來不及處理而丟失資料。如果傳送方每發出一個報文(極端的情況下甚至只發送一個位元組的資料)都要等待對方的確認,則又造成效率低下,網路資源得不到充分利用。為此,TCP採用一種折中的方法,即在緩衝區(暫時存放從應用程字傳出並準備傳送的資料)上使用滑動視窗,TCP傳送資料的多少由這個滑動視窗定義。這樣既能夠保證可靠性,又可以充分利用網路的傳輸能力。

    滑動視窗機制通過傳送方視窗和接收方視窗的配合來完成傳輸控制。傳送方視窗如圖7-30所示。傳送緩衝區中是一組按順序編號的位元組資料,這些資料的一部分在傳送視窗之中,另一部分在傳送視窗之外。傳送緩衝區左端和右端空白處表示可以加入資料的空閒空間,整個緩衝區就是一個左端和右端相連的環。傳送視窗左側是已傳送並被接收方確認的資料,相應的緩衝區部分被釋放。傳送視窗中靠左的部分是已傳送但尚未得到確認的資料,靠右的部分是可以立即傳送的資料,也就是當前可用的視窗。傳送視窗右側是暫時不能傳送的資料,一旦傳送視窗內的部分資料得到確認,視窗便向右滑動,將已確認的資料移到視窗左側空閒空間。傳送視窗右邊界的移動使新的資料又進入到視窗中,成為可以立即傳送的資料。

       接收方視窗反映當前能夠接收的資料的數量,大小取決於接收方處理資料的速度和傳送方傳送資料的速度,當從緩衝區中取出資料的速度低於資料進入緩衝區的速度時,接收視窗逐漸縮小,反之則逐漸擴大。接收方將當前視窗大小通告給傳送方(利用TCP報文段首部的視窗大小欄位),傳送方根據接收視窗調整其傳送視窗,使傳送視窗始終小於或等於接收視窗的大小。只有在接收視窗滑動時(與此同時也傳送了確認),傳送窗口才有可能滑動。收發雙方的視窗按照以上規律不斷地向前滑動,因此這種協議又稱為滑動視窗協議。

       當傳送視窗和接收視窗的大小都等於1時,每傳送一個位元組的資料都要等待對方的確認,這就是停止等待協議。當傳送視窗大於1,接收視窗等於1時,就是回退N步協議。當傳送視窗和接收視窗的大小均大於1時,就是選擇重發協議。協議中規定視窗內未經確認的分組需要重發。這種分組的數量最多可以等於傳送視窗的大小,即滑動視窗的大小n減去1(因為傳送視窗不可能大於(n-1),起碼接收視窗要大於等於1)。

       TCP的視窗以位元組為單位進行調整,以適應接收方的處理能力。處理過程如下。

          (1)TCP連線階段,雙方協商視窗大小,同時接收方預留資料快取區;

          (2)傳送方根據協商的結果,傳送符合視窗大小的資料位元組流,並等待對方的確認;

         ( 3)傳送方根據確認資訊,改變視窗大小,增加或者減少傳送未得到確認的位元組流中的位元組數。如果出現傳送擁塞,傳送視窗縮小為原來的一半,同時將超時重傳的時間間隔擴大一倍。

      在滑動視窗的操作中可能出現一個嚴重的問題,這就是傳送應用程式產生資料很慢,或者接收應用程式消耗資料很慢,或者兩者都有。不管是上述情況中的哪一種,都使得傳送資料的報文很小,這就引起操作效率的降低,這個問題叫做糊塗視窗綜合症(Silly Window Syndrome)。

     2.傳送方產生的糊塗視窗綜合症如果傳送方TCP為生產資料很慢的應用程式服務,就可能產生糊塗視窗綜合症。解決的方法是防止傳送方TCP逐個位元組地傳送資料,強迫傳送方TCP等待,湊成大塊資料再發送。為了使TCP等待的時間更為合理,採用了Nagle演算法,具體解決方法如下。

        (1)傳送方將其從傳送應用程式收到的第一塊資料(即使只有1位元組)傳送出去。

        (2)傳送第1個報文段以後,傳送方TCP就在輸出緩衝區中積累資料並等待,直到或者接收方TCP傳送出確認,或者已積累到足夠的資料可以裝成最大長度的報文段。這時,傳送方TCP就可以傳送這個報文段。

        (3)對剩下的傳輸,重複步驟2。如果收到了對報文段2的確認,或者已積累到足夠的資料可以裝成最大長度的報文段,報文段3就必須傳送出去。採用Nagle演算法,如果應用程式比網路更快,則報文段就較大(最大長度報文段)。若應用程式比網路慢,則報文段就較小(小於最大長度報文段)。

提示:滑動視窗機制為端到端裝置間的資料傳輸提供了可靠的流量控制機制。然而,它只能在源端裝置和目的端裝置起作用,當網路中間裝置(如路由器等)發生擁塞時,滑動視窗機制將不起作用。

TCP擁塞控制

      流量控制是由於接收方不能及時處理資料而引起的控制機制,擁塞是由於網路阻塞引起的嚴重時延現象。擁塞會造成資料的丟失,資料的丟失會引起超時重傳,而超時重傳會進一步的加劇網路阻塞,如果不加以控制,最終會導致系統崩潰。對於擁塞造成的資料損失,僅僅靠超時重傳是無法解決的。為此TCP提供了擁塞控制的機制。傳送方所能傳送的資料量受接收方的控制(流量控制),而且還有有網路的擁塞程度來決定。

      為了避免和消除擁塞,RFC 2581為TCP定義了4種擁塞控制機制,分別是慢啟動(Slow Start)、擁塞避免(Congestion Avoidance)、快重傳(FastRetransmit)和快恢復(Fast Recovery)

1.擁塞視窗

     網路中一個重要的問題就是阻塞。如果網路上的負載超過服務端能夠處理的程度,就會發生網路阻塞。在TCP的擁塞控制中還是傳送串列埠來控制資料流入速度,減緩網路的流入速度,擁塞就會慢慢解除。傳送視窗的大小取決於兩個因素:一個是接收方的處理能力,由確認報文段所通告的大小接收視窗表示;另一個就是網路處理能力,由接收方所傳送的擁塞視窗所決定。傳送視窗的大小最終卻決於接收視窗和擁塞視窗中最小的那個所決定。與接收視窗一樣,擁塞視窗也處於不斷的調整中,一旦發現擁塞,TCP將減小擁塞視窗,進而控制傳送視窗。

2.擁塞策略

      TCP處理擁塞基於3個階段:慢啟動、擁塞避免和擁塞檢測。在慢開始階段,傳送方逐漸增大發送視窗的大小,很快就增大到一個閾值(門限值),當達到閥值時,資料傳送速率的增大就放慢以避免擁塞;最後,如果檢測到擁塞,傳送方就又回到慢啟動或擁塞避免階段。為了避免和消除擁塞,TCP迴圈往復地採用3種策略來控制擁塞視窗的大小。

     傳送方維持一個擁塞視窗 cwnd ( congestion window )的狀態變數。擁塞視窗的大小取決於網路的擁塞程度,並且動態地在變化。傳送方讓自己的傳送視窗等於擁塞視窗。

     傳送方控制擁塞視窗的原則是:只要網路沒有出現擁塞,擁塞視窗就再增大一些,以便把更多的分組傳送出去。但只要網路出現擁塞,擁塞視窗就減小一些,以減少注入到網路中的分組數。

慢開始演算法:

    當主機開始傳送資料時,如果立即所大量資料位元組注入到網路,那麼就有可能引起網路擁塞,因為現在並不清楚網路的負荷情況。因此,較好的方法是 先探測一下,即由小到大逐漸增大發送視窗,也就是說,由小到大逐漸增大擁塞視窗數值。

   通常在剛剛開始傳送報文段時,先把擁塞視窗 cwnd 設定為一個最大報文段MSS的數值。而在每收到一個對新的報文段的確認後,把擁塞視窗增加至多一個MSS的數值。用這樣的方法逐步增大發送方的擁塞視窗 cwnd ,可以使分組注入到網路的速率更加合理。

     每經過一個傳輸輪次,擁塞視窗 cwnd 就加倍。一個傳輸輪次所經歷的時間其實就是往返時間RTT。不過“傳輸輪次”更加強調:把擁塞視窗cwnd所允許傳送的報文段都連續傳送出去,並收到了對已傳送的最後一個位元組的確認。

     另,慢開始的“慢”並不是指cwnd的增長速率慢,而是指在TCP開始傳送報文段時先設定cwnd=1,使得傳送方在開始時只發送一個報文段(目的是試探一下網路的擁塞情況),然後再逐漸增大cwnd。

     為了防止擁塞視窗cwnd增長過大引起網路擁塞,還需要設定一個慢開始門限ssthresh狀態變數。慢開始門限ssthresh的用法如下:

  • 當 cwnd < ssthresh 時,使用上述的慢開始演算法。

  • 當 cwnd > ssthresh 時,停止使用慢開始演算法而改用擁塞避免演算法。

  • 當 cwnd = ssthresh 時,既可使用慢開始演算法,也可使用擁塞控制避免演算法。擁塞避免

擁塞避免

    讓擁塞視窗cwnd緩慢地增大,即每經過一個往返時間RTT就把傳送方的擁塞視窗cwnd加1,而不是加倍。這樣擁塞視窗cwnd按線性規律緩慢增長,比慢開始演算法的擁塞視窗增長速率緩慢得多。

     無論在慢開始階段還是在擁塞避免階段,只要傳送方判斷網路出現擁塞(其根據就是沒有收到確認),就要把慢開始門限ssthresh設定為出現擁塞時的傳送 方視窗值的一半(但不能小於2)。然後把擁塞視窗cwnd重新設定為1,執行慢開始演算法

    這樣做的目的就是要迅速減少主機發送到網路中的分組數,使得發生 擁塞的路由器有足夠時間把佇列中積壓的分組處理完畢。

    如下圖,用具體數值說明了上述擁塞控制的過程。現在傳送視窗的大小和擁塞視窗一樣大。

快重傳和快恢復

快重傳

    快重傳演算法首先要求接收方每收到一個失序的報文段後就立即發出重複確認(為的是使傳送方及早知道有報文段沒有到達對方)而不要等到自己傳送資料時才進行捎帶確認。

      接收方收到了M1和M2後都分別發出了確認。現在假定接收方沒有收到M3但接著收到了M4。

      顯然,接收方不能確認M4,因為M4是收到的失序報文段。根據 可靠傳輸原理,接收方可以什麼都不做,也可以在適當時機發送一次對M2的確認。

    但按照快重傳演算法的規定,接收方應及時傳送對M2的重複確認,這樣做可以讓 傳送方及早知道報文段M3沒有到達接收方。傳送方接著傳送了M5和M6。接收方收到這兩個報文後,也還要再次發出對M2的重複確認。這樣,傳送方共收到了 接收方的四個對M2的確認,其中後三個都是重複確認。

    快重傳演算法還規定,傳送方只要一連收到三個重複確認就應當立即重傳對方尚未收到的報文段M3,而不必 繼續等待M3設定的重傳計時器到期。

    由於傳送方儘早重傳未被確認的報文段,因此採用快重傳後可以使整個網路吞吐量提高約20%。

快恢復

    與快重傳配合使用的還有快恢復演算法,其過程有以下兩個要點:

  • 當傳送方連續收到三個重複確認,就執行“乘法減小”演算法,把慢開始門限ssthresh減半。
  • 與慢開始不同之處是現在不執行慢開始演算法(即擁塞視窗cwnd現在不設定為1),而是把cwnd值設定為 慢開始門限ssthresh減半後的數值,然後開始執行擁塞避免演算法(“加法增大”),使擁塞視窗緩慢地線性增大。