Ⅰ 計算機網路-網路層-超網
在一個劃分子網的網路中可同時使用幾個不同的子網掩碼。使用變長子網掩碼VLSM(Variable Length Subnet Mask)可進一步提高IP地址資源的利用率。在VLSM的基礎上又進一步研究出無分類編址方法,它的正式名字是 無分類域間路由選擇CIDR (Classless Inter-Domain Routing,CIDR的讀音是「sider'」)。
CIDR最主要的特點有兩個:
(I)CIDR把32位的IP地址劃分為前後兩個部分。前面部分是「網路前綴」(network-prefix)(或簡稱為「前綴」),用來指明網路,後面部分則用來指明主機。因此CIDR使IP地址從三級編址(使用子網掩碼)又回到了兩級編址,但這已是無分類的兩級編址。其記法是:
IP地址:={<網路前綴>,<主機號>} (4-3)
CIDR還使用「斜線記法」(slash notation),或稱為CIDR記法,即在IP地址後面加上斜線「/」,然後寫上網路前綴所佔的位數。
(2)CIDR把網路前綴都相同的連續的IP地址組成一個「CIDR地址塊」。我們只要知道CIDR地址塊中的任何一個地址,就可以知道這個地址塊的起始地址(即最小地址)和最大地址,以及地址塊中的地址數。例如,已知IP地址128.14.35.7/20是某CIDR地址塊中的一個地址,現在把它寫成二進製表示,其中的前20位是網路前綴,而後面的12位是主機號:
128.14.35.7/20= 1000 0000 0000 1110 0010 0011 0000 0111
這個地址所在的地址塊中的最小地址和最大地址可以很方便地得出:找出 地址掩碼(斜線後面的數字個數是掩碼地址1的個數, 20位)中1和0的交界處 發生在地址中的哪一個位元組。現在是在第三個位元組,取後面12 都寫成0是最小地址,寫成1為最大地址。
最小地址:128.14.32.0 1000 0000 0000 1110 0010 0000 0000 0000
最大地址:128.14.47.255 1000 0000 0000 1110 0010 1111 1111 1111
以上這兩個特殊地址的主機號是全0和全1的地址。一般並不使用。通常只使用在這兩個特殊地址之間的地址。 這個地址塊共有2^12個地址(2 的主機號位數次冪) 。我們可以用地址塊中的最小地址和網路前綴的位數指明這個地址塊。例如,上面的地址塊可記為128.14.32.0/20。在不需要指出地址塊的起始地址時,也可把這樣的地址塊簡稱為「/20地址塊」。
為了更方便地進行路由選擇,CIDR使用32位的地址掩碼(address mask)。地址掩碼由一串1和一串0組成,而1的個數就是網路前綴的長度。雖然CIDR不使用子網了,但由於目前仍有一些網路還使用子網劃分和子網掩碼,因此CIDR使用的地址掩碼也可繼續稱為子網掩碼。例如,/20地址塊的地址掩碼是:1111 1111 1111 1111 1111 0000 0000 0000(20個連續的1)。 斜線記法中,斜線後面的數字就是地址掩碼中1的個數。
在「CIDR不使用子網」是指CIDR並沒有在32位地址中指明若干位作為子網欄位。但分配到一個CIDR地址塊的單位,仍然可以在本單位內根據需要劃分出一些子網。這些子網也都只有一個網路前綴和一台主機號欄位,但子網的網路前綴比整個單位的網路前綴要長些。例如,某單位分配到地址塊/20,就可以再繼續劃分為8個子網(即需要從主機號中借用3位來劃分子網)。這時每一個子網的網路前綴就變成23位(原來的20位加上從主機號借來的3位),比該單位的網銘前綴多了3位。
由於一個CIDR地址塊中有很多地址,所以在路由表中就利用CIDR地址塊來查找目的網路。這種地址的聚合常稱為 路由聚合 (route aggregation),它使得路由表中的一個項目可以表示原來傳統分類地址的很多個(例如上干個)路由, 路由聚合也稱為構成超網 (supemetting)。路由聚合有利於減少路由器之間的路由選擇信息的交換,從而提高了整個互聯網的性能。
CIDR記法有多種形式,例如,地址塊10.0.0.0/10可簡寫為10/10,也就是把點分十進制中低位連續的0省略。另一種簡化表示方法是在網路前綴的後面加一個星號*,如:0000101000*意思是:在星號*之前是網路前綴,而星號◆表示P地址中的主機號,可以是任意值。
前綴位數不是8的整數倍時,需要進行簡單的計算才能得到一些地址信息。表47給出了最常用的CIDR地址塊。表中的K表示2^10=1024,網路前綴小於13或大於27都較少使用。在「包含的地址數」中沒有把全1和全0的主機號除外。
從表4-7可看出,每一個CIDR地址塊中的地址數一定是2的整數次冪。CIDR地址塊多數可以包含多個C類地址(是一個C類地址的2」倍,n是整數),這就是「 構成超網 」這一名詞的來源。
使用CIDR的一個好處就是可以更加有效地分配PV4的地址空間,可根據客戶的需要分配適當大小的CIDR地址塊。假定某ISP已擁有地址塊206.0.64.0/18(相當於有64個C類網路)。現在某大學需要800個IP地址。ISP可以給該大學分配一個地址塊206.0.68.0/22,它包括1024(即2^10)個1P地址,相當於4個連續的C類(/24地址塊),占該ISP擁有的地址空間的1/16。這個大學然後可自由地對本校的各系分配地址塊,而各系還可再劃分本系的地址塊。
從圖4-25可以清楚地看出地址聚合的概念。這個ISP共擁有64個C類網路。如果不採用CIDR技術,則在與該SP的路由器交換路由信息的每一個路由器的路由表中,就需要有64個項目,但採用地址聚合後,就只需用路由聚合後的一個項目206.0.64.0/18就能找到該ISP,同理,這個大學共有4個系,在1SP內的路由器的路由表中,也需使用206.0.68.022這個項目。這個項目好比是大學的收發室。凡寄給這個大學任何一個系的郵件,郵遞員都不考慮大學各個系的地址,而是把這些郵件集中投遞到大學的收發室,然後由大學的收發室再進行下一步的投遞。這樣就減輕了v遞員的工作量(相當於簡化了路由表的查找)。
從圖4-25下面表格中的二進制地址可看出,把四個系的路由聚合為大學的一個路由(即構成超網),是將網路前綴縮短。 網路前綴越短,其地址塊所包含的地址數就越多。而在三級結構的P地址中,劃分子網是使網鉻前綴變長。
在使用CIDR時,由於採用了網路前綴這種記法,IP地址由網路前綴和主機號這兩個部分組成,因此在路由表中的項目也要有相應的改變。這時, 每個項目由「網路前綴」和「下一跳地址」組成 。但是在查找路由表時可能會得到不止一個匹配結果。這樣就帶來一個間題:我們應當從這些匹配結果中選擇哪一條路由呢?
答案是:應當從匹配結果中 選擇具有最長網路前綴的路由 。這叫做 最長前綴匹 配longest-.prefix matching) ,這是因為網鉻前綴越長,其地址塊就越小,因而路由就越具體(more specific)。最長前綴匹配又稱為最長匹配或最佳匹配,為了說明最長前綴匹配的概念。
假定大學下屬的四系希望IS把轉發給四系的數據報直接發到四系面不要經過大學的路由器,但又不願意改變自己使用的P地址塊。因此,在SP的路由器的路由表中,至少要有以下兩個項目,即206.0.68.0/22(大學)和206.0.71.128/25(四系)。現在假定ISP收到一個數據報,其目的IP地址為D=206.0.71.130。把D分別和路由表中這兩個項目的掩碼逐位相「與」(AND操作)。將所得的逐位AND操作的結果按順序寫在下面:
D和 1111 1111 1111 1111 1111 11 00 0000 0000逐位相「與」 = 206.0.68.0/22 匹配
D和 1111 1111 1111 1111 1111 1111 1 000 0000逐位相「與」 = 206.0.71.128/25 匹配
不難看出,現在同一個IP地址D可以在路由表中找到兩個目的網路(大學和四系)和該地址相匹配。根據 最長前綴(1的位數) 匹配的原理,應當選擇後者,把收到的數據報轉發到後一個目的網路(四系),即選擇兩個匹配的地址中更具體的一個。
從以上的討論可以看出,如果IP地址的分配一開始就採用CIDR,那麼我們可以按網路所在的地理位置來分配地址塊,這樣就可大大減少路由表中的路由項目。例如,可以將世界劃分為四大地區,每一地區分配一個CIDR地址塊:
地址塊194/7(194.0.0.0至195255.255,25)分配給歐洲:
地址塊198/7(198.0.0.0至199.255.255,255)分配給北類洲
地址塊2007(200.0.0.0至201255.255.255)分配給中美洲和南美洲:
地址塊202/7(202.0.0.0至203255.255.255)分配給亞洲和太平洋地區,
上面的每一個地址塊包含有釣3200萬個地址,這種分配地址的方法就使得IP地址與地理位置相關聯。它的好處是可以大大壓縮路由表中的項目數。例如,凡是從中國發往北美的IP數據報(不管它是地址塊198/7中的哪一個地址)都先送交位於美國的一個路由器,因此在路由表中使用一個項目就行了。
使用CIDR後,由於要尋找最長前綴匹配,使路由表的查找過程變得更加復雜了。當路由表的項目數很大時,怎樣設法減小路由表的查找時間就成為一個非常重要的問題。例如,連接路由器的線路的速率為10Gbit/s,而分組的平均長度為2000bit,那麼路由器就應當平均每秒鍾能夠處理500萬個分組(常記為5Mpps)。或者說,路由器處理一個分組的平均時間只有200s(1ns=10^-9秒)。因此,查找每一個路由所需的時間是非常短的。
對無分類編址的路由表的最簡單的查找演算法就是對所有可能的前綴進行循環查找。例如,給定一個目的地址D。對每一個可能的網路前綴長度M,路由器從D中提取前M個位成一個網路前綴,然後查找路由表中的網路前綴。所找到的最長匹配就對應於要查找的路由。
"這種最簡單的演算法的明顯缺點就是查找的次數太多。最壞的情況是路由表中沒有這個路由。在這種情況下,演算法仍要進行32次(具有32位的網路前綴是一個特定主機路由)。就是要找到一個傳統的B類地址(即/16),也要查找16次。對於經常使用的歌認路由,這種演算法都要經歷31次不必要的查找。"
為了進行更加有效的查找,通常是把無分類編址的路由表存放在一種層次的數據結構中,然後自上而下地按層次進行查找。這里最常用的就是 二叉線索 (binary trie),它是一種特殊結構的樹。IP地址中從左到右的比特值決定了從根節點逐層向下層延伸的路徑,而二叉線索中的各個路徑就代表路由表中存放的各個地址。
圖4-26用一個例子來說明二叉線索的結構。圖中給出了5個IP地址。為了簡化二叉線索的結構,可以先找出對應於每一個P地址的唯一前綴(unique prefix)。所謂唯一前綴就是在表中所有的P地址中,該前綴是唯一的。這樣就可以用這些唯一前綴來構造二叉線索。在進行查找時,只要能夠和唯一前綴相匹配就行了。
從二叉線索的根節點自頂向下的深度最多有32層,每一層對應於IP地址中的一位。一個IP地址存入二叉線索的規則很簡單。先檢查IP地址左邊的第一位,如為0,則第一層的節點就在根節點的左下方;如為1,則在右下方。然後再檢查地址的第二位,構造出第二層的節點。依此類推,直到唯一前綴的最後一位。由於唯一前綴一般都小於32位,因此用唯一前綴構造的二叉線索的深度往往不到32層。圖中較粗的折線就是前綴0101在這個二叉線索中的路徑。二叉線索中的小圓圈是中間節點,而在路徑終點的小方框是葉節點(也叫做外部節點)。每個葉節點代表一個唯一前綴。節點之間的連線旁邊的數字表示這條邊在唯一前綴中對應的比特是0或1。
假定有一個IP地址是1001 1011 0111 1010 0000 0000 0000 0000,需要查找該地址是否在此二叉線索中。我們從最左邊查起。很容易發現,查到第三個字元(即前綴10後面的0)時,在二叉線索中就找不到匹配的,說明這個地址不在這個二叉線索中。
以上只是給出了二叉線索這種數據結構的用法,而並沒有說明「與唯一前綴匹配」和「與網路前綴匹配」的關系。顯然,要將二叉線索用於路由表中,還必須使二叉線索中的每一個葉節點包含所對應的網路前綴和子網掩碼。當搜索到一個葉節點時,就必須 將尋找匹配的目的地址和該葉節點的子網掩碼進行逐位「與」運算,看結果是否與對應的網路前綴相匹配 。若匹配,就按下一跳的介面轉發該分組。否則,就丟棄該分組。
總之,二叉線索只是提供了一種可以快速在路由表中找到匹配的葉節點的機制。但這是否和網路前綴匹配,還要和子網掩碼進行一次邏輯與的運算。
「為了提高二叉線索的查找速度,廣泛使用了各種 壓縮技術 。例如,在圖4-26中的最後兩個地址,其最前面的4位都是1011。因此,只要一個地址的前4位是1011,就可以跳過前面4位(即壓縮了4個層次)而直接從第5位開始比較。這樣就可以減少查找的時間。當然,製作經過壓縮的二叉線索需要更多的計算,但由於每一次查找路由表時都可以提高查找速度,因此這樣做還是值得的。」
Ⅱ 計算機網路(5)| 運輸層
從通信和處理信息的角度看,運輸層是向它上面的應用層提供通信服務的,它屬於面向通信部分的最高層,同時也是用戶功能中的最低層。當網路的邊緣部分中的兩台主機使用網路的核心部分的功能進行端到端的通信時,只有主機的協議棧才有運輸層,而網路核心部分中的路由器在轉發分組時都只用到下三層的功能。
運輸層的兩個主要協議 TCP/IP 都是互聯網的正式標准,即:
(1)用戶數據報協議UDP
(2)傳輸控制協議TCP
TCP則是面向連接的服務。在傳送數據之前必須先建立連接,數據傳送結束後要釋放連接。TCP不提供廣播或者多播服務。由於TCP要提供可靠的面向連接的運輸服務,因此需要增加很多的開銷。
TCP/IP的運輸層用一個16位埠號來標志一個埠。埠號只有本地意義。它是為了標志本計算機應用層中的各個進程在和運輸層交互時的層間介面。
運輸層的埠號分為以下兩類:
(1)伺服器端使用的埠號: 它主要分為系統埠號0~1023和登記埠號1024~49151。
(2)客戶端使用的埠號: 49152~65535,這類埠號僅在客戶端進程運行時才動態選擇。當伺服器收到客戶端進程的報文時,就知道客戶端進程的埠號。因而可以把數據發送給客戶進程。
用戶數據報協議相比於IP的數據報服務就是只增加了復用、分用和差錯檢測功能。UDP的主要特點是:
(1)UDP是無連接的, 發送數據之前不需要建立連接,因此減少開銷和發送數據之前的時延。
(2)UDP使用盡最大努力交付, 即不保證可靠交付,因此主機不需要維持復雜的連接狀態表。
(3)UDP是面向報文的。 發送方的UDP對應用交下來的報文,添加首部後就向下交付給IP層。不對報文做任何處理,因此當報文過長時,IP層可能需要進行分片處理。
(4)UDP沒有擁塞控制, 網路出現的擁塞不會使源主機的發送速率減低。
(5)UDP支持一對一、一對多、多對一和多對多的交互通信。
(6)UDP的首部開銷小, 只有8個位元組。
UDP有兩個欄位:數據欄位和首部欄位。先介紹首部欄位,它是由4個欄位組成的,每個欄位只有2個位元組,總共有8個位元組。各個欄位的意義如下:
(1)源埠: 源埠號。在需要對方回信時選用。不需要時可用全0。
(2)目的埠: 目的埠號。在這終點交付報文時必須使用。
(3)長度: UDP用戶數據報的長度,其最小值是8(只有首部)。
(4)檢驗和: 檢測UDP用戶數據報在傳輸中是否有錯,有錯則丟棄。
當在傳送用戶數據報時,如果接收方UDP發現收到的報文中目的埠號不正確(即不存在對應於該埠號的應用進程),就丟棄該報文,並由網際控制報文協議ICMP發送「埠不可達」差錯報文給發送方。
TCP的主要特點如下:
(1)TCP是面向連接的運輸層協議。 應用程序在使用TCP協議之前,必須先建立TCP連接。傳送數據完畢後,必須釋放TCP連接。
(2)每一條TCP連接只能有兩個端點。 每一條TCP連接只能是點對點的。
(3)TCP提供可靠交付的服務。 通過TCP連接傳送的數據,無差錯、不丟失、不重復,並且按序到達。
(4)TCP提供全雙工通信。 TCP允許通信雙方的應用進程在任何時候都能發送數據。
(5)面向位元組流。 TCP中的流指的是流入到進程或進程流出的位元組序列。雖然應用程序和TCP的交互是一次一個數據塊,但TCP把應用程序交下來的數據看成一連串的無結構的位元組流。TCP不保證發送方發送的數據塊和接收方接收的數據塊一致,但保證程序接收到的位元組流和程序發送的位元組流一致。
TCP連接的端點叫做套接字或者插口。套接字是指將埠號拼接到IP地址之後,即:
每一條TCP連接唯一的被通信兩端的兩個端點所確定。即:
如圖所示,A發送分組M1,發送完畢就暫停發送,等待B的確認,B收到了M1就向A發死你確認。A在收到了對M1的確認之後,就再發送下一個分組M2,以此類推。
如圖所示,當B接收M1時檢測出了差錯,就丟棄M1,其他什麼也不做。而A只要超過了一段時間沒有收到確認,就會認為剛才發送的分組丟失了,因而重傳前面發送過的分組,這就叫做超時重傳,而實現超時重傳則需要A為每一個已發送的分組都設置一個超時計時器。
需要注意以下三點:
(1)A在發送完一個分組後,必須暫時保留已發送的分組的副本。
(2)分組和確認分組必須編號,這樣才能明確哪一個發出的分組收到了確認。
(3)超時計時器設置的重傳時間應當比數據在分組傳輸的平均往返時間更長。
如圖所示,B所發送的對M1確認丟失了,A在設定的超時重傳時間內沒有收到確認,所以無法知道自己發送的分組是怎樣出錯的,所以會重傳M1,而當B又收到了重傳的分組M1,這時應該採取兩個行動:
(1)丟棄這個重復分組M1。
(2)向A發送確認。
還有一種情況就是在傳輸過程中沒有出現差錯,但B對分組M1的確認遲到了,而A會收到重復的確認,A收下後就會丟棄,B仍然會收到重復的M1,並且同樣要丟棄重復的M1,並且重傳確認分組。
停止等待協議的優點是簡單,缺點則是信道的利用率太低。我們用TD表示A發送分組需要的時間,TA表示B發送確認分組需要的時間,RTT為往返時間,則:
為了提高傳輸的效率,發送方可以不使用低效率的停止等待協議,而是採用流水線傳輸的方式。即不必每發完一個分組就停下來等待對方的確認,這樣就可以使信道上一直有數據在不間斷的傳送。
如圖表示的是發送方維持的發送窗口,它指的是位於發送窗口內的5個分組都可以連續發送出去而不需要等待對方的確認。同時連續ARP協議規定,發送方每收到一個確認,就把發送窗口向前滑動一個分組的位置。
對於接收方採用的則是累計確認的方式,即接收方不必對收到的分組逐個發送確認。而是在收到幾個分組後,對按序到達的最後一個分組發送確認,這就表示:到這個分組為止的所有分組都已正確收到了。這種方式的優點是:容易實現,即使確認丟失也不必重傳(意思是發送方不必重傳)。但缺點是不能向發送方反映出接收方已經正確收到的所有分組信息。
TCP雖然是面向位元組流的,但傳送TCP的數據單元卻是報文段。一個TCP報文段可以分為首部和數據兩部分。
為了後面講述的方便,我們假設數據傳輸只在一個方向進行,即A發送數據,B給出確認。
TCP的滑動窗口是以位元組為單位的。如圖所示,現在假定A收到了B發來的確認報文段,其中的窗口是20位元組,而確認號是31,根據這2個數據,A就構造出自己的發送窗口。
發送窗口表示:在沒有收到B的確認的情況下,A可以連續把窗口內的數據都發送出去。凡是已經發送過的數據,在未收到確認之前都必須暫時保留,以便在超時重傳時使用。發送窗口後面的部分表示已發送且已經收到了確認。而發送窗口前沿的部分表示不允許發送的。
現在假定A發送了序號為31~41的數據。這時發送窗口位置並未改變但是發送窗口內靠後面有11個位元組表示已發送但是未收到確認。而發送窗口內靠前面的9個位元組時允許發送但未發送的。如圖所示:
而對於B,它的接收窗口大小是20,在接收窗口外面到30號位置的數據是接收並確認的,因此可以丟棄。在下圖中,B收到了32和33的數據,但它們不是按序到達的,因為並沒有收到31號數據。B只能對按序達收到的數據中的最高序號給出確認,因此B發送的確認報文欄位的確認號依然是31號。
現在假定B收到了序號為31的數據,並把31~33的數據交付主機,然後B刪除這些數據。接著把窗口向前移動3個序號,同時給a發送確認,其中的窗口值仍為20,但確認號變為34。表明B已經收到序號33為止的數據。
因為TCP的發送方在規定的時間內沒有收到確認就要重傳已經發送的報文段,但是重傳時間的選擇卻TCP最復雜的問題之一。為此TCP採用了一種自適應演算法,它記錄了一個報文段發出的時間以及收到相應的確認的時間。這兩個時間之差就是報文段的往返時間RTT,同時TCP保留了RTT的加權平均往返時間RTTs。而RTTD是RTT的偏差加權平均值,它與RTTs和新的RTT樣本之差有關。
超時重傳時間的演算法如下:
第一次測量時,加權平均往返時間取往返時間RTT,以後每次測量到一個新的RTT,按以下公式計算:
第一次測量時,RTT偏差的加權平均等於RTT的一半,以後的測里中,按以下公式計算:
綜上超時重傳時間RTO計算如下:
若收到的報文無差錯,只是未按序號,使用選擇確認SACK可是讓發送方發送那些未收到的數據,而不重復發送已經收到的那些數據。如果要使用選擇確認SACK,那麼在建立TCP連接時,就要在TCP首部的選項中加上「允許SACK」的選項,並且雙方必須都事先商量好。
流量控制就是指讓發送方的發送速率不要太快,要讓接收方來得及接收。而利用滑動窗口機制就可以很方便的在TCP連接上實現對發送方的流量控制。
如上圖所示,接收方B進行了三次流量控制。第一次把窗口減小到rwnd=300,第二次又減到rwnd=100,最後是rwnd=0,即不允許發送方再發送數據了。
但是我們應該考慮一種情況,就是當接收方B的存儲已滿時,會向發送方發送零窗口的報文段,接著B的存儲又有了一些空間,B再向A發送一個不為零的窗口值,但這個報文丟失了,結果就是雙方一直等待下去。所以為了解決這個問題,TCP為每一個連接設有一個持續計時器。只要TCP連接的一方收到對方的零窗口通知,就啟動持續計時器,當計時器到期後,就發送一個探測段文段,而對方就在確認這個探測段時給出了現在的窗口值。如果窗口仍然是0,那麼收到這個報文段的一方就重新設置持續計時器,反之則死鎖的僵局就可以打破了。
應用程序把數據傳送到TCP的發送緩存後,TCP在何時發送這些數據?,在TCP的實現中廣泛使用了Nagle演算法。具體演算法如下:
(1)若發送應用進程要把數據逐個位元組地送到TCP的發送緩存,則發送方就把第一個數據位元組先發出去,把後面到達的數據位元組都緩存起來。
(2)方發送方收到對第一個數據位元組的確認後,再把發送緩存中的所有數據組裝成一個報文發送出去,同時繼續對後續到來的數據進行緩存。
(3)只有收到對前一個報文段的確認後才繼續發送下一個報文段。
當數據到達快而網路速度慢時,這種方法可以明顯減少網路帶寬。Nagle還規定:當到達的數據達到窗口的一半或最大報文長度時就立即發送一個報文。
但還還需要考慮一個叫做糊塗綜合征的問題,具體內容是若接收方的緩存已滿,應用進程每次只從緩存中取1個位元組,然後向發送方確認,並把窗口設為1個位元組(緩存只空了1個位元組的空間),接著發送方發來1個位元組,接收方發回確認,仍然將窗口設為1,這樣進行下去,網路的利用率很低。
為了解決這個問題,可以讓接收方等待一段時間,使得或者緩存已有足夠的空間或者等到接收緩存已有一半的空閑空間。此時,接收方就發出確認報文,並向發送方通知當前窗口的大小。
擁塞 是指在某一段時間內,若對網路中某一資源的需求超過了該資源所能提供的可用部分,網路的性能就會變壞的情況。而所謂的 擁塞控制 就是防止過多的數據注入到網路當中,這樣可以使網路中的路由器或者鏈路不致過載,它是一個全局性的過程,涉及到所有的主機和路由器,而流量控制往往是指點對點通信量的控制。擁塞控制所要做的都有一個前提,就是網路能夠承受現有的網路負荷。
TCP進行擁塞控制的演算法有4種:慢開始、擁塞避免、快重傳和快恢復。下面在討論這些演算法時我們假定:
(1)數據是單方向傳送的,對方只傳送確認報文。
(2)接收方總是有足夠大的緩存空間。
發送方維持一個擁塞窗口的狀態變數,其大小取決於擁塞程度,並且動態變化。發送方讓自己的發送窗口小於擁塞窗口(如果考慮接收方的接收能力的話,發送窗口可能小於擁塞窗口)。發送方控制擁塞窗口的原則是:只要網路沒有擁塞,擁塞窗口就再增大一點,以便把更多的分組發送出去,只要出現擁塞,就減小擁塞窗口,以減少注入到網路的分組數。
下面會從「慢開始演算法」講起來討論擁塞窗口的大小如何變化的。
慢開始的演算法思路是:當主機開始發送數據時,由於並不清楚網路的負荷情況,所以如果立即把大量數據位元組注入到網路中,就有可能引起網路擁塞。因此會採用由小逐漸增大發送窗口。即在通常開始發送報文時,先將擁塞窗口cwnd的值設為一個最大報文段MSS的數值,而在每收到一個新的報文段確認後,把擁塞窗口增加至多一個MSS的數值。
如上圖所示,開始時cwnd=1,發送方發送一個M1,接收方收到M1發送確認,發送方收到一個確認後將cwnd加1,此時cwnd=2,因此發送方發送M2和M3兩個報文段,接收方收到後返回兩個確認,因此cwnd增加兩次,此時cwnd=4,接著發送方發送M4~M7四個報文段。依次類推。因此使用慢開始演算法後,每經過一個傳輸輪次,擁塞窗口就加倍。
但是為了防止擁塞窗口cwnd增加過大導致網路擁塞,需要設置一個慢開始門限ssthresh,慢開始門限用法如下:
當cwnd<ssthresh時,使用上述的慢開始演算法。
當cwnd>ssthresh時,停止使用慢開始演算法,使用擁塞避免演算法。
當cwnd=ssthresh時,既可以使用慢開始演算法,也可以使用擁塞避免演算法。
這里的擁塞避免演算法是指讓擁塞窗口緩慢的增大,即每經過一個往返時間RTT就把發送方的擁塞窗口cwnd加1,而不是像慢開始階段那樣加倍增長。
需要注意的是無論在慢開始階段還是擁塞避免階段,只要發送方判斷網路出現擁塞(根據是沒有按時收到確認),立即把慢開始門限ssthresh設為出現擁塞時的發送窗口的一半。然後發送窗口cwnd重新設為1,執行慢開始演算法。目的是迅速減少主機發送到網路分組的分組數。
快重傳演算法要求接收方每收到一個失序的報文段後就立即發送重復確認,如下圖接收了M1和M2後,又接收到一個M4,M4屬於失序報文,則發送對M2的重復確認。發送方只要連續收到三次確認重復就立即重傳對方未收到的報文段M3。
與快重傳演算法配合的還有快恢復演算法,過程如下:
(1)當發送方連續收到三個重復確認時,就把慢開始門限ssthresh減半,這是為了防止網路擁塞,接著並不執行慢開始演算法。
(2)由於上圖這種情況很可能不是因為網路擁塞引起的,因此這里不執行慢開始演算法(即不把擁塞窗口cwnd設為1,這樣速度太慢),而是把cwnd值設置為慢開始門限ssthresh減半後的數值,然後開始執行擁塞避免演算法。
TCP的運輸連接有是三個階段:連接建立、數據傳送和連接釋放。在TCP的連接過程中要解決以下三個問題:
(1)要使每一方能夠確知對方的存在。
(2)要允許雙方協商一些參數(如最大窗口值、是否使用窗口擴大選項和時間戳選項以及服務質量)。
(3)能夠對運輸實體資源進行分配。
TCP建立連接的過程叫做握手,握手需要在客戶和伺服器之間交換3個TCP報文段。如圖是三報文握手建立的連接過程:
A最後還要發送一次確認的原因是為了防止已經失效的連接請求報文段突然又傳送到了B,因而產生錯誤。試想一種情況:如果只有第一次和第二次握手,第二次B向A發送的確認丟失了,此時B進入了連接建立狀態,A沒有收到確認,過一段時間後會再次向B發送連接請求,B收到後又會再次建立連接,白白浪費B的資源。
A在TIME-WAIT狀態等待2MSL(MSL,最長報文段壽命),主要是因為以下兩點考慮:首先是為了保證A發送的最後一個ACK報文段能夠到達B,因為這個ACK報文段可能丟失,此時B會重傳連接釋放報文,如果A已經關閉,則無法收到這個報文。其次,當A在發送完最後一個ACK報文段後,再經過時間2MSL,就可以使本連接持續時間內產生的所有報文段都從網路中消失。這樣,下一個新連接中不會出現這種舊的連接請求報文段。
在圖中每一個方框即TCP可能具有的狀態。每個方框中的大寫英文字元串時TCP標准所使用的的TCP連接狀態名。狀態之間的箭頭表示可能發生的狀態變遷。箭頭旁邊的字表明引起這種變遷的原因,或表明發生狀態變遷後又出現什麼動作,在圖中粗實線箭頭表示對客戶進程的正常變遷,粗虛線箭頭表示對伺服器進程的正常變遷,細線箭頭表示異常變遷。