1- 運輸層概述
1.1 基本概念
1.2 進程之間的通信
- 從通信和信息處理的角度看,運輸層向它上面的應用層提供通信服務,它屬於面向通信部分的最高層,同時也是用戶功能中的最低層。
- 當網絡的邊緣部分中的兩個主機使用網絡的核心部分的功能進行端到端的通信時,只有位於網絡邊緣部分的主機的協議棧才有運輸層,而網絡核心部分中的路由器在轉發分組時都只用到三層(到網絡層)的功能。
1.3 進程之間通信流程
局域網1上的主機與局域網2上的主機,通過互連的廣域網進行通信,網絡層的作用范圍是主機到主機。
提供直接的通信服務是運輸層的任務。運輸層協議又稱為端到端協議,運輸層的作用范圍是應用進程到應用進程也稱為端到端。
步驟分析
“邏輯通信”是指運輸層之間的通信好像是沿水平方向傳送數據,但事實上,這兩條數據並沒有一條水平方向的物理連接,要傳送的數據是沿着圖中上下多次的虛線方向傳送的。
進程Ap1與Ap4之間進行基於網絡的通信,進程Ap2與Ap3之間進行基於網絡的通信,在運輸層使用不同的端口,來對應不同的應用進程,然后通過網絡層及其下層來傳輸應用層報文。
接收方的運輸層通過不同的端口,將收到的應用層報文,交付給應用層中相應的應用進程,這里端口並不是指看得見、摸得着的物理端口,而是指用來區分不同應用進程的標識符。
1.4 概念總結
2- 運輸層端口號、復用與分用
2.1 為啥使用端口號
2.2 發送方的復用和接收方的分用
UDP復用
這是收發雙方的應用進程,發送方的某些應用進程所發送的不同應用報文,在運輸層使用UDP協議進行封裝,這稱為UDP復用。
TCP復用
另一些應用進程所發送的不同應用報文,在運輸層使用TCP協議進行封裝,這稱為TCP復用。
IP復用
運輸層使用端口號來區分不同的應用進程,不管是使用運輸層的UDP協議封裝成的UDP用戶數據報,還是使用TCP協議封裝成的TCP報文段,在網絡層都需要使用IP協議封裝成IP數據報
發送方
IP數據報首部中的協議字段的值,用來表明IP數據報的數據載荷部分,封裝的是何種協議數據單元,取值為6。表示封裝的是TCP報文段,取值為17,表示封裝的是UDP用戶數據報。
接收方
接收方的網絡層收到IP數據報后進行IP分用,若IP數據報首部中協議字段的值為17,則把IP數據報的數據的數據載荷部分所封裝的UDP用戶數據報,上交運輸層的UDP。若協議字段的值為6,則把IP數據報的數據載荷部分所封裝的TCP報文段,上交運輸層的TCP。運輸層對UDP用戶數據報進行UDP分用,對TCP報文段進行TCP分用,也就是根據端口號,將它們交付給上層相應的應用進程。
2.3 運輸層熟知端口號
不管在運輸層使用UDP還是TCP協議,在網絡層都需要使用IP協議,IP數據報首部中協議字段的值,表明了IP數據報數據載荷部分,封裝的是何種協議數據單元。
3- 運輸層傳輸流程
3.1 步驟一
通過實例來說明運輸層端口號的作用
用戶PC、DNS服務器、WEB服務器通過交換機進行互聯,它們處於同一個以太網中。DNS服務器中的記錄有該域名所對應的IP地址。我們在用戶PC中使用網頁瀏覽器來訪問Web服務器的內容,在網頁瀏覽器的地址欄中輸入Web服務器的域名。用戶PC中的DNS客戶端進程會發送一個DNS查詢請求報文,其內容為"域名www.porttest.com所對應的IP地址是什么?"
DNS查詢請求報文需要使用運輸層的UDP協議,封裝成UDP用戶數據報,其首部中的源端口字段的值,在短暫端口號(49151~65535)中挑選一個未被占用的,用來表示DNS客戶端進程,例如49152。目的端口字段的值設置為53,這是DNS服務端進程所使用的熟知端口號。
3.2 步驟二
將UDP用戶數據報封裝在IP數據報中,通過以太網發送給DNS服務器,DNS服務器收到該數據報后。
3.3 步驟三
從中解封出UDP用戶數據報,UDP首部中的目的端口號為53,這表明應將該UDP用戶數據報的數據載荷部分,也就是DNS查找請求報文交付給本服務器中的DNS服務器端進程,DNS服務器端進程解析DNS查詢請求報文的內容,然后按其要求查找對應的IP地址。
之后,會給用戶PC發送DNS響應報文,其內容為"域名www.porttest.comsu所對應的IP地址是192.168.0.3"。DNS響應報文需要使用運輸層的UDP協議,封裝成UDP用戶數據報,其首部中的源端口字段的值設置為熟知端口號53,表明這是DNS服務器端進程所發送的UDP用戶數據報,目的端口字段的值設置為49152,這是之前用戶PC中發送DNS查詢請求報文的DNS客戶端進程所使用的短暫端口號。之后,將UDP用戶數據報封裝在IP數據報中的通過以太網發送給用戶PC。
3.4 步驟四
之后,將UDP用戶數據報封裝在IP數據報中通過以太網發送給用戶PC。用戶PC收到該數據報后,從中解封出UDP用戶數據報。UDP首部中的目的端口號為49152,這表明應將該UDP用戶數據報的數據載荷部分也就是DNS響應報文,交付給用戶PC中的DNS客戶端進程。DNS客戶端進程解析DNS響應報文的內容,就可知道自己之前的所請求的Web服務器的域名,所對應的IP地址為192.168.0.3。
3.5 步驟五
現在,用戶PC中的HTTP客戶端進程,可以向Web服務器發送HTTP請求報文,其內容為"首頁內容是什么?"HTTP請求報文需要使用運輸層的TCP協議封裝成TCP報文段,其首部中的源端口字段的值,在短暫端口號49151~65535中挑選一個未被占用的,用來表示HTTP客戶端進程,例如仍然使用之前用過的49152。目的端口字段的值設置為80,這是HTTP服務器進程所使用的熟知端口號。
3.6 步驟六
之后,將TCP報文段封裝在IP數據報中,通過以太網發送給Web服務器。Web服務器收到該數據報后,從中解封出TCP報文段。TCP首部中的目的端口號為80,這表明應該將TCP報文段的數據載荷部分也就是HTTP請求報文,交付給本服務器中的HTTP服務器端進程,HTTP服務器端進程解析HTTP請求報文的內容,然后按其要求查找首頁內容。
3.7 步驟六
之后,會給用戶PC發送HTTP響應報文,其內容是HTTP客戶端所請求的首頁內容,HTTP響應報文需要使用運輸層的TCP協議封裝成TCP報文段,其首部中的源端字段的值設置為熟知端口號80。表明這是HTTP服務器端進程所發送的TCP報文段,目的端口字段的值設置為49152,這是之前用戶PC中,發送HTTP請求報文HTTP客戶端進程所使用的短暫端口號。
3.8 步驟七
之后,將TCP報文段封裝在IP數據報中,通過以太網發送給用戶PC,用戶PC收到該數據報后,從中解封出TCP報文段。TCP首部中的目的端口號為49152,這表明應將該TCP報文段的數據載荷部分,也就是HTTP響應報文,交付給用戶PC中的HTTP客戶端進程。
HTTP客戶端進程解析HTTP響應報文的內容,並在網頁瀏覽器中進行顯示,這樣我們就可以在網頁瀏覽器中,看到Web服務器所提供的首頁內容。
4-UDP和TCP的對比
4.1基本概念
- UDP 和 TCP是TCP/IP體系結構運輸層中的兩個重要協議。
- 當運輸層采用面向連接的 TCP協議時,盡管下面的網絡是不可靠的,但這種邏輯通信信道就相當於一條全雙工的可靠信道。
- 當運輸層采用無連接的 UDP協議時,這種邏輯通信信道是一條不可靠信道。
兩個對等運輸實體在通信時傳送的數據單位叫作運輸協議數據單元 TPDU。
TCP 傳送的數據單位協議是 TCP 報文段,UDP 傳送的數據單位協議是 UDP 報文或用戶數據報。
UDP特點
無連接的協議,提供無連接服務。其傳送的運輸協議數據單元TPDU是UDP報文或者用戶數據報。
支持單播,多播、廣播,不提供可靠交付。簡單適用於很多應用,如多媒體應用等。
UDP的通信是無連接的,不需要套接字(Socket)。
TCP特點
面向連接的協議,提供面向連接服務。其傳送的運輸協議數據單元TPDU是TCP報文。
支持點對點單播,不支持多播、廣播、提供可靠服務。
復制、用於大多數應用,如:萬維網、電子郵件、文件傳送等。
TCP是面向連接的,TCP之間的通信必須要在兩個套接字(Socket)之間建立連接。
兩者對比
使用UDP協議的通信雙方,可以隨時發送數據。使用TCP協議的通信雙方,在進行數據傳輸之前必須使用“三報文握手”來建立TCP連接。
TCP連接建立成功后才能進行數據傳輸,數據傳輸接收后,必須使用"四報文揮手",來釋放TCP連接。
4.2 用戶數據報協議UDP
4.2.1 基本傳輸
可以發送廣播
可以向某個多播組發送多播
還可以發送單播
總結
使用UDP協議進行通信的四台主機,其中任何一台主機都可向其他三台主機發送廣播。也可以向某個多播組發多播,還可以向某台主機發送單播。
UDP支持單播、多播、以及廣播。UDP支持一對一,一對多,以及一對全的通信。
4.2.2 對應用報文的處理
步驟流程
發送方的應用進程,將應用層報文交付給運輸層的UDP。UDP直接給應用層報文添加一個UDP首部,使之成為UDP用戶數據報,然后進行發送。
接收方的UDP收到該UDP用戶數據報后,去掉UDP首部,將應用層報文交付給應用進程。也就是說,UDP對應用進程交下來的報文既不合並也不拆分,而是保留這些報文的邊界,換句話來說。UDP是面向應用報文的。
4.2.3 UDP向上層提供無連接不可靠傳輸服務
網際層向其上層提供的是無連接不可靠的傳輸服務,當運輸層使用UDP協議時,向其上層提供的也是無連接不可靠的傳輸服務。
流程步驟
發送方給接收方發送UDP用戶數據報,若傳輸過程中用戶數據報受到干擾而產生誤碼,接收方UDP可以通過該數據報首部中的檢驗和字段的值,檢查出產生誤碼的情況。但是僅僅丟棄該數據報,其他什么也不做,發送方給接收方發送UDP用戶數據報。
如果該數據報被因特網中的某個路由器丟棄了,發送方UDP不做任何處理。因為UDP向上層提供的是無連接不可靠的傳輸服務。對於UDP用戶數據報出現的誤碼和丟失等問題,UDP並不關心。基於UDP的這個特點,UDP適用於實時應用,例如IP電話,視頻會議等。
4.3 傳輸控制協議TCP
4.3.1 基本傳輸
使用TCP協議的通信雙方,在進行數據傳輸之前,必須使用“三報文握手”建立TCP連接。
TCP連接建立成功后,通信雙方之間就好像有一條可靠的通信信道,通信雙方使用這條基於TCP連接的可靠信道進行通信。
總結
很顯然,TCP僅支持單播,也就是一對一的通信。
4.3.2 對應用報文的處理
運輸過程
發送方
- TCP會把應用進程交付下來的數據塊看作是一連串無結構的字節流,TCP並不知道這些待傳送的字節流的含義。
- 並將他們編號,並存儲在自己發送緩存中。
- TCP會根據發送策略,提取一定量的字節構建TCP報文並發送。
接收方
- 一方面從所接受到的TCP報文段中,取出數據載荷部分並存儲在接收緩存中;一方面將接收緩存中的一些字節交付給應用進程。
- TCP不保證接收方應用進程所收到的數據塊與發送方發送的數據塊,具有對應大小的關系(例如,發送方應用進程交給發送方的TCP共10個數據塊,但接收方的TCP可能只用了4個數據塊,就把收到的字節流交付給了上層的應用進程,但接收方收到的字節流必須和發送方應用進程發出的字節流完全一樣)。
- 接收方的應用進程必須有能力識別收到的字節流,把它還原成有意義的應用層數據。
TCP是面向字節流的,這正是TCP實現可靠傳輸、流量控制、以及擁塞控制的基礎。在實際網絡中,基於TCP連接的兩端,可以同時進行TCP報文段的發送和接收,也就是全雙工通信。
4.3.3 TCP向上層提供面向連接的可靠傳輸服務
盡管網際層中的IP協議,向上層提供的是無連接不可靠的傳輸服務。也就是說,IP數據報可能在傳輸過程中出現丟失或誤碼。
但只要運輸層使用TCP協議,就可向其上層提供面向連接的可靠傳輸服務,我們可將其想象成,使用TCP協議的收發雙方基於TCP連接的可靠信道進行數據傳輸。
不會出現誤碼、丟棄、亂碼以及重復等傳輸差錯。TCP適用於要求可靠傳輸的應用,例如文件傳輸。
4.4 協議對比
UDP構成
一個UDP用戶數據報由首部和數據載荷兩部分構成,其首部格式如圖所示,僅有4個字段,每個字段長度為2個字節。由於UDP不提供可靠的傳輸服務,它僅僅在網際層的基礎上,添加了用於區分應用進程的端口。因此它的首部非常簡單,僅有8個字節。
TCP構成
一個TCP報文段由首部和數據載荷兩個部分構成,其首部格式如圖所示,這比UDP用戶數據報的首部復制的多,其最小長度為20個字節。最大的長度為60個字節,這是因為TCP要實現可靠傳輸,流量控制,擁塞控制等服務。其首部自然會比較復雜,首部中的字段比較多,首部長度也比較長。
4.5 小結
5- TCP控制
5.1 TCP的流量控制
5.1.1 基本概念
5.1.2 案例分析
步驟分析1
假設主機A和B是因特網上的兩台主機,它們之間已經建立了TCP連接,A給B發送數據,B對A進行流量控制。這是主機A中待發送數據的字節序號。假設主機A發送的每個TCP數據報文段可攜帶100字節數據。因此圖中每個小格子表示100個字節數據的序號,在主機A和B建立TCP連接時,B告訴A:"我的接收窗口為400"。主機A將自己的發送窗口也設置為400。這意味着主機A在未收到主機B發來的確認時,可將序號落入發送窗口中的全部數據發送出去。
步驟分析2
主機B對A的流量控制,主機A將發送窗口內序號1~100的數據封裝成一個TCP報文段發送出去。發送窗口內還有300字節可以發送,這里的seq是TCP報文段首部中的序號字段,取值1表示TCP報文段數據載荷的第一個字節的序號是1。
這里的DATA表示這是TCP數據報文段,主機A將發送窗口內序號101200的數據封裝成一個TCP報文段發送出去,發送窗口內還有200字節可以發送。主機A將發送窗口內還有200字節可以發送。主機A將發送窗口內序號201300的數據,封裝成一個TCP報文段發送出去。但該報文段在傳輸過程中丟失了,主機A發送窗口內還有100個字節可以發送,主機B對主機A所發送的201號以前的數據進行累計確認。
並在該累計確認中將窗口字段的值調整為300,也就是對主機A進行流量控制。這里的大寫ACK是TCP報文段首部中的標志位,取值1表示這是一個TCP確認報文段,小寫ack是TCK報文段首部中的確認號字段。取值201表示序號201之前的數據已全部正確接收,現在希望收到序號201及其后續數據。rwnd是TCP報文段首部中的窗口字段,取值300表示自己的接收窗口大小為300。
步驟分析3
主機A收到該累計確認后,將發送窗口向前滑動,使已經發送並收到確認的這些數據的序號移出發送窗口。由於主機B在該累計確認中將自己的接收窗口調整為了300。主機A相應地將自己的發送窗口調整為300。主機A發送窗口內的序號為201500,也就是主機A還可以發送這300字節,201300號字節是已發送的數據,如果重傳計時器超時,它們會被重傳。301400字節以及401500號字節還未被發送,可分別封裝在一個TCP報文段中發送,主機A現在可將發送緩存中序號1~200的字節數據全部刪除了。
因為已經收到了主機B對它們的累計確認,主機A將發送窗口內序號301400的數據封裝成一個TCP報文段發送出去,發送窗口內還有100字節可以發送。主機A將發送窗口內序號401500的數據,封裝成一個TCP報文段發送出去。至此,序號落在發送窗口內的數據已經全部發送出去了,不能再發送新數據了。
步驟分析4
現在,發送窗口內序號201~300這100個字節數據的重傳計時器超時了,主機A將它們重新封裝成一個TCP報文段發送出去,暫時不能發送其他數據。主機B收到該重傳的TCP報文段后,對主機A所發送的501號以前的數據進行累計確認,並在該累計確認中將窗口字段的值調整為100,這是主機B對主機A進行的第二次流量控制。
步驟分析5
主機A收到該累計確認后,將發送窗口向前滑動,使已發送並收到確認的這些數據的序號移出發送窗口。由於主機B在該累計確認中將自己的接收窗口調整為了100。因此,主機A相應地將自己的發送窗口調整為100。目前,主機A發送窗口內的序號為501600。也就是主機A還可以發送這100字節,主機A現在可將發送緩存中序號201500的字節數據全部刪除了,因為已經收到了主機B對它們的累計確認。
步驟分析6
主機A將發送窗口內序號501600的數據,封裝成一個TCP報文段發送出去。至此,序號落在發送窗口內的數據已經全部發送出去了,不能在發送新數據了。主機A所發送的601號以前的數據進行累計確認,並且在改累計確認中將窗口字段的值調整為0,這是主機B對主機A進行的第三次流量控制,主機A收到該累計確認后,並且將發送窗口向前滑動,使已發送並收到確認的這些數據的序號移出發送窗口。由於主機B在該累計確認中將自己的接收窗口調整為了0。因此,主機A相應地將自己的接收窗口調整為0。目前,主機A不能再發送一般的TCP報文段了。主機A現在可將發送緩存中的序號501600的字節數據全部刪除了,因為已經收到了主機B對它們的累計確認。
步驟分析7
假設主機B向主機A發送了零窗口的報文段后不久,主機B的接收緩存又有了一些存儲空間。於是,主機B向主機A發送了接收窗口等於300的報文段。然而,這個報文段在傳輸過程中丟失了,主機A一直等待主機B發送的非零窗口的通知,而主機B也一直等待主機A發送的數據,如果不采取措施,這種互相等待而形成的死鎖局面將一直持續下去。
步驟分析8
TCP為每一個連接設有一個持續計時器。只要TCP連接的一方收到對方的零窗口通知,就啟動持續計時器。若持續計時器超時,就發送一個零窗口探測報文,僅攜帶一字節的數據。而對方在確認這個探測報文段時,給出自己現在的接收窗口值。如果接收窗口仍然是0,那么收到這個報文段的一方就重新啟動持續計時器。如果接收窗口不是0,那么死鎖的局面就可以被打破了。
主機A收到零窗口通知時,就啟動一個持續計時器。當持續計時器超時時,主機A立刻發送一個僅攜帶一字節數據的零窗口探測報文段。假設主機B此時的接收窗口又為0了。主機B就在確認這個零窗口探測報文段時給出自己現在的接收窗口值為0,主機A再次收到零窗口通知,就再次啟動一個持續計時器。當持續計時器超時,主機A立刻發送一個零窗口探測報文段。假設主機B此時的接收緩存又有了一些存儲空間,於是將自己的接收窗口調整為了300,主機B就在確認這個零窗口探測報文段時,給出自己現在的接收窗口值為300,這樣就打破了死鎖的局面。
步驟分析9
主機A所發送的零窗口探測報文段到達主機B時,如果主機B此時的接收窗口仍然為0,那么主機B根本就無法接受該報文段,又怎么會針對該報文段給主機A發回確認時?實際上TCP規定,即使接收窗口為0,也必須接受零窗口探測報文段、確認報文段、以及攜帶有緊急數據的報文段。
如果零窗口探測報文段丟失了,會出現怎樣的問題呢? 還能否打破死鎖的局面嗎?
能打破死鎖的局面,因為零窗口探測報文段也有重傳計時器,當重傳計時器超時后,零窗口探測報文段會被重傳。
5.1.3 小結
5.2 TCP的擁塞控制
5.2.1 基本概念
5.2.2 擁塞控制的算法
條件設定
5.2.3 慢開始和擁塞避免
慢開始
步驟流程1
傳輸輪次是指: 發送方給接收方發送數據報文段后,接收方給發送方發回相應的確認報文段。一個傳輸輪次所經歷的時間,其實就是往返時間。往返時間並非是恆定的數值。使用傳輸輪次是為了強調,把擁塞窗口所允許發送的報文段都連續發送出去,並且收到了對已發送的最后一個報文段的確認。
縱坐標是擁塞窗口,它會隨網絡擁塞程度以及所使用的擁塞控制算法動態變化,在TCP雙方建立邏輯連接關系時,擁塞窗口的值被設置為1,如下圖標出傳輸輪次0時的擁塞窗口值為1,另外,還需要設置慢開始門限的初始值。本例采用16發送方每收到一個新報文段的確認時,就把擁塞窗口值加1,然后開始下一輪的傳輸,當擁塞窗口值增長到慢開始門限值時,就改為執行擁塞避免算法。
步驟流程2
由於發送方當前的擁塞窗口值是1,而發送窗口值等於擁塞窗口值,發送方當前只能發送一個TCP數據報文段,換句話說,擁塞窗口值是幾,就能發送幾個數據報文段。發送方發送0號數據報文段,接收方收到后,給發送方發回對0號報文段的確認報文段,發送方收到該確認報文段后,將擁塞窗口值加1增大到2,這意味着發送方。現在可以發送12號共兩個數據報文段。接收方收到后,給發送方發回對12號報文段的確認報文段,發送方收到后,將擁塞窗口值增加2增大到4。
步驟流程3
發送方現在可以發送36號共四個數據報文段。接收方收到后,給發送方發回對36號報文段的確認報文段。發送方收到后,將擁塞窗口值加4增大到8,發送方現在可以發送714號共8個數據報文段。接收方收到后,給發送方發回對714號報文段的確認報文段,發送方收到后,將擁塞窗口值加8增大到16。
發送方當前的擁塞窗口值,已經增大到了慢開始門限值。之后,然后要改用擁塞避免算法。
擁塞避免
步驟流程1
每個傳輸輪次結束后,擁塞窗口值只能線性加1,而不像慢開始算法那樣,每個傳輸輪次結束后,擁塞窗口值按指數規律增大,發送方現在可以發送1530號共16個數據報文段,接收方收到后。給發送方發回對1530號報文段的確認報文段。發送方收到后,將擁塞窗口值加1增大到17。
步驟流程2
在圖中標出該值,發送方現在可以發送3147號共17個數據報文段,接收方收到后,給發送方發回對3147號報文段的確認報文段。發送方收到后,將擁塞窗口值加1增大到18。
步驟流程3
在圖中標出該值,隨着傳輸輪次的增加,擁塞窗口值每輪次都線性加1。當前擁塞窗口值增加到類4,發送方現在可以發送171~194號共24個數據報文段。假設這24個數據報文段在傳輸過程中丟失了幾個。這必然會造成發送方對這些丟失報文段的超時重傳。發送方以此判斷網絡很可能出現了擁塞。
步驟流程4
發送方以此判斷網絡很可能出現了擁塞,需要進行以下工作。(1) 將慢開始門限值更新為發生擁塞時擁塞窗口值得一半,網絡發送擁塞時的擁塞窗口值是24,因此更新慢開始門限值為該值的一半,即12。(2) 將擁塞窗口值減小為1,並且重新開始執行慢開始算法。
步驟流程5
當慢開始算法執行到擁塞窗口值,增大到新的慢開始門限值時,就停止使用慢開始算法。轉而執行擁塞避免算法。
步驟流程6
TCP發送方一開始使用慢開始算法,讓擁塞窗口值從1開始按指數規律增大。當擁塞窗口值增大到慢開始門限值時,停止使用慢開始算法,轉而執行擁塞避免算法,讓擁塞窗口值按線性加1的規律增大。當發生超時重傳時,就判斷網絡很可能出現擁塞。采取相應的措施,一方面將慢開始門限值,更新為發生擁塞時擁塞窗口值得一半。另一方面將擁塞窗口值減少為1,並且從新開始執行慢開始的算法,擁塞窗口值又從1開始按指數規律增大,當增大到了新的慢開始門限值時,停止使用慢開始算法,轉而執行擁塞避免算法,讓擁塞窗口值按線性加1的規律增大。
5.2.4 快重傳和快恢復
快重傳(fast retrasmit)
快恢復(fast recovery)
改進后的整體算法的示意圖
步驟流程
TCP發送方一開始使用慢開始算法,讓擁塞窗口值從1開始按指數規律增大,當增大到慢開始門限初始值時,停止使用慢開始算法。轉而執行擁塞避免算法,讓擁塞窗口值按線性加1的規律增大。當發生超時重傳時,就判斷網絡可能出現了擁塞,采取相應的措施。一方面將慢開始門限值更新為發生擁塞時擁塞窗口值的一半。另一方面將擁塞窗口值減少為1,並重新開始執行慢開始算法。
擁塞窗口值又從1開始按指數規律增大,當增大到了新的慢開始門限值時,停止使用慢開始算法,轉而執行擁塞避免算法,讓擁塞窗口值按線性加1的規律增大。當發送方收到3個重復確認時,就進行快重傳和快恢復。也就是更新慢開始門限值為當前擁塞窗口值的一半,並將擁塞窗口值也取為新的慢開始門限值,轉而執行擁塞避免算法,讓擁塞窗口值按線性加1的規律增大。
5.3 TCP超時重傳時間的選擇
5.3.1 基本概念
步驟流程1
主機A給主機B發送TCP數據報文段0,並且記錄下當前的時間。主機B收到后,給主機A發送相應的確認報文段。主機A收到確認報文段后,記錄下當前的時間。那么主機A記錄下的這兩個時間,它們的差值就是報文段的往返時間RTT。
如果超時重傳時間RTO的值設置得比RTT0的值小很多,這會引起報文段不必要的重傳,使網絡負荷增大。
步驟流程2
如果超時重傳時間RTO的值設置得遠大於RTT0的值,這會使重傳時間推遲的太長,使網絡的空閑時間增大,降低傳輸效率。
步驟流程3
注意:TCP下層是復雜的互聯網環境,主機A所發送的報文段,可能只經過一個高速率的局域網,也有可能經過多個低速率的網絡,每個IP數據報的轉發路由還可能不同。
5.3.2 超時重傳時間
RFC6298建議使用下式計算超時重傳時間RTO
5.3.3 往返時間RTT的測量比較復雜
存在問題
當發送方出現超時重傳后,收到確認報文段時,是無法判斷出該確認,到底是對原報文段的確認。還是對重傳報文段的確認,也就是無法准確測量出RTT,進而無法正確計算超時重傳時間RTO。
解決方案
5.3.4 TCP超時重傳的計算
步驟分析1
這是測量到的第一個RTT樣本RTT1,根據RTTs1的計算公式可知RTTs1的值。根據RTTs1的計算公式可知RTTs1的值。根據RTTD1的計算公式可知RTTD1的值,再根據RTO的計算公式可計算出RTO1的值。這是測量到的第二個RTT樣本RTT2。根據RTTs的計算公式和 α的值,可寫出計算RTTs2的表達式。將之前計算出的RTTs1的值和本次測量到的RTT2的值帶入該式,可計算出RTTs2的值。
步驟分析2
根據RTTD的計算公式和 β的值,可以寫出計算RTTD2的表達式。將之前計算出的RTTD1、RTTs1、以及本次測量到的RTT2的值代入該公式,可計算出RTTD2的值,再根據RTO的計算公式可計算出RTO2的值。
步驟分析3
假設這是測量到的第五個RTT樣本,但是根據RTO4的值可知,在收到確認之前就會產生超時重傳。則不采用上述公式計算RTO,而是將新RTO的值取為舊RTO值的兩倍。因此RTO5的值取為兩倍的RTO4的值。
5.3.5 小結
5.4 TCP可靠傳輸的實現
5.4.1 案例說明
步驟流程1
假定數據傳輸只在一個方向進行,發送方給接收方發送TCP數據報文段,接收方給發送方發送相應的TCP確認報文段,這樣的好處是使討論僅限於兩個窗口,也就是發送方的發送窗口和接收方的接收窗口。TCP的滑動窗口是以字節為單位的。
步驟流程2
假設發送方收到了一個來自接收方的確認報文段,在報文段首部中的窗口字段的值為20,也就是接收方表明自己的接收窗口的尺寸為20字節。確認號字段的值為31,這表明接收方希望收到下一個數據的序號是31,而序號30為止的數據已經全部正確接收了。
步驟流程3
發送方根據這兩個字段的值構造出自己的發送窗口,假定網絡不存在擁塞問題,也就是發送方在構造自己的發送窗口時,僅僅考慮接收方的接收窗口,而不是考慮擁塞窗口。發送方在沒有收到接收方確認的情況下,可以把發送窗口內的數據依次全部發送出去。凡是已經發送過的數據,在未收到確認之前,都必須暫時保留,以便在超時重傳時使用。發送窗口后沿的后面部分,是已發送並收到確認定位數據字節的序號,這些數據字節顯然不需要再保存在發送緩存中了,可以將它們刪除。發送窗口前沿的前面是當前不允許發送的數據字節的序號,發送窗口的后沿不可能向后移動,因為不能撤銷掉已收到的確認。
如何描述發送窗口的狀態?
假定發送方將發送窗口內序號31-41的數據,封裝在幾個不同的報文段中發送出去。此時發送窗口的位置並沒有改變。發送窗口內序號3141的數據已經發送但是未收到確認,而序號4250的數據是允許發送但是還未發送的。可以使用三個指針P1,P2,P3分別指向相應的字節序號。
步驟流程4
繼續看接收方的接收窗口,它的尺寸為20。在接收窗口外面到30號為止的數據,是已經發送過相應確認並已交付給應用進程的數據。因此無需再保留這些數據,可將它們從接收緩存中刪除了。接收窗口內31~50號數據是允許接收的數據,接收窗口外51號及其后續數據,目前不允許接收。假設發送方之前發送的,封裝有32和33號數據的報文段到達了接收方。
由於數據序號落在接收窗口內,所以接收方接受他們。將它們存入接收緩存,但是,它們是未按序到達的數據,因為31號數據還沒有到達,這有可能丟了,也有可能是滯留在網絡中的某處。請注意:接收方只能對按序收到的數據中的最高序號給出確認。因此,接收方發出的確認報文段中的確認序號仍然是31,也就是希望收到31號數據,窗口字段的值仍然是20,表明接收方沒有改變自己接收窗口的大小。
發送方收到該確認報文段后,發現這是一個針對31號數據的重復確認,就知道接收方收到了未按序到達的數據。由於這是針對31號數據的第一個重復確認,因此這並不會引起發送方針對該數據的快重傳。另外,接收方通知的窗口尺寸仍是20。現在假設封裝有31號數據的報文段到達了接收方,接收方接受該報文段,將其封裝的31號數據存入接收緩存。
將其封裝的31號數據存入接收緩存,接收方現在可將接收到的31~33號數據交付給應用進程。然后將接收窗口向前移動3個序號,並給發送方發送確認報文段。該確認報文段中窗口字段的值仍為20,表明接收方沒有改變自己接收窗口的大小。確認號字段的值為34,這表明接收方已經收到了序號33為止的全部數據。
步驟流程5
現在,假設又有幾個數據報文段到達了接收方,它們封裝有37、38以及40號數據。這些數據的序號雖然落在接收窗口內,但它們都是未按序到達的數據,只能先暫存在接收緩存中。
假設接收方先前發送的確認報文段到達了發送方,發送方接收后,將發送窗口向前滑動3個序號。
發送窗口的尺寸保存不變,這樣就有新序號5153落入發送窗口內,而且序號3133移出了發送窗口,現在可將31~33號數據從發送緩存中刪除了,因為已經收到了接收方針對它們的確認。
發送方繼續將發送窗口內序號42~53的數據,封裝在幾個不同的報文段中發送出去。現在,發送窗口內的序號已經用完了,發送方在未收到接收方來確認的情況下,不能再發送新的數據。序號落在發送窗口內的已發送數據,如果遲遲收不到接收方的確認,則會產生超時重傳。
5.4.2 解決方案
6- TCP的運輸連接管理
6.1 基本概念
6.2 TCP的連接建立
前置步驟
- TCP 建立連接的過程叫做握手。
- 握手需要在客戶和服務器之間交換三個 TCP 報文段。稱之為三報文握手。
- 采用三報文握手主要是為了防止已失效的連接請求報文段突然又傳送到了,因而產生錯誤。
TCP的連接建立要解決以下三個問題
6.2.1三報文握手建立連接
流程步驟1
TCP 連接的建立采用客戶服務器方式,主動發起連接建立的應用進程叫做TCP客戶 (client)。被動等待連接建立的應用進程叫做TCP服務器 (server)。
“握手”需要在TCP客戶端和服務器之間交換三個TCP報文段,最初兩端的TCP進程都處於關閉狀態。
流程步驟2
一開始,TCP服務器進程首先創建傳輸控制塊,用來存儲TCP連接中的一些重要信息。例如TCP連接表、指向發送和接收緩存的指針、指向重傳隊列的指針,當前的發送和接收序號等之后,就准備接受TCP客戶端進程的連接請求。此時,TCP服務器進程就進入監聽狀態,等待TCP客戶端進程的連接請求。
TCP服務器進程是被動等待來自TCP客戶端進程的連接請求,因此成為被動打開連接
流程步驟3
TCP客戶進程也是首先創建傳輸控制塊,由於TCP連接建立是由TCP客戶端主動發起的,因此稱為主動打開連接。然后,在打算建立TCP連接時,向TCP服務器進程發送TCP連接請求報文段,並進入同步已發送狀態。TCP連接請求報文段首部中,同步位SYN被設置為1,表明這是一個TCP連接請求報文段。序號字段seq被設置了一個初始值x,作為TCP客戶端進程所選擇的初始序號,請注意:TCP規定SYN被設置為1的報文段不能攜帶數據,但要消耗掉一個序號。
流程步驟4
TCP服務器進程收到TCP連接請求報文段后,如果同意建立連接,則向TCP客戶進程發送TCP連接請求確認報文段,並進入同步已接收狀態TCP連接請求確認報文段首部中,同步位SYN和確認為ACK都設置為1,表明這是一個TCP連接請求確認報文段,序號字段seq被設置了一個初始值y,作為TCP服務器進程所選擇的初始序號。確認號字段ack的值被設置成了x+1,這是對TCP客戶進程所選擇的初始序號(seq)的確認。請注意:這個報文段也不能攜帶數據,因為它是SYN被設置為1的報文段,但同樣要消耗掉一個序號。
TCP客戶進程收到TCP連接請求確認報文段后,還要向TCP服務器進程發送一個普通的TCP確認報文段,並進入連接已連接狀態。普通的TCP確認報文段首部中確認位ACK被設置為1,表明這是一個普通的TCP確認報文段,序號字段seq被設置為x+1,這是因為TCP客戶進程發送的第一個TCP報文段的序號為x,所以TCP客戶進程發送的第二個報文段的序號為x+1。確認號字段ack被設置為y+1,這是對TCP服務器進程所選擇的初始序號的確認。請注意:TCP規定普通的TCP確認報文段可以攜帶數據,但如果不攜帶數據,則不消耗序號。
流程步驟5
TCP服務器進程收到該確認報文段后也進入連接已建立狀態,現在,TCP雙方都進入了連接已建立狀態,它們可以基於已建立好的TCP連接,進行可靠的數據傳輸。
6.2.2 兩報文握手
為什么TCP客戶進程最后還要發送一個普通的TCP確認報文段?能否使用“兩報文握手”建立連接?
流程步驟
TCP客戶進程發出一個TCP連接請求報文段、但該報文段在某些網絡結點長時間滯留了,這必然會造成該報文段的超時重傳,假設重傳的報文段被TCP服務器進程正常接收。TCP服務器進程給TCP客戶進程發送一個TCP連接請求確認報文段,並進入連接已建立狀態。
請注意: 由於我們改為"兩報文握手"
因此TCP服務器進程發送完TCP連接請求確認報文段后,進入的是連接已建立狀態,而不像"三報文握手"那樣進入同步已連接狀態,並等待TCP客戶進程發來針對TCP連接請求確認報文段的普通確認報文段。TCP客戶進程收到TCP連接請求確認報文段后,進入TCP連接已建立狀態。但不會給TCP服務器進程發送針對該報文段的普通確認報文段。現在,TCP雙方都處於連接已建立狀態。它們可以相互傳輸數據。之后,可以通過“四報文揮手”來釋放連接,TCP雙方都進入了關閉狀態。
一段時間后,之前滯留在網絡中的那個失效的TCP連接請求報文段、到達了TCP服務器進程。TCP服務器進程會誤認為這是TCP客戶進程,又發起一個新的TCP連接請求。於是給TCP客戶進程發送TCP連接請求確認報文段,並進入連接已建立狀態。該報文段到達TCP客戶進程,由於TCP客戶進程並沒有發起新的TCP連接請求,並且處於關閉狀態,因此不會理會該報文段。但是TCP服務器進程已經進入連接已建立狀態,它認為新的TCP連接已經建立好了,並且一直等待TCP客戶進程發來數據,這將白白浪費TCP服務器進程所在主機的很多資源。
得出結論
采用"三報文握手"而不是"兩報文握手"來建立TCP連接,是為了防止已失效的連接請求報文段突然又傳送到了TCP服務器,因而導致錯誤。
6.2.3 小結
6.3 TCP的連接釋放
6.3.1 前置步驟
- TCP 連接釋放過程比較復雜。
- 數據傳輸結束后,通信的雙方都可釋放連接。TCP 連接釋放過程是四報文握手。
6.3.2 四報文揮手來釋放連接
- TCP 連接的建立采用客戶服務器方式。
- 主動發起連接建立的應用進程叫做TCP客戶 (client)。
- 被動等待連接建立的應用進程叫做TCP服務器 (server)。
- 任何一方都可以在數據傳送結束后發出連接釋放的通知
6.3.3 執行流程
流程步驟1
現在TCP客戶進程和TCP服務器進程都處於連接已建立狀態,TCP客戶進程的應用進程通知其主動關閉TCP連接。TCP客戶進程會發送TCP連接釋放報文段,並進入終止等待1狀態,TCP連接釋放報文段首部中。終止位FIN和確認為ACK的值都被設置為1,表明這是一個TCP連接釋放報文段,同時也對之前收到的報文段進行確認序號seq字段的值設置為u,它等於TCP客戶進程之前已傳送過的數據的最后一個字節的序號加1,確認號ack字段的值設置為v,它等於TCP客戶進程之前已收到的、數據的最后一個字節的序號加1。請注意:TCP規定終止位FIN等於1的報文段即使不攜帶數據,也要消耗掉一個序號。
流程步驟2
TCP服務器進程收到TCP連接釋放報文段后,會發送一個普通的TCP確認報文段並進入關閉等待狀態,普通的TCP確認報文段首部中。確認位ACK的值被設置為1,表明這是一個普通的TCP確認報文段。序號seq字段的值設置為v,它等於TCP服務器進程之前已傳送過的數據的最后一個字節的序號加1,這也與之前收到的TCP連接釋放報文段中的確認號匹配,確認號ack字段的值設置為u+1,這是對TCP連接釋放報文段的確認。
流程步驟3
TCP服務器進程應該通知高層應用進程,TCP客戶進程要斷開與自己的TCP連接。此時,從TCP客戶進程到TCP服務器進程這個方向的連接就釋放了。這時的TCP連接屬於半關閉狀態,也就是TCP客戶進程已經沒有數據要發送了。但如果TCP服務器進程還有數據要發送,TCP客戶進程仍要接收,也就是說從TCP服務器進程到TCP客戶進程這個方向的連接並未關閉。
流程步驟4
TCP客戶進程收到TCP確認報文段后就進入終止等待2狀態,等待TCP服務器進程發出的TCP連接釋放報文段。若使用TCP服務器進程的應用進程已經沒有數據要發送了,應用進程就通知其TCP服務器進程釋放連接。由於TCP連接釋放是由TCP客戶進程主動發起的,因此TCP服務器進程對TCP連接的釋放稱為被動關閉連接。
流程步驟5
TCP服務器進程發送TCP連接釋放報文段並進入最后確認狀態,該報文段首部中。終止位FIN和確認位ACK的值都被設置為1,表明這是一個TCP連接釋放報文段,同時也對之前收到的報文段進行確認,序號seq字段的值為w,這是因為在半關閉狀態下,TCP服務器進程可能又發送。確認號ack字段的值為u+1,這是對之前收到的TCP連接釋放報文段的重復確認。
流程步驟6
TCP客戶進程收到TCP連接釋放報文段后,必須針對該報文段發送普通的TCP確認報文段,之后進入時間等待狀態。該報文段首部中確認為ACK的值被設置為1,表明這是一個普通的TCP確認報文段。序號seq字段的值設置為u+1,這是因為TCP客戶進程之前發送的TCP連接釋放報文段雖然不攜帶數據,但要消耗掉一個序號。確認號ack字段的值設置為w+1,這是對所收到的TCP連接釋放報文段的確認。TCP服務器進程收到該報文段后就進入關閉狀態,而TCP客戶進程還要進過2MSL后才能進入關閉狀態。
TCP客戶進程在發送完最后一個確認報文后,為什么不直接進入關閉狀態?而是要進入時間等待狀態?
TCP服務器進程發送TCP連接釋放報文段后進入最后確認狀態。TCP客戶進程收到該報文段后,發送普通的TCP確認報文段,並進入關閉狀態而不是時間等待狀態。然而,該TCP確認報文段丟失了。這必然會造成TCP服務器進程對之前所發送的TCP連接釋放報文段的超時重傳,並仍處於最后的確認狀態。重傳的TCP連接釋放報文段到達TCP客戶進程。由於TCP客戶進程屬於關閉狀態,因此不理睬該報文段,這必然會造成TCP服務器進程反復重傳TCP連接釋放報文段,並一直處於最后確認狀態而無法進入關閉狀態。因此,時間等待狀態以及處於該狀態2MSL時長,可以確保TCP服務器進程可以收到最后一個TCP確認報文段而進入關閉狀態。另外,TCP客戶進程在發送完最后一個TCP確認報文段后,再經過2MSL時長,就可以使本次連接持續時間內所產生的所有報文段都從網絡中消失,這樣就可以使下一個新的TCP連接中,不會出現舊連接中的報文段。
6.4 TCP保活計時器的作用
TCP雙方已經建立了連接,后來,TCP客戶進程所在的主機突然出現了故障。
TCP服務器進程以后就不能再收到TCP客戶進程發來的數據,因此,應當有措施使TCP服務器進程不要再白白等待下去。
7- TCP報文段的首部格式
7.1 基本概念
7.2 源端口和目的端口
源端口和目的端口的作用
假設主機中的瀏覽器進程,要訪問Web服務器中的Web服務器進程。當在瀏覽器地址欄中輸入了Web服務器的域名后,瀏覽器進程會構建一個封裝有HTTP請求報文的TCP報文段,該報文段首部中的源端口字段會填寫一個短暫端口號,例如49152,用來標識發送該報文段的瀏覽器進程。目的端口字段會填寫熟知端口號80,因為使用HTTP協議的Web服務器進程默認監聽該端口。
Web服務器收到該TCP報文段后,從中解封出HTTP請求報文,並根據TCP報文段首部中目的端口字段的值,將HTTP請求報文上交給Web服務器進程。Web服務器進程根據HTTP請求報文的內容進行相應處理,並構建一個HTTP響應報文。HTTP響應報文需要封裝成TCP報文段進行發送。該報文段首部中的源端口字段會填寫熟知端口號80,用來標識發送該TCP報文段的Web服務器進程。而目的端口字段會填寫49152,這是主機中需要接收該TCP報文段的瀏覽器進程所對應的端口號。
主機收到該TCP報文段后,從中解封出HTTP響應報文,並根據TCP報文段首部中目的端口字段的值49152,將HTTP響應報文上交給瀏覽器進程。瀏覽器進程對HTTP響應報文的內容進行解析並且顯示。
7.3 序號、確認號和確認標志位
流程步驟
TCP客戶進程發送一個TCP報文段,該報文段首部中序號字段的取值為201,這表示該TCP報文段數據載荷的第一個字節的序號為201。假設數據載荷的長度為100字節,首部中確認號字段的取值為800,這表示TCP客戶進程收到了TCP服務器進程發來的,序號到799為止的全部數據,現在期望收到序號從800開始的數據。為了使確認號字段有效,首部中的確認標志位ACK的值必須設置為1。
TCP服務器進程收到該報文段后,也給TCP客戶進程發送TCP報文段。該報文段首部中序號字段的取值為800,這表示該TCP報文段數據載荷的第一個字節的序號為800,這正好與TCP客戶進程的確認相匹配。
假設數據載荷的長度為200字節。首部中確認號字段的取值為301,這表示TCP服務器進程收到了TCP客戶進程發來的,序號到300為止的全部數據,現在期望收到序號從301開始的數據。為了使確認號字段有效,首部中的確認標志位ACK的值必須設置為1。
7.4 數據偏移、保留、窗口和校驗和
分析
假設這個TCP報文段首部中的數據偏移字段的取值為二進制的0101,那么首部長度就為20字節。因為二進制0101的十進制值是5,而該字段以4字節為單位,因此5乘以4字節等於20字節。
分析
假設這個TCP報文段首部中的數據偏移字段的取值為二進制的1111,那么首部的長度就為60字節,因為二進制1111的十進制是15,而該字段以4字節為單位,因此15乘以4字節等於60字節。
注意事項
發送窗口的大小還取決於擁塞窗口的大小,也就是應該從接收窗口和擁塞窗口中的取小者,TCP報文段首部中的檢驗和字段。
7.5 同步標志位、終止標志位、復位標志位、推送標志位、緊急標志位和緊急指針
同步標志位
TCP通過"三報文握手"建立連接的過程。TCP客戶進程發送的TCP連接請求報文段,首部中的同步標志位SYN被置於1,表明這是一個TCP連接請求報文段。TCP服務器進程發送的TCP連接請求確認報文段,首部中的同步標志位SYN被置1,確認位ACK也被置1,表明這是一個TCP連接請求確認報文段。
終止標志位
不管是TCP客戶進程還是TCP服務器進程,它們所發送的TCP連接釋放報文段,首部中的終止標志位FIN都被置1,表明這是TCP連接釋放報文段。
復位標志位
推送標志位
緊急標志位和緊急指針