1. 程式人生 > >計算機網路第5章 運輸層(下)

計算機網路第5章 運輸層(下)

《計算機網路(第七版)-謝希仁》 第5章 運輸層(下)

TCP協議 相關內容詳細介紹

TCP可靠傳輸的實現

假定資料傳輸只在一個方向進行

以位元組為單位的滑動視窗

傳送視窗表示:在沒有收到B的確認的情況下,A 可以連續把視窗內的資料都發送出去。凡是已經發送過的資料,在未收到確認之前都必須暫時保留,以便在超時重傳時使用。

傳送視窗後沿的變化情況有兩種可能,即不動(沒有收到新的確認)和前移(收到了新的確認)。

這裡寫圖片描述

  • 第一,雖然A的傳送視窗是根據B的接收視窗設定的,但在同一時刻,A的傳送視窗並不總是和B的接收視窗一樣大,時間滯後和擁塞

  • 第二,對於不按序到達的資料應如何處理,TCP標準並無明確規定。

    通常對不按序到達的資料是先臨時存 放在接收視窗中,等到位元組流中所缺少的位元組收到後,再按序交付上層的應用程序。

  • 第三,TCP要求接收方必須有累積確認的功能,這樣可以減小傳輸開銷。TCP標準規定,確認推遲的時間不應超過0.5秒。

超時重傳時間的選擇

TCP採用了一種自適應演算法設定超時重傳時間。

TCP採用了一種自適應演算法,它記錄一個報文段發出的時間,以及收到相應的確認的時間。這兩個時間之差就是報文段的往返時間RTT。TCP保留了 RTT的一個加權平均往返時間RTT~S~ (這又稱為平滑的往返時間,S表示Smoothed。因為進行的是加權平均,因此得出的結果更加平滑)。每當第一次測量到RTT樣本時,RTT~S~值就取為所測量到的RTT樣本值。但以後每測量到一個新的RTT樣本,就按下式重新計算一次RTT~S~ :

己成為建議標準的RFC 6298推薦 的a值為1/8,即0.125

超時計時器設定的超時重傳時間RTO (RetransmissionTime-Out)應略大於上面得 出的加權平均往返時間RTTs。RFC 6298建議使用下式計算RTO:

RTT~D~是RTT的偏差的加權平均值,它與RTTS和新的RTT樣本之差有關。RFC 6298建議這樣計算RTT~D~。當第一次測量時,RTT~D~值取為測量到的RTT樣本值的一半。在 以後的測量中,則使用下式計算加權平均的RTT~D~:

這裡β是個小於1的係數,它的推薦值是1/4,即0.25。

Kam提出了一個演算法:在計算加權平均RTTS時,只要報文段重傳 了,就不採用其往返時間樣本。這樣得出的加權平均RTTS和RTO就較準確。

對Kam演算法進行修正。方法是:報文段每重傳一次,就把超時重傳時間RTO增 大一些。典型的做法是取新的重傳時間為舊的重傳時間的2倍。當不再發生報文段的重傳時,才根據上面給出的公式計算超時重傳時間。

選擇確認SACK

若收到的報文段無差錯,只是未按序號,中間還缺少一些序號的資料,只傳送缺少的資料而不重傳已經正確到達接收方的數 據選擇確認就是一種可行的處理方法。

TCP的首部沒有哪個欄位能夠提供上述這些位元組塊的邊界資訊。RFC 2018 規定,如果要使用選擇確認SACK,那麼在建立TCP連線時,就要在TCP首部的選項中加 上“允許SACK”的選項,而雙方必須都事先商定好。

SACK文件並沒有指明發送方應當怎樣響應SACK。因此大多數的實現還是重傳所有未被確認的資料塊。

TCP的流量控制

利用滑動視窗實現流量控制

所謂流量控制(flow control)就是讓傳送方的傳送速率不要太快,要讓接收方來得及接收。

設A向B傳送資料。在連線建立時,B告訴了 A: “我的接收視窗 rwnd = 400”(這裡 rwnd表示receiver window)。因此,傳送方的傳送視窗不能超過接收方給出的接收視窗的數值。請注意,TCP的視窗單位是位元組,不是報文段。

圖中箭頭上面大寫ACK表示首部中的確認位ACK,小寫ack表示確認欄位的值。

TCP為每一個連線設有一個持續計時器(persistence timer)。只要TCP連線的一方收到對方的零視窗通知,就啟動持續計時器。若持續計時器設定的時間到期,就傳送一個零視窗探測報文段(僅攜帶1位元組的資料),而對方就在確認這個探測報文段時給出了現在的視窗值。如果視窗仍然是零,那麼收到這個報文段的一方就重新設定持續計時器。

TCP的傳輸效率

控制TCP報文段的傳送機制

  • 第一種機制是TCP維持一個變數,它等於最大報文段長度MSS。只要快取中存放的資料達到MSS位元組時,就組裝成一個TCP報文段傳送出去。
  • 第二種機制是由傳送方的應用程序指明要求傳送報文段,即TCP支援的推送(push)操作。
  • 第三種機制是傳送方的一個計時器期限到了,這時就把當前己有的快取資料裝入報文段(但長度不能超過MSS)傳送出去。

Nagle演算法

若傳送應用程序把要傳送的資料逐個位元組地送到TCP的傳送快取,則傳送方就把第一個資料位元組先發送出去,把後面到達的資料位元組都快取起來。

當傳送方收到對第一個資料字元的確認後,再把傳送快取中的所有資料組裝成一個報文段傳送出去,同時繼續對隨後到達的資料進行快取。

只有在收到對前一個報文段的確認後才繼續傳送下一個報文段。

當資料到達較快而網路速率較慢時,用這樣的方法可明顯地減少所用的網路頻寬。

Nagle演算法還規定,當到達的資料己達到傳送視窗大小的一半或己達到報文段的最大長度時,就立即傳送一個報文段。這樣做,就可以有效地提高網路的吞吐量。

糊塗視窗綜合徵(silly window syndrome)

要解決這個問題,可以讓接收方等待一段時間,使得或者接收快取已有足夠空間容納一個最長的報文段,或者等到接收快取已有一半空閒的空間。只要出現這兩種情況之一,接收方就發出確認報文,並向傳送方通知當前的視窗大小。此外,傳送方也不要傳送太小的報文段,而是把資料積累成足夠大的報文段,或達到接收方快取的空間的一半大小。

TCP的擁塞控制

擁塞(congestion)

擁塞控制:防止過多的資料注入到網路中,這樣可以使網路中的路由器或鏈路不致過載。

擁塞控制所要做的都有一個前提,就是網路能夠承受現有的網路負荷。

擁塞控制是一個全域性性的過程,涉及到所有的主機、所有的路由器,以及與降低網路傳輸效能有關的所有因素。

流量控制往往是指點對點通訊量的控制,是個端到端的問題(接收端控制傳送端)。流量控制所要做的就是抑制傳送端傳送資料的速率,以便使接收端來得及接收。

TCP的擁塞控制方法

慢開始(slow-start)、擁塞避免(congestion avoidance)、快重傳(fast retransmit)和快恢復(fast recovery)

慢開始和擁塞避免

下面討論的擁塞控制也叫做基於視窗的擁塞控制。為此,傳送方維持一個叫做擁塞視窗cwnd (congestion window)的狀態變數。擁塞視窗的大小取決於網路的擁塞程度,並且動態地在變化。傳送方讓自己的傳送視窗等於擁塞視窗

傳送方控制擁塞視窗的原則是:只要沒有出現擁塞,擁塞視窗就變大一些,只要出現了擁塞,擁塞視窗就小一些。

判斷網路擁塞的依據就是出現了超時

慢開始演算法:由小到大逐漸增大擁塞視窗數值。

限制初始擁塞視窗的位元組數的規則:

  • 若 SMSS>2190 位元組,則設定初始擁塞視窗cwnd = 2 x SMSS位元組,且不得超過2個報文段。
  • 若(SMSS> 1095 位元組)且(SMSSS2190 位元組),則設定初始擁塞視窗 cwnd = 3 x SMSS位元組,且不得超過3個報文段。
  • 若 SMSS<=1095 位元組,則設定初始擁塞視窗 cwnd = 4 x SMSS位元組,且不得超過4個報文段。

慢開始規定,在每收到一個對新的報文段的確認後,可以把擁塞視窗增加最多一個SMSS的數值

使用慢開始演算法後,每經過一個傳輸輪次(transmission round),擁塞視窗cwnd就加倍。

在TCP的實際執行中,傳送方只要收到一個對新報文段的確認,其擁塞視窗cwnd就立即加1,並可以立即傳送新的報文段,而不需要等這個輪次中所有的確認都收到後(如圖5-24所示的那樣)再發送新的報文段。

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

  • 當cwnd

快重傳和快恢復

快重傳演算法可以讓傳送方儘早知道發生了個別報文段的丟失。

快重傳演算法首先要求接收方不要等待自己傳送資料時才進行捎帶確認,而是要立即傳送確認,即使收到了失序的報文段也要立即發出對己收到的報文段的重複確認。

快重傳

如圖所示,接收方沒有收到M3但卻收到了 M4。按照快重傳演算法,接收方必須立即傳送對M2的重複確認,以便讓傳送方及早知道接收方沒有收到報文段M3。傳送方接著傳送M5和M6。接收方收到後也仍要再次分別發出對M2的重複確認。這樣,傳送方共收到了接收方的4個對M2的確認,其中後3個都是重複確認。

快重傳演算法規定,傳送方只要一連收到3個重複確認,就知道接收方確實沒有收到報文段M3,因而應當立即進行重傳(即“快重傳”),這樣就不會出現超時,傳送方也不就會誤認為出現了網路擁塞。使用快重傳可以使整個網路的吞吐量提高約20%。

因此,在圖5-25中的點❹,傳送方知道現在只是丟失了個別的報文段。於是不啟動慢開始,而是執行快恢復演算法。這是傳送發調整門限值ssthresh = cwnd / 2 = 8,同時設定擁塞視窗 cwnd = ssthresh = 8 (見圖5-25中的點❺),並開始執行擁塞避免演算法。

請注意,也有的快恢復實現是把快恢復開始時的擁塞視窗cwnd值再增大一些(增大3 個報文段的長度),即等於新的ssthresh + 3 x MSS。這樣做的理由是:既然傳送方收到3個重複的確認,就表明有3個分組已經離開了網路。

在擁塞避免階段,擁塞視窗是按照線性規律增大的,這常稱為加法增大AI (Additive Increase)。而一旦出現超時或3個重複的確認,就要把門限值設定為當前擁塞視窗值的一半,並大大減小擁塞視窗的數值。這常稱為“乘法減小” MD(Multiplicative Decrease)。二者合在一起就是所謂的AIMD演算法。

接收方視窗 rwnd 和擁塞視窗 cwnd

主動佇列管理AQM

AQM實際上就是對路由器中的分組排隊進行智慧管理,而不是簡單地把佇列的尾部丟棄。

TCP的運輸連線管理

運輸連線就有三個階段:連線建立、資料傳送和連線釋放

TCP的連線建立

上面給出的連線建立過程叫做三報文握手。

在圖中B傳送給A的報文段,也可拆成兩個報文段。可以先發送一個確認報文段(ACK = 1,ack = x + 1),然後再發送一個同步報文段(SYN=l,seq = y)。這樣的過程就變成了四報文握手。

TCP的連線釋放

資料傳輸結束後,通訊的雙方都可釋放連線。現在A和B都處於ESTABLISHED狀態 。A的應用程序先向其TCP發出連線釋放報文段,並停止再發送資料,主動關閉TCP連線。A把連線釋放報文段首部的終止控制位FIN置1,其序號seq = u,它等於前面己傳送過的資料的最後一個位元組的序號加1。這時A進入FIN-WAIT-1 (終止等待1)狀態,等待B的確認。請注意,TCP規定,FIN報文段即使不攜帶資料,它也消耗掉一個序號。

TCP連線釋放

B收到連線釋放報文段後即發出確認,確認號是ack = u+1,而這個報文段自己的序號是v,等於B前面已傳送過的資料的最後一個位元組的序號加1。然後B就進入CLOSE- WAIT (關閉等待)狀態。TCP 伺服器程序這時應通知高層應用程序,因而從A到B這個方向的連線就釋放了,這時的TCP連線處於半關閉(half-dose)狀態,即A己經沒有資料要傳送了,但B若傳送資料,A仍要接收。也就是說,從B到A這個方向的連線並未關閉,這個狀態可能會持續一段時間。

A收到來自B的確認後,就進入FIN-WAIT-2 (終止等待2)狀態,等待B發出的連線釋放報文段。

若B己經沒有要向A傳送的資料,其應用程序就通知TCP釋放連線。這時B發出的連線釋放報文段必須使FIN = 1。現假定B的序號為w (在半關閉狀態B可能又傳送了一些資料)。B還必須重複上次己傳送過的確認號ack = u+ 1。這時B就進入LAST-ACK (最後確認)狀態,等待A的確認。

A在收到B的連線釋放報文段後,必須對此發出確認。在確認報文段中把ACK置1,確認號ack = w+l,而自己的序號是seq = u+l (根據TCP標準,前面傳送過的FIN報文段要消耗一個序號)。然後進入到TIME-WAIT (時間等待)狀態。請注意,現在TCP連線還沒有釋放掉。必須經過時間等待計時器(TIME-WAIT timer)設定的時間2MSL後,A才進入到CLOSED狀態。時間MSL叫做最長報文段壽命(Maximum Segment Lifetime)。

除時間等待計時器外,TCP還設有一個保活計時器(keepalive timer)。客戶己主動與伺服器建立了TCP連線。但後來客戶端的主機突然出故障。伺服器每收到一次客戶的資料,就重新設定保活計時器,時間的設定通常是兩小時。若兩小時沒有收到客戶的資料,伺服器就傳送一個探測報文段,以後則每隔75秒鐘傳送一次。若一連發送10個探測報文段後仍無客戶的響應,伺服器就認為客戶端出 了故障,接著就關閉這個連線。

TCP的有限狀態機