計算機網路-傳輸層詳解

一、傳輸層的服務基本原理

1.多路複用和解複用(分路)技術

複用是指:發送方的不同的應用進程都可以使用同一個傳輸層協議傳送數據;

分路技術是指:接收方的傳輸層剝去報文首部之後能把這些數據正確的傳輸到正確的應用進程上。

2.可靠數據傳輸


3.流量控制和擁塞控制

二、傳輸層提供的服務

2.1傳輸層尋址和端口

傳輸層主要是提供不同主機上的進程之間的邏輯通信(端到端的通信),即使在不可靠的網絡層(主機之間的邏輯通信)傳輸下,傳輸層也能提供可靠的傳輸。(所謂的邏輯通信就是指:傳輸層之間看似是在水平方向傳送數據,但是事實上這兩個傳輸層之間並沒有水平方向上的物理連接

傳輸層的尋址最重要的就是進程的端口號了。那麼什麼是端口和端口號呢?

端口簡言之就是爲其臨近層的應用層的各個應用進程的數據通過這個“門”向下傳遞給傳輸層,反過來呢就是讓傳輸層知道接受到的報文數據如何正確傳遞交付到對應的應用層上的進程上。

端口號就是用來標識應用進程的數字標識。其端口號的長度爲16Bit;也就是能夠標識2^16個不同的端口號。另外端口號根據端口範圍分爲2類。

1.服務端使用的端口號:1、熟知端口號:0-1023範圍。由IANA(互聯網地址指派機構分配給TCP/IP最重要的一些應用進程,爲固定格式)。2、登記端口號:1024-49151爲沒有熟知端口號的應用程序使用的,需要給IANA註冊登記,防止重複。

常見的熟知端口號:

應用進程 FTP TELNET SMTP DNS TFTP HTTP SNMP
端口號 21  23 25 53 69 80 161

2.客戶端使用的端口號:數值範圍爲49152-65535.也叫作短暫端口號。是在客戶端進程運行成功後動態選擇的。

另外需要注意 是端口號只具有本地意義,即端口號只是標誌本地計算機應用層的各進程。在因特網中,不同的計算機的相同端口號是沒有聯繫的。

補充:套接字(socket)。我們知道在網絡中通過Ip來唯一標識一個主機。而通過端口號來標識一臺主機中的不同應用進程。所以在網絡連接中就出現了Socket套接字來標識一個主機上的某進程。其實際是一個通信端點。

套接字(Socket) = (Host IP , port)

2.2無連接服務和面向連接服務

面向連接和無連接服務的區別在於在通信雙方通信之前,是否需要先建立連接。換句話說就是,通信雙方之間的數據傳輸是否基於雙方需要建立連接。那麼,面向連接就是在雙方通信之前,必須建立連接,在通信過程中,整個連接的過程一直被監控和管理,在通信結束之後,則釋放這個連接。相反,無連接服務是。兩個實體之間的通信不需要建立好連接,需要通信時,直接將信息發送到“網絡”上,讓該信息在網上盡力傳輸到目的方。

在TCP/IP協議簇中,在IP層中使用了這兩種協議服務。其中TCP提供面向連接的可靠的傳輸服務,它不提供廣播和組播機制,包括了確認-重傳機制、流量控制、計時定時器、連接管理等等。這一方面使得TCP連接適用在可靠性高的傳輸場合,如HTTP何FTP、TELNET等 。但是,另一方面呢就是也因此增加了開銷。例如數據報的報頭增大。

UDP協議是非連接的不可靠傳輸機制。它在Ip之上僅提供了多路複用和數據差錯檢查服務。由於UDP服務不需要建立連接,執行速度快,實時性好,只要用於小文件的傳輸協議*(DNS,SNMP,RTP,TFTP)

補充:

1.IP數據報和UDP數據報的區別:IP數據報在網絡層要經過路由的存儲轉發;而UDP數據報是在傳輸層的端到端的邏輯信道中傳輸,而封裝成IP數據報在網絡傳輸中,UDP數據報對於路由是不可見的。

2.TCP和網絡層的虛電路的區別:TCP報文段在傳輸層抽象的邏輯信道中傳輸,對路由器不可見;虛電路所經過的交換節點都必須保存虛電路狀態信息。在網絡層若採用虛電路方式,則無法提供無連接服務;而傳輸層採用TCP協議不影響網絡層提供無連接服務。

三、UDP協議

3.1UDP的首部格式

UDP數據報有兩個部分組成,分爲UDP首部和用戶數據。首部部分有8個字節,4個2字節的字段組成,整個UDP數據報作爲IP數據報的數據部分封裝在IP數據報中。其UDP數據報組成圖解如下:

其中checkSum校驗和表示簡單的校驗和來進行差錯檢測。有錯就丟棄。該字段是可選的。



以下是UDP數據報首部和僞首部(12位,爲了計算檢驗和)和IP數據報的圖解

僞首部僅僅是爲了計算校驗和,而不進行傳送和遞交服務。這樣的校驗和,既檢查了UDP數據報,

又同時對IP數據報的源IP地址和目的IP地址進行了校驗。


四、TCP協議

TCP協議只要解決傳輸的可靠、有序、無丟失和不重複的問題,它主要特點是:

1.是面向連接的傳輸層協議。

2.是端對端的,只能是一對一連接。

3.可靠的交付服務。無差錯、無重複、且有序。

4.面向字節流

4.1、TCP報文報

同樣的,TCP數據報分爲數據首部和TCP數據兩部分。其首部格式圖解:


字段解釋:

  • 來源連接端口(16位長)-辨識發送連接端口
  • 目的連接端口(16位長)-辨識接收連接端口
  • 序列號(seq,32位長)
  • 確認號(ack,32位長) —期望收到的數據的開始序列號。也即已經收到的數據的字節長度加1。 
    • 如果含有同步化旗標(SYN),則此爲最初的序列號;第一個數據比特的序列碼爲本序列號加一。
    • 如果沒有同步化旗標(SYN),則此爲第一個數據比特的序列碼。
  • 報頭長度 —以4字節(如果不這樣根本不夠)爲單位計算出的數據段開始地址的偏移值。
  • 保留 —須置0
  • 標誌符 
    • URG —爲1表示高優先級數據包,緊急指針字段有效。
    • ACK —爲1表示確認號字段有效
    • PSH —爲1表示是帶有 PUSH標誌的數據,指示接收方應該儘快將這個報文段交給應用層而不用等待緩衝區裝滿(很少使用)
    • RST —爲1表示出現嚴重差錯。可能需要重現創建TCP連接。還可以用於拒絕非法的報文段和拒絕連接請求。
    • SYN —爲1表示這是連接請求或是連接接受請求,用於創建連接和使順序號同步
    • FIN —爲1表示發送方沒有數據要傳輸了,要求釋放連接。
  • 窗口(WIN) —表示從確認號開始,本報文的源方可以接收的字節數,即源方接收窗口大小。用於流量控制
  • 校驗和 —對整個的TCP報文段,包括TCP頭部和TCP數據,以16位字進行計算所得。這是一個強制性的字段。
  • 緊急指針 —本報文段中的緊急數據的最後一個字節的序號。
  • 選項字段 —最多40字節。每個選項的開始是1字節的kind字段,說明選項的類型。

序列號:

  • 序列號指的是Segment中第一個字節的編號,而不是Segment的編號
  • 建立TCP連接時,雙方隨機選擇序列號

ACKs:

  • 希望收到的下一個字節的序列號
  • 累積確認:該序列號之前的所有字節均已被正確接收到

五、可靠數據傳輸的基本原理:


可靠數據傳輸的基本結構-接口


3.可靠傳輸協議Rdt版本

3.1、rdt1.0

基本特性:

  • 底層信道完全可靠
  • 不會丟棄分組
有限狀態機Finite State Machine互相獨立

3.2、Rdt2.0(引入差錯控制-接收發送反饋-重傳機制)



下面是Rdt2.0下的有限狀態機的簡圖表示:採用停等協議


我們再看看當通信中無錯誤存在下的有限狀態機FSM的簡圖





下面是有錯誤存在的FSM簡圖


總結:在rdt2.0中我們很好的引入了檢驗和來檢驗差錯,同時引入ACK和NAK進行反饋給發送方,告知接收是否成功,如果不成功發送NAK給sender,sender重傳。但是我們考慮:如果反饋信息ACK和NAK存在錯誤呢?那麼發送方收到的反饋就是錯誤的或者接收不到呢?所以引入rdt2.1


Rdt2.1的sender和rev方對Rdt2.1的有限狀態機表示:

Sender


Receiver2.1

總體來說Rdt2.1相比,具有以下改進:


我們可以發現在Rdt2.1中,我們只是針對ACK進行了檢驗,加入了序列號解決分組重傳重複問題,那麼NAK就不需要了,所以Rdt2.2的做法就是不採用NAK。

我們再考慮到如果傳輸信道極可能發生錯誤嗎,也可能發生分組丟失,那麼Rdt2.2上採用的“序號+檢驗和+ACK+重傳機制就不能實際解決問題了。那麼也就出現了Rdt3.0,引入定時器”


rdt3.0舉例:


六、TCP連接管理:

TCP是面向連接的,所以每一個TCP都會有三個階段狀態:連接建立、數據傳送、連接拆除。連接管理就是使運輸連接的建立和釋放都正常運行。

6.1、TCP的連接建立

典型的“三次握手”:

第一次握手

當客戶端向服務器發起連接請求時,客戶端會發送同步序列標號SYN到服務器,在這裏我們設SYN爲m,等待服務器確認,這時客戶端的狀態爲SYN_SENT。

第二次握手

當服務器收到客戶端發送的SYN後,服務器要做的是確認客戶端發送過來的SYN,在這裏服務器發送確認包ACK,這裏的ACK爲m+1,意思是說“我收到了你發送的SYN了”,同時,服務器也會向客戶端發送一個SYN包,這裏我們設SYN爲n。這時服務器的狀態爲SYN_RECV。在此時,服務器爲該TCP連接分配TCP緩存和變量。服務器資源在此時分配(而客戶端在第三次完成時才分配資源)。記錄了客戶端的請求信息,如果沒有收到來自客戶端的第三次回話,就會在一段時間內緩存TCP信息,這也是黑客攻擊服務器的SYN洪泛攻擊

一句話,服務器端發送SYNACK兩個包。

第三次握手

客戶端收到服務器發送的SYNACK包後,需向服務器發送確認包ACK,“我也收到你發送的SYN了,我這就給你發個確認過去,然後我們即能合體了”,這裏的ACK爲n+1,發送完畢後,客戶端和服務器的狀態爲ESTABLISH,即TCP連接成功。

在三次握手中,客戶端和服務器端都發送兩個包SYNACK,只不過服務器端的兩個包是一次性發過來的,客戶端的兩個包是分兩次發送的

圖解三次握手:



6.2、TCP連接的釋放

典型“四次揮手”

四次揮手

當A端和B端要斷開連接時,需要四次握手,這裏稱爲四次揮手。

斷開連接請求可以由客戶端發出,也可以由服務器端發出,在這裏我們稱A端向B端請求斷開連接。

第一次揮手

A端向B端請求斷開連接時會向B端發送一個帶有FIN標記的報文段,這裏的FINFINish的意思。

第二次揮手

B端收到A發送的FIN後,B段現在可能現在還有數據沒有傳完,所以B端並不會馬上向A端發送FIN,而是先發送一個確認序號ACK,意思是說“你發的斷開連接請求我收到了,但是我現在還有數據沒有發完,請稍等一下唄”。

第三次揮手

當B端的事情忙完了,那麼此時B端就可以斷開連接了,此時B端向A端發送FIN序號,意思是這次可以斷開連接了。

第四次揮手

A端收到B端發送的FIN後,會向B端發送確認ACK,然後經過兩個MSL時長後斷開連接。

MSL是Maximum Segment Lifetime,最大報文段生存時間,2個MSL是報文段發送和接收的最長時間。
四次揮手圖解



TCP連接管理總結:

1、連接建立

  1. 客戶端:syn= 1,seq=x;
  2. 服務端:syn = 1,ACK = 1,seq = y, ack = x+1;
  3. 客戶端:ACK = 1,seq = x+1,ack = y+1;

2、連接釋放

  1. 客戶端:FIN = 1,seq = u;
  2. 服務端:ACK = 1, seq = v,ack = u+1;
  3. 服務端:FIN= 1,ACK = 1,seq  =w,ack = u+1;
  4. 客戶端:ACK= 1,seq = u+1,ack = w+1;

七、TCP的可靠傳輸
TCP提供的可靠傳輸就是要保證接收方從緩存中讀取的字節流和發送方發出點的字節流是完全一致的。TCP使用了校驗和、=序號、確認、重傳機制來得到結果目的。
7.1、序號
TCP首部的序號存在的價值在於讓數據能夠有序的交付給應用層。TCP把數據看成是無結構但是有序的字節流。序號是建立在字節流上的。TCP中的每個數據流的字節都附加上一個序號。序號字段的值是該發送數據的第一個字節的序號。如圖:假設A-B之間建立了一條TCP連接,A的發送緩存區有0-9的十個字節。第一個報文爲0-2;則該報文段的序號爲0;第二報文段序號爲3.


0 1 2 3 4 5 6 7 8 9
7.2、確認號
TCP首部的確認號是期望對方下一次報文段的數據的第一個字節的序號。如上圖所示,如果B成功接收了0-2的第一報文段,則B發送給A的報文中確認號爲3.發送方會繼續存儲那些已經發送,但是未收到確認的報文段,以便需要的時候進行重傳。
TCP你、默認使用的是累計確認。即TCP中只確認數據流中至第一個丟失字節爲止的字節。比如,B收到A發送的包含字節0-2和6-7的報文段。由於某種原因,沒有收到3-5的報文段。此時B仍然在等待字節3和後面的字節。因此,B到A的下一個報文段將確認號置爲3。

7.3、重傳
導致重傳的事件:超時和冗餘ACK.
7.3.1、超時
TCP每發送一個報文段的同時就會啓動該報文段的計時器。只要計時器設置的重傳時間到期但還沒有收到確認時,就重傳該報文段。
TCP採用自適應的算法確認時間RTT(Round-Trip-Time),計算公式爲:
新的RTTs = (1-a)*(舊的RTTs)+a*(新的RTT樣本)          a 的典型取值爲0.125
計時器設置的超時重傳時間RTO(Retransmission Time-Out)時間的取值應該大於加權平均RTT,取值爲RTO  = RTTs +4*RTTd
RTTd是RTT的偏差加權平均值。RTTd = (1-B)*(舊的RTTd)+B*[RTTs-新的RTT樣本]  B = 0.25

7.3.2、冗餘ACK
快速重傳’ 算法:就是在收到對同一個報文段的三次ACK時, 就會迅速的重傳相應的報文段。


八、流量控制
防止發送方使接收方緩存區溢出的可能性。換句話說就是流量控制是一個速度匹配服務(匹配發送方的發送速率和接收方的讀取速率)
流量控制是通過滑動窗口協議的控制原理的,在通信過程中,接收方根據自己的緩存區大小,動態的調整發送方的發送窗口大小,這就是接受窗口rwnd。也就是調整TCP報文段的首部的“窗口”字段值。來限制發送方網絡注入報文的速率。同時,發送方根據當前網絡擁塞程序情況而確定窗口值,成爲擁塞窗口cwnd,其大小與網絡的帶寬和時延密切相關。其實,在發送端的窗口大小是取rwnd和cwnd中的最小值。
利用滑動窗口進行流量控制的圖解:




如上圖所示A向B發送數據。在連接建立時,B告訴A接收窗口rwndreceiver window= 400,單位字節,因此發送方A的發送窗口不能400

(可以看出,B向A發送的三個報文段都設置了 ACK = 1以保證字段有效,後面的rwnd值就是接收方對發送方的三次流量控制。)

第一次把窗口設置爲300 ,第二次100 ,最後一次爲 0,即不允許發送方再發送數據的狀態。

但是當某個ACK報文丟失了,就會出現A等待B確認,並且B等待A發送數據的死鎖狀態。爲了解決這種問題,TCP引入了持續計時器(Persistence timer,當A收到rwnd=0時,就啓用該計時器,時間到了則發送一個1字節的探測報文,詢問B是很忙還是上個ACK丟失了,然後B迴應自身的接收窗口大小,返回仍爲0(A重設持續計時器繼續等待)或者會重發rwnd=x。


九、TCP擁塞控制
所謂的擁塞控制就是防止過多的數據注入到網絡中,這樣可以使網絡中的路由器或鏈路不致於過載。網絡中的鏈路容量、交換結點中的緩存、處理機等等都有着工作的極限,當網絡的需求超過它們的工作極限時,就出現了擁塞。
擁塞控制是一個全局性的過程,和流量控制不同,流量控制指點對點通信量的控制。
因特網建議標準定義了四種算法來進行擁塞控制:慢啓動、擁塞避免、快重傳和快恢復
9.1慢啓動算法
在剛開始啓動TCP連接時,先令擁塞窗口cwnd=1,即最大的報文段長度MSS,每收到一個對新的報文段的確認後,將cwnd加1.用這樣的方法逐步增大發送方的擁塞窗口cwnd,可以使分組注入網絡的效率更高。成指數型增長,直到達到一個閾值後再改用擁塞控制算法

9.2、擁塞避免算法
擁塞控制的做法是:發送端的擁塞窗口cwnd每經過一個往返時延RTT就增加一個MSS的大小。而不是加倍。使cwnd呈現線性增長(即加法增大),而當出現一次超時(網絡擁塞),則讓慢啓動的門限閾值減少爲當前cwnd的一半(乘法減小)。

慢開始算法是指開始發送數據時,並不清楚網絡的負荷情況,會先發送一個1字節的試探報文,當收到確認後,就發送2個字節的報文,繼而4個,8個以此指數類推。

需要注意的是,慢開始的“慢”並不是指擁塞窗口的增長速率慢,而是指在TCP開始發送報文時先設置擁塞窗口=1

擁塞避免算法是讓擁塞窗口緩慢地增大,即cwnd加1,而不是如慢開始算法一樣加倍。



兩種擁塞處理的實例:

根據上圖的實例進行分析,一開始的慢開始算法的指數增長是很恐怖的,所以爲了防止擁塞窗口cwnd增長過快需要設置一個門限ssthresh,這裏是16

(1)當 cwnd < ssthresh 時,使用上述的慢開始算法。

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

(3)當 cwnd = ssthresh 時,既可使用慢開始算法,也可使用擁塞控制避免算法。(通常做法)

無論在慢開始階段還是在擁塞避免階段,只要發送方沒有收到確認,就認爲這時候擁塞了,就要把慢開始門限ssthresh設置爲此時發送方窗口值的一半(上例中是把發送方窗口值24修改爲12)。然後把擁塞窗口cwnd重新設置爲1,執行慢開始算法

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


在慢開始和擁塞避免算法中,使用了“乘法減小”和“加法增大”方法。

其中”乘法減小“是指不論在慢開始還是擁塞避免階段,只要出現一次超時(很有可能出現了擁塞),就把慢啓動的初始閾值調整爲當前擁塞窗口的一半值。當網絡中頻繁出現擁塞時,初始閾值就會下降的很快。以大大減少注入網絡中的分組數。

”加法增大“是指在執行擁塞避免算法後,在收到對所有報文段的確認後(即經過一個RTT),就把擁塞窗口cwnd增加一個MSS大小,使得擁塞窗口緩慢增大,以避免網絡的過早出現擁塞。


9.3 快恢復和快重傳

快重傳是指,如果發送端接收到3個以上的重複ACK,不需要等到重傳定時器溢出就重新傳遞,所以叫做快速重傳,而快速重傳以後,因爲走的不是慢啓動而是擁塞避免算法,所以這又叫做快速恢復算法。

如果沒有快速重傳和快速恢復,TCP將會使用定時器來要求傳輸暫停。在暫停這段時間內,沒有新的數據包被髮送。所以快速重傳和快速恢復旨在快速恢復丟失的數據包

快重傳圖解



快恢復是配合快重傳的


有以下兩個要點:

①當發送方連續收到三個重複確認時,就執行“乘法減小”算法,把ssthresh門限減半。但是接下去並不執行慢開始算法。

②考慮到如果網絡出現擁塞的話就不會收到好幾個重複的確認,所以發送方現在認爲網絡可能沒有出現擁塞。所以此時不執行慢開始算法,而是將cwnd設置爲ssthresh的大小,然後執行擁塞避免算法。
















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