計算機網絡基礎知識總結及思維導圖(五)運輸層

五、運輸層

5.1 基礎概念

1)運輸層通信雙方:主機中的進程。

2)運輸層的兩個主要協議TCP和UDP

  • 用戶數據報協議UDP(User Datagram Protocol):無連接,協議數據單元爲UDP用戶數據報。
  • 傳輸控制協議TCP(Transmission Control Protocol):面向連接,協議數據單元爲TCP報文段。

3)使用UDP和TCP協議的各種應用和應用層協議
Snipaste_2020-01-27_16-15-39
4)運輸層的端口

  • 服務器端使用的端口號
    • 熟知端口號(well-known port number):或系統端口號,數值爲0~1023。IANA把這些端口號指派給了TCP/IP最重要的一些應用程序,讓所有的用戶都知道。
    • 登記端口號:數值爲1024~49151。這類端口號是爲沒有熟知端口號的應用程序使用的。使用這類端口號必須在IANA按照規定的手續登記,以防止重複。
  • 客戶端使用的端口號:數值爲49152~65535。由於這類端口號僅在客戶進程運行時才動態選擇,因此又叫做短暫端口號。

5.2 用戶數據報協議UDP

5.2.1 UDP的特點

1)UDP是無連接的。

2)UDP使用盡最大努力交付,即不保證可靠交付,因此主機不需要維持複雜的連接狀態表。

3)UDP是面向報文的。發送方的UDP對應用程序交下來的報文,在添加首部後就向下交付IP層。UDP對應用層交下來的報文,既不合並,也不拆分,而是保留這些報文的邊界。

4)UDP沒有擁塞控制,因此網絡出現的擁塞不會使源主機的發送速率降低。(適用於一些實時應用)

5)UDP支持一對一、一對多、多對一和多對多的交互通信。

6)UDP的首部開銷小,只有8個字節,比TCP的20個字節的首部要短。

5.2.2 UDP的首部格式

Snipaste_2020-01-27_16-24-40

  • 源端口:源端口號。在需要對方回信時選用。不需要時可用全0。
  • 目的端口:目的端口號。這在終點交付報文時必須使用。
  • 長度:UDP用戶數據報的長度,其最小值是8(僅有首部)。
  • 檢驗和:檢測UDP用戶數據報在傳輸中是否有錯。有錯就丟棄。(檢驗UDP用戶數據報的首部和數據部分,計算方法和計算IP數據報首部檢驗和的方法相似。) 在計算檢驗和時,要在UDP用戶數據報之前增加12個字節的僞首部。僞首部既不向下傳送也不向上遞交,而僅僅是爲了計算檢驗和。

5.3 傳輸控制協議TCP

5.3.1 TCP的特點

1)TCP是面向連接的運輸層協議。

2)每一條TCP連接只能有兩個端點(endpoint),每一條TCP連接只能是點對點的(一對一)。

3)TCP提供可靠交付的服務。通過TCP連接傳送的數據,無差錯、不丟失、不重複,並且按序到達。

4)TCP提供全雙工通信。

5)面向字節流。雖然應用程序和TCP的交互是一次一個數據塊(大小不等),但TCP把應用程序交下來的數據僅僅看成是一連串的無結構的字節流。

5.3.2 TCP報文段的格式

Snipaste_2020-01-27_16-34-26

  • 源端口和目的端口:各佔2個字節,分別寫入源端口號和目的端口號。
  • 序號:佔4字節。序號範圍是[0,23212^{32} –1],共2322^{32}(即4 294 967 296)個序號。在一個TCP連接中傳送的字節流中的每一個字節都按順序編號。首部中的序號字段值則指的是本報文段所發送的數據的第一個字節的序號。
  • 確認號(ack):佔4字節,是期望收到對方下一個報文段的第一個數據字節的序號。
  • 數據偏移:佔4位,它指出TCP報文段的數據起始處距離TCP報文段的起始處有多遠。這個字段實際上是指出TCP報文段的首部長度。(首部長度範圍:20~60字節)
  • 保留:佔6位,保留爲今後使用,但目前應置爲0。
  • 緊急URG(URGent):當URG=1時,表明緊急指針字段有效。它告訴系統此報文段中有緊急數據,應儘快傳送(相當於高優先級的數據),而不要按原來的排隊順序來傳送。與首部中緊急指針(Urgent Pointer)字段配合使用。
  • 確認ACK(ACKnowledgment):僅當ACK=1時確認號字段纔有效。TCP規定,在連接建立後所有傳送的報文段都必須把ACK置1。
  • 推送PSH(PuSH):當兩個應用進程進行交互式的通信時,有時在一端的應用進程希望在鍵入一個命令後立即就能夠收到對方的響應。在這種情況下,TCP就可以使用推送(push)操作。
  • 復位RST(ReSeT):當RST=1時,表明TCP連接中出現嚴重差錯(如由於主機崩潰或其他原因),必須釋放連接,然後再重新建立運輸連接。
  • 同步SYN(SYNchronization):在連接建立時用來同步序號。當SYN=1而ACK=0時,表明這是一個連接請求報文段。對方若同意建立連接,則應在響應的報文段中使SYN=1和ACK=1。因此,SYN置爲1就表示這是一個連接請求或連接接受報文。
  • 終止FIN(FINis):用來釋放一個連接。當FIN=1時,表明此報文段的發送方的數據已發送完畢,並要求釋放運輸連接。
  • 窗口:佔2字節。窗口值是[0,21612^{16} –1]之間的整數。窗口指的是發送本報文段的一方的接收窗口(而不是自己的發送窗口)。窗口值作爲接收方讓發送方設置其發送窗口的依據。
  • 檢驗和:佔2字節。檢驗和字段檢驗的範圍包括首部和數據這兩部分。和UDP用戶數據報一樣,在計算檢驗和時,要在TCP報文段的前面加上12字節的僞首部。
  • 緊急指針:佔2字節。緊急指針僅在URG=1時纔有意義,它指出本報文段中的緊急數據的字節數(緊急數據結束後就是普通數據)。
  • 選項:長度可變,最長可達40字節。當沒有使用“選項”時,TCP的首部長度是20字節。
    • TCP最初只規定了一種選項,最大報文段長度MSS(Maximum Segment Size),即每一個TCP報文段中的數據字段的最大長度。
    • 窗口擴大選項是爲了擴大窗口。
    • 時間戳選項佔10字節,其中最主要的字段是時間戳值字段(4字節)和時間戳回送回答字段(4字節)。一方面用來計算往返時間RTT,另一方面用於處理TCP序號超過2322^{32}的情況,這又稱爲防止序號繞回PAWS(Protect Against Wrapped Sequence numbers)。
    • 選擇確認選項。

5.3.3 TCP的連接

1)TCP連接的端點叫做套接字(socket)或插口。套接字 socket=(IP地址:端口號)。

2)每一條TCP連接唯一地被通信兩端的兩個端點(即兩個套接字)所確定。

3)同一個IP地址可以有多個不同的TCP連接,而同一個端口號也可以出現在多個不同的TCP連接中。


5.4 可靠傳輸的工作原理

5.4.1 停止等待協議

1)停止等待協議是數據鏈路層協議,具有差錯檢測和流量控制功能。

2)“停止等待”就是每發送完一個分組就停止發送,等待對方的確認。在收到確認後再發送下一個分組。

3)超時重傳:發送方只要超過了一段時間仍然沒有收到確認,就認爲剛纔發送的分組丟失了,因而重傳前面發送過的分組。

  • 發送方在發送完一個分組後,必須暫時保留已發送的分組的副本(在發生超時重傳時使用)。只有在收到相應的確認後才能清除暫時保留的分組副本。
  • 分組和確認分組都必須進行編號。這樣才能明確是哪一個發送出去的分組收到了確認,而哪一個分組還沒有收到確認。
  • 超時計時器設置的重傳時間應當比數據在分組傳輸的平均往返時間更長一些。

4)接收方接收重複分組的處理

  • 第一步,丟棄這個重複的分組 ,不向上層交付。
  • 第二步,向發送方發送確認。不能認爲已經發送過確認就不再發送,因爲發送方之所以重傳就表示發送方沒有收到對該分組的確認。

5)停止等待協議的優點是簡單,但缺點是信道利用率太低。

5.4.2 連續ARQ協議

Snipaste_2020-01-27_17-04-25
1)發送方:發送方維持的發送窗口,它的意義是:位於發送窗口內的5個分組都可連續發送出去,而不需要等待對方的確認。這樣,信道利用率就提高了。連續ARQ協議規定,發送方每收到一個確認,就把發送窗口向前滑動一個分組的位置。

2)接收方:一般都是採用累積確認的方式。這就是說,接收方不必對收到的分組逐個發送確認,而是在收到幾個分組後,對按序到達的最後一個分組發送確認。
累積確認優點是容易實現,即使確認丟失也不必重傳。但缺點是不能向發送方反映出接收方已經正確收到的所有分組的信息。


5.5 TCP可靠傳輸的實現

5.5.1 以字節爲單位的滑動窗口

1)TCP的滑動窗口是以字節爲單位的。

2)接收方只能對按序收到的數據中的最高序號給出確認。

3)發送方和接收方都維護有發送緩存、發送窗口和接收緩存和接收窗口。發送方的應用進程把字節流寫入TCP的發送緩存,接收方的應用進程從TCP的接收緩存中讀取字節流。
Snipaste_2020-01-27_17-16-10

  • 發送緩存用來暫時存放:(1)發送應用程序傳送給發送方TCP準備發送的數據;(2)TCP已發送出但尚未收到確認的數據。
  • 接收緩存用來暫時存放:(1)按序到達的、但尚未被接收應用程序讀取的數據;(2)未按序到達的數據。

5.5.2 超時重傳時間的選擇

1)一個報文段發出的時間,以及收到相應的確認的時間。這兩個時間之差就是報文段的往返時間RTT。TCP保留了RTT的一個加權平均往返時間RTTs(這又稱爲平滑的往返時間)。每當第一次測量到RTT樣本時,RTTs值就取爲所測量到的RTT樣本值。但以後每測量到一個新的RTT樣本,就按下式重新計算一次RTTs:

新的RTTs = (1 - α) x (舊的RTTs) + α x (新的RTT樣本)。 已成爲建議標準的RFC 6298推薦的α值爲1/8,即0.125。

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

RTO = RTTs + 4 x RTTDRTT_DRTTDRTT_D是RTT的偏差的加權平均值,它與RTTs和新的RTT樣本之差有關。

3)RFC6298建議這樣計算RTTDRTT_D。當第一次測量時,RTTDRTT_D值取爲測量到的RTT樣本值的一半。在以後的測量中,則使用下式計算加權平均的RTTDRTT_D

新的RTTDRTT_D = (1 - β) x (舊的RTTDRTT_D) + β x |RTTs - 新的RTT樣本|。 這裏β是個小於1的係數,它的推薦值是1/4,即0.25。

5.5.3 選擇確認SACK

若收到的報文段無差錯,只是未按序號,中間還缺少一些序號的數據,那麼可以設法只傳送缺少的數據而不重傳已經正確到達接收方的數據。選擇確認就是一種可行的處理方法。
Snipaste_2020-01-27_18-49-51
上面接收到的字節流序號不連續,接收的字節流左邊界指出字節塊的第一個字節的序號,但右邊界減1纔是字節塊中的最後一個序號。

RFC2018規定,如果要使用選擇確認SACK,那麼在建立TCP連接時,就要在TCP首部的選項中加上“允許SACK”的選項,而雙方必須都事先商定好。

由於首部選項的長度最多隻有40字節,而指明一個邊界就要用掉4字節(因爲序號有32位,需要使用4個字節表示),因此在選項中最多隻能指明4個字節塊的邊界信息。這是因爲4個字節塊共有8個邊界,因而需要用32個字節來描述。另外還需要兩個字節。一個字節用來指明是SACK選項,另一個字節是指明這個選項要佔用多少字節。

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


5.6 TCP的流量控制和擁塞控制

5.6.1 TCP的流量控制

1)流量控制(flow control):就是讓發送方的發送速率不要太快,要讓接收方來得及接收。發送方根據接收方的接受能力(接收方窗口)來發送數據。即發送方的發送窗口不能超過接收方給出的接收窗口的數值

5.6.2 TCP的擁塞控制

1)擁塞控制:就是防止過多的數據注入到網絡中,這樣可以使網絡中的路由器或鏈路不致過載。

2)流量控制和擁塞控制的區別

  • 某些擁塞控制算法是向發送端發送控制報文,並告訴發送端,網絡已出現麻煩,必須放慢發送速率。
  • 流量控制往往是指點對點通信量的控制,是個端到端的問題(接收端控制發送端)。流量控制所要做的就是抑制發送端發送數據的速率,以便使接收端來得及接收。

5.6.3 TCP的擁塞控制方法

1)擁塞窗口cwnd(congestion window):發送方維持一個叫做擁塞窗口的狀態變量。擁塞窗口的大小取決於網絡的擁塞程度,並且動態地在變化。發送方讓自己的發送窗口等於擁塞窗口。

2)判斷網絡擁塞的依據就是出現了超時。

3)擁塞控制方法
Snipaste_2020-01-27_19-23-28

  • 慢開始算法:初始化擁塞窗口cwnd爲1個最大報文段SMSS,慢開始規定,在每收到一個對新的報文段的確認後,把擁塞窗口增加一個SMSS的數值。

    Snipaste_2020-01-27_19-17-20
    使用慢開始算法後,每經過一個傳輸輪次(transmission round),擁塞窗口cwnd就加倍。一個傳輸輪次所經歷的時間其實就是往返時間RTT。如圖中的開始到點1。

    爲了防止擁塞窗口cwnd增長過大引起網絡擁塞,還需要設置一個慢開始門限ssthresh狀態變量。慢開始門限ssthresh的用法如下:
    當cwnd < ssthresh時,使用上述的慢開始算法。
    當cwnd > ssthresh時,停止使用慢開始算法而改用擁塞避免算法。
    當cwnd=ssthresh時,既可使用慢開始算法,也可使用擁塞避免算法。

  • 擁塞避免算法:擁塞避免算法的思路是讓擁塞窗口cwnd緩慢地增大,即每經過一個往返時間RTT就把發送方的擁塞窗口cwnd加1 ,而不是像慢開始階段那樣加倍增長。如圖中的點1到點2。

  • 當網絡出現超時,發送方判斷爲網絡擁塞,於是調整門限值ssthresh=當前擁塞窗口cwnd/2,同時設置擁塞窗口cwnd=1,然後開始執行慢開始算法及擁塞避免算法。如圖中的點2到點4。

  • 快重傳算法:發送方只要一連收到3個重複確認,就知道接收方確實沒有收到報文段,因而應當立即進行重傳(即“快重傳”),這樣就不會出現網絡超時,發送方也不就會誤認爲出現了網絡擁塞。

  • 快恢復算法:在完成快重傳後,發送方調整門限值ssthresh=cwnd/2,同時設置擁塞窗口cwnd=ssthresh,並開始執行擁塞避免算法,如圖中的點4之後。

4)發送方窗口的設置

發送方的窗口的上限值應當取爲接收方窗口rwnd和擁塞窗口cwnd這兩個變量中較小的一個,也就是說:發送方窗口的上限值 = Min[rwnd, cwnd]。

5)全局同步(global syncronization):許多TCP連接在同一時間突然都進入到慢開始狀態。全局同步使得全網的通信量突然下降了很多,而在網絡恢復正常後,其通信量又突然增大很多。解決方法:隨機早期檢測RED(Random Early Detection)。


5.7 TCP的運輸連接管理

5.7.1 TCP的連接建立(三次握手)

TCP建立連接的過程叫做握手,握手需要在客戶和服務器之間交換三個TCP報文段。
Snipaste_2020-01-27_19-48-29
1)一開始,B的TCP服務器進程先創建傳輸控制塊TCB ,準備接受客戶進程的連接請求。然後服務器進程就處於LISTEN(收聽)狀態,等待客戶的連接請求。

2)A的TCP客戶進程也是首先創建傳輸控制模塊TCB。然後,在打算建立TCP連接時,向B發出連接請求報文段,這時首部中的同步位SYN=1,同時選擇一個初始序號seq=x。TCP規定,SYN報文段(即SYN=1的報文段)不能攜帶數據,但要消耗掉一個序號。這時,TCP客戶進程進入SYN-SENT(同步已發送)狀態。

3)B收到連接請求報文段後,如同意建立連接,則向A發送確認。在確認報文段中應把SYN位和ACK位都置1,確認號是ack=x+1,同時也爲自己選擇一個初始序號seq=y。請注意,這個報文段也不能攜帶數據,但同樣要消耗掉一個序號。這時TCP服務器進程進入SYN-RCVD(同步收到)狀態。

4)TCP客戶進程收到B的確認後,還要向B給出確認。確認報文段的ACK置1,確認號ack=y+1,而自己的序號seq=x+1。TCP的標準規定,ACK報文段可以攜帶數據。但如果不攜帶數據則不消耗序號,在這種情況下,下一個數據報文段的序號仍是seq=x+1。這時,TCP連接已經建立,A進入ESTABLISHED(已建立連接)狀態。

5)當B收到A的確認後,也進入ESTABLISHED狀態。

爲什麼有前兩次握手建立了連接,還要第三次握手?

答:這主要是爲了防止已失效的連接請求報文段突然又傳送到了B,因而產生錯誤。

  假設只用前兩次握手建立TCP連接。A發出第一次連接請求,但是這個連接請求報文段在某些網絡結點長時間滯留了(並沒有丟失)。一段時間後,A因爲超時未收到B的確認,於是發出第二次連接請求。第二次連接A收到了B的確認,建立了連接。數據傳輸完畢後,就釋放了連接。

  如果B緊接着收到了第一個失效的連接請求報文段,就誤認爲是A又發出一次新的連接請求。於是就向A發出確認報文段,同意建立連接。因爲沒有第三次握手,那麼只要B發出確認,新的連接就建立了。

  由於現在A並沒有發出建立連接的請求,因此不會理睬B的確認,也不會向B發送數據。但B卻以爲新的運輸連接已經建立了,並一直等待A發來數據。B的許多資源就這樣白白浪費了。

  採用三報文握手的辦法,可以防止上述現象的發生。例如在剛纔的異常情況下,A不會向B的確認發出確認。B由於收不到確認,就知道A並沒有要求建立連接。

5.7.2 TCP的連接釋放

Snipaste_2020-01-27_20-05-35
1)A的應用進程先向其TCP發出連接釋放報文段,並停止再發送數據,主動關閉TCP連接。A把連接釋放報文段首部的終止控制位FIN置1,其序號seq=u,它等於前面已傳送過的數據的最後一個字節的序號加1。這時A進入FIN-WAIT-1(終止等待1)狀態,等待B的確認。請注意,TCP規定,FIN報文段即使不攜帶數據,它也消耗掉一個序號。

2)B收到連接釋放報文段後即發出確認,確認號是ack=u+1,而這個報文段自己的序號是v,等於B前面已傳送過的數據的最後一個字節的序號加1。然後B就進入CLOSE-WAIT(關閉等待)狀態。

3)從A到B這個方向的連接就釋放了,這時的TCP連接處於半關閉(half-close)狀態,即A已經沒有數據要發送了,但B若發送數據,A仍要接收。也就是說,從B到A這個方向的連接並未關閉,這個狀態可能會持續一段時間。

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

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

6)A在收到B的連接釋放報文段後,必須對此發出確認。在確認報文段中把ACK置1,確認號ack=w+1,而自己的序號是seq=u+1(根據TCP標準,前面發送過的FIN報文段要消耗一個序號)。然後進入到TIME-WAIT(時間等待)狀態。

7)請注意,現在A的TCP連接還沒有釋放掉。必須經過時間等待計時器(TIME-WAIT timer)設置的時間2MSL後,A才進入到CLOSED狀態。時間MSL叫做最長報文段壽命(MaximumSegment Lifetime),RFC 793建議設爲2分鐘。但這完全是從工程上來考慮的,對於現在的網絡,MSL=2分鐘可能太長了一些。因此TCP允許不同的實現可根據具體情況使用更小的MSL值。因此,從A進入到TIME-WAIT狀態後,要經過4分鐘才能進入到CLOSED狀態,才能開始建立下一個新的連接。當A撤銷相應的傳輸控制塊TCB後,就結束了這次的TCP連接。

  • 第一,爲了保證A發送的最後一個ACK報文段能夠到達B。
  • 第二,防止上一節提到的“已失效的連接請求報文段”出現在本連接中。

8)B只要收到了A發出的確認,就進入CLOSED狀態。同樣,B在撤銷相應的傳輸控制塊TCB後,就結束了這次的TCP連接。我們注意到,B結束TCP連接的時間要比A早一些。


思維導圖

第五章 運輸層

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章