傳輸協(xié)議(transport protocol)是整個網(wǎng)絡(luò)體系結(jié)構(gòu)中的關(guān)鍵之一。本章討論TCP/IP體系中的運輸協(xié)議UDP和TCP。TCP比UDP復雜得多。最重要的是應弄清端口的概念及TCP的各種機制(如面向連接的可靠服務、序號、確認、窗口、擁塞控制等)以及TCP有關(guān)連接管理和狀態(tài)圖的概念。
從通信和信息處理的角度.運輸層向它上面應用層提供通信服務,它屬于面向通信部分的最高層,同時也是用功能中的最低層、運輸層只存在于通信子網(wǎng)以外的主機中,在
通信子網(wǎng)中沒有運輸層,如圖8-所示。
下面通過圖8-1的示意圖來說明運輸層的作用。設(shè)局域網(wǎng)1上的主機A和局域網(wǎng)2上的主機B通過互連的廣域網(wǎng)進行通信。既然IP協(xié)議能夠?qū)⒃粗鳈C發(fā)送出的分組按照首部中的目的地址送交到目的主機,那么,為什么還需要再設(shè)置一個運輸層呢
圖8-1 傳輸層為相互通信的應用進程提供了邏輯通信
嚴格地講,兩個主機進行通信實際上就是兩個主機中的應用進程互相通信。IP協(xié)議雖然能把分組送到目的主機,但是這個分組還停留在主饑的網(wǎng)絡(luò)層而沒有交付給主機中的應用進程(請注意:IP地址是標識在因特網(wǎng)中的—個主機,而不是標識主機中的應用進程)。然而一個主機中經(jīng)常有多個應用進程同時分別和另一個主機中的多個應用進程通信。例如,某用戶在使用瀏覽器查找某網(wǎng)站的信息時,其主機的應用層運行瀏覽器客戶進程。如果在瀏覽網(wǎng)頁的同時,還要用電子郵件給網(wǎng)站發(fā)送反饋意見,那么主機的應用層就還要運行電子郵件的客戶進程:在圖8-1中,主機A的應用進程l和主機B的應用進程3通信,而與此同時,應用進程2也和對方的應用進程4通信。運輸層的—個很重要的功能就是復用和分用。應用層不同進程的報文通過不同的端口(在8.2.2節(jié)還要詳細討論端口的概念)向下交到運輸層,再往下就共用網(wǎng)絡(luò)層提供的服務。當這些報文沿著圖中的虛線到達目的主機后,目的主機的運輸層就使用其分用功能,通過不同的端口將報文分別交付到相應的應用進程。圖8-2中兩個運輸層之間有一個粗的雙向箭頭,寫明“運輸層提供應用進程間的邏輯通信”。“邏輯通信”的意思是:應用進程的報文到達運輸層后,從效果上看,就好像是直接沿水平方向傳送到遠地的運輸層。當然事實上這兩個應用進程之間并沒有一條水平方向的物理連接。要傳送的數(shù)據(jù)是沿著圖中的虛線方向傳送的。
從這里可以看出網(wǎng)絡(luò)層和運輸層有很大的區(qū)別。運輸層為應用進程之間提供邏輯通信,但網(wǎng)絡(luò)層是為主機之間提供邏輯通信,如圖8-2所示。如果運輸層只有這—點復用和分用功能,那么取消運輸層而讓網(wǎng)絡(luò)層增加這一點功能也未嘗不可。然而,運輸層還具有網(wǎng)絡(luò)層無法代替的許多其他重要功能。
圖8-2 運輸層協(xié)議和網(wǎng)絡(luò)層協(xié)議的主要區(qū)別
其次,運輸層還要對收到的報文進行差錯檢測。大家應當還記得,在網(wǎng)絡(luò)層,IP數(shù)據(jù)報首部中的檢驗和字段,只檢驗首部是否出現(xiàn)差錯而不檢查數(shù)據(jù)部分。
圖8-3 運輸層與其上下層之間的關(guān)系的OSI表示法
再次,根據(jù)應用的不同,運輸層需要有兩種不同的運輸協(xié)議,即面向連接的TCP和無連接的UDP,而網(wǎng)絡(luò)層無法同時實現(xiàn)這兩種協(xié)議。
OSI使用了簡潔的抽象方法將運輸層與其上下層之間的關(guān)系歸納如圖8-3所示。
根據(jù)OSI的觀點,運輸層中向應用層提供運輸服務的是運輸實體。使用運輸服務的是運輸服務用戶(也就是應用層中的各種應用進程,或應用層實體,但不是使用計算機的最終用戶)。運輸層中的兩個對等運輸實體之間的通信遵循著運輸協(xié)議。運輸協(xié)議保證了運輸層能夠向應用層提供運輸服務。運輸層提供的運輸服務也使用了下面網(wǎng)絡(luò)層向上提供的網(wǎng)絡(luò)服務。TSAP和NSAP分別是運輸層和網(wǎng)絡(luò)層的服務訪問點,它們都是層與層之間交換信息的抽象
接口。
我們要再次強調(diào)指出,運輸層向高層用戶屏蔽了下面通信子網(wǎng)的細節(jié)(如網(wǎng)絡(luò)拓撲、所采用的協(xié)議等),它使應用進程看見的就是好像在兩個運輸層實體之間有一條端到端的邏輯通信信道,但這條邏輯通信信道對上層的表現(xiàn)卻因運輸層使用的不同協(xié)議而有很大的差別。當運輸層采用面向連接的TCP協(xié)議時,盡管下面的網(wǎng)絡(luò)是不可靠的(即只提供盡最大努力服務),但這種邏輯通信信道就相當于一條全雙工的可靠信道。但當運輸層采用無連接的UDP協(xié)議時,這種邏輯通信信道則是一條不可靠信道。在圖8-4中我們將可靠信道畫成一個管道,這意味著報文在這樣的“管道”中運輸時,可以做到無差錯、按序(接收的順序和發(fā)送的順序一樣)、無丟失和無重復。對不可靠信道就用一個云狀網(wǎng)絡(luò)來表示,它不具備可靠倍道的按序、無丟失和無重復的特性,但仍具有無差錯的特性。只要檢查出報文有差錯就將其丟棄。最后再強調(diào)一下,我們說運輸層提供可靠的交付,是指運輸層將數(shù)據(jù)可靠地交付給接收端的應用層,但應用層是否再可靠地交付給最終用戶,現(xiàn)在還不知道。
圖8-4運輸層向上提供可靠的和不可靠的邏輯通信信道
TCP/IP的運輸層有兩個不同的協(xié)議,如圖8-5所示,它們都是因特網(wǎng)的正式標準。即:(1)用戶數(shù)據(jù)報協(xié)議UDP(User Datagram Protocol):見[RFC 793]。
(2)傳輸控制協(xié)議TCP(Transmission Control Protocol):見[RFC 768]。
按照OSI的術(shù)語,兩個對等運輸實體在通信時傳送的數(shù)據(jù)單位叫做運輸協(xié)議數(shù)據(jù)單元TPDU(Transport Protocol Data Unit)。但在TCP/IP體系中,則根據(jù)所使用的協(xié)議是TCP或UDP,分別稱之為TCP報文段(segment)或UDP報文或用戶數(shù)據(jù)報。
UDP在傳送數(shù)據(jù)之前不需要先建立連接。遠地主機的運輸層在收到UDP報文后,不需要給出任何確認。雖然UDP不提供可靠交付,但在某些情況下UDP是—種最有效的工作方式。TCP/IP體系中的應用服務,如DNS和NFS就使用UDP這種運輸方式。
圖8-5 TCP/IP 體系中的運輸層協(xié)議
TCP則提供面向連接的服務。在傳送數(shù)據(jù)之前必須先建立連接,數(shù)據(jù)傳送結(jié)束后要釋放連接。即不提供廣播或多播服務。由于TCP要提供可靠的、面向連接的運輸服務,因此不可避免地增加了許多的開銷,如確認、流量控制、計時器以及連接管理等。這不僅使協(xié)議數(shù)據(jù)單元的首部增大很多,還要占用許多的處理機資源。
這里還要強調(diào)兩點:
(1)運輸層的UDP用戶數(shù)據(jù)報與網(wǎng)際層的IP數(shù)據(jù)報有很大的區(qū)別。IP數(shù)據(jù)報要經(jīng)過互連網(wǎng)中許多路由器的存儲轉(zhuǎn)發(fā),但UDP用戶數(shù)據(jù)報是在運輸層的端到端抽象的邏輯信道中傳送的。這個邏輯信道雖然也是盡最大努力交付(因而不可靠),但運輸層的這個邏輯信道并不經(jīng)過路由器(運輸層看不見路由器),因為路由器只有下三層協(xié)議而沒有運輸層。IP數(shù)據(jù)報雖然經(jīng)過路由器進行轉(zhuǎn)發(fā),但用戶數(shù)據(jù)報只是IP數(shù)據(jù)報中的數(shù)據(jù),因此路由器看不見有用戶數(shù)據(jù)報經(jīng)過它。這兩種數(shù)據(jù)報不能弄混。
(2)TCP連接也和網(wǎng)絡(luò)層中的虛電路(X.25所使用的)完全不同。TCP報文段是在運輸層的端到端抽象的邏輯信道中傳送,但TCP連接是可靠的全雙工信道,不涉及到互連網(wǎng)中的路由器。這些路由器根本不知道上面的運輸層建立了多少個TCP連接。然而在X.25建立的虛電路所經(jīng)過的交換結(jié)點中,都要保存X.25虛電路的狀態(tài)信息。
UDP和TCP都使用了與應用層接口處的端口(port)與上層的應用進程進行通信。端口是個非常重要的概念,因為應用層的各種進程是通過相應的端口與運輸實體進行交互。當運輸層收到IP層交上來的數(shù)據(jù)(即TCP報文段或UDP用戶數(shù)據(jù)報)時,就要根據(jù)其中首部的端口號來決定應當通過哪—個端口上交給應當接收此數(shù)據(jù)的應用進程。圖8-6說明了端口在進程之間的通信中所起的作用。
用OSI的術(shù)語,圖中的端口就是運輸層服務訪問點TSAPC可以看出,若沒有端口,運輸層就無法知道數(shù)據(jù)應當交付給應用層的哪一個進程。從這個意義上講,端口是用來標識應用層的進程。由于使用了復用和分用技術(shù),在運輸層與網(wǎng)絡(luò)層的交互中已看不見各種應用進程,而只有TCP報文段或用戶數(shù)據(jù)報。IP層也使用類似的復用和分用技術(shù),因而在網(wǎng)絡(luò)層和鏈路層的交互中也只有IP數(shù)據(jù)報。上述概念在網(wǎng)絡(luò)中是十分重要的。
圖8-6端口在進程之間的通信中所起的作用
在運輸層與應用層的接口上所設(shè)置端口是一個16 bit的地址,并用端口號進行標識。端口就是一個抽象的定位符,有時也可稱為郵箱(mailbox)。端口的基本概念就是:應用層的源進程將報文發(fā)送給運輸層的某個端口,而應用層的目的進程從端口接收報文。端口號只具有本地意義。即端口號只是為了標識本計算機應用層中的各進程。不同計算機中的相同端口號是沒有聯(lián)系的。16比的端口號可允許有64K個端口號,這個數(shù)目對一個計算機來說是足夠用的。
端口號分為兩類。一類是由因特網(wǎng)指派名字和號碼公司I。ANN負責分配給—些常用的應用層程序固定使用的熟知端口(well-known port),其數(shù)值一股為0~l023,見[RFC1700]。例如,F(xiàn)TP用21,TELNET用23,SMTP用25,DNS用53,HTTP用80,SNMP用161,等等。“熟知”就表示這些端口號是TCP/IP體系確定并公布的,因而是所有用戶進程都知道的。當一種新的應用程序出現(xiàn)時,必須為它指派一個熟知端口,否則其他的應用進程就無法和它進行交互。在應用層中的各種不同的服務器進程不斷地檢測分配給它們的熟知端口,以便發(fā)現(xiàn)是否某個客戶進程要和和它通信。另一類則是一般端口,用來隨時分配給請求通信的客戶進程。
圖8-8舉例說明了端口的作用。設(shè)主機A使用簡單郵件傳送協(xié)議SMTP與主機。通信。SMTP使用而向連接的TCPC為了找到目的主機中的SMTP,主機A與主機。建立的連接要使用目的主機中的熟知端口,其端口號為25。主機A也要給自己的進程分配一個端口號,設(shè)分配的源端口號為1500。這就是主機A和主機。建立的第一連接。圖中的連接畫成虛線,表示這種連接不是物理連接而只是個虛連接(即邏輯連接)。
現(xiàn)在主機A中的另一個進程也要和主機。中的SMTP建立連接。目的端口號仍為25,但其源端口號不能與上一個連接的重復。設(shè)主機A分配的這個源端口號為1501。這是主機A和主機。建立的第二個連接。
設(shè)主機B現(xiàn)在也要和主機C的SMTP建立連接,端口號當然還是25。主機B選擇源端口號為1500。這是和主機C建立的第三個連接。這里的源端口號與第一個連接的源端口號相同,但純屬巧合。各主機都獨立地分配自已的端口號。
為了在通信時不致發(fā)生混亂,就必須把端口號和主機的IP地址結(jié)合在—起使用,在圖8-8中,主機A和B雖然都使用了相同的源端口號1500.但只要查一下IP地址就可知道是哪一個主機的數(shù)據(jù)。
因此,TCP使用“連接”(而不僅僅是“端口”)作為最基本的抽象。一個連接由它的兩個端點來標識。這樣的端點就叫做插口(socket)或套接字。插口的概念并不復雜,但非常重要。插口包括IP地址(32 bit)和端口號(16 bit),共48 bit。插口和端口、IP地址的關(guān)系如圖8-9所示。
在整個因特網(wǎng)中,在運輸層通信的一對插口必須是惟一的。例如:對圖8-8中的連接1的一對插口是:
(131.6.23.13,1500)和(130.42.85.15,25)
意思是:IP地址為131.6.23.13的主機用端口1500和IP地址為130.42.85.15的主機端口25建立了連接1,而連接2的一對插口是:
(131.6.23.13,1501和(230.42.85.15,25)
意思是:IP地址為131.6.23.13的土機用端口1501和IP地址為130.42.85.15的主機的端口25建立了連接2。
上面的例子是使用面向連接的TCP。若使用無連接的DDP,雖然在相互通信的兩個進程之間沒有一條虛連接,但發(fā)送端UDP一定有一個發(fā)送端口而在接收端UDP一定有—個接收端口,因而也同樣可使用插口的概念。這樣才能區(qū)分多個主機中同時通信的多個進程。
值得注意的是,插口這個名詞很容易讓人將一些概念弄混淆,因為同一個名詞socket有多種不同的意思。例如:
(1)允許應用程序訪問連網(wǎng)協(xié)議的應用編程接口API(Application Programming Interface),也就是在運輸層和應用層之間的—種接口,稱為socket API,并簡稱為socket。
(2)在socket API中使用的—個函數(shù)名也叫做socket。
(3)調(diào)用socket函數(shù)的端點稱為socket,如“創(chuàng)建—個數(shù)據(jù)報socket”。
(4)socket函數(shù)的返回值稱為socket描述符,可簡稱為socket。
(5)在操作系統(tǒng)內(nèi)核中連網(wǎng)協(xié)議的Berkeley實現(xiàn)稱為socket實現(xiàn)。
上面的這些socket的意思都和本章中的socket(指IP地址和端口號的組合)不同。
本節(jié)將分別介紹UDP和TCP的要點。由于UDP很簡單,因而本節(jié)以討論TCP為重點。
用戶數(shù)據(jù)報協(xié)議UDP只在IP的數(shù)據(jù)報服務之上增加了很少—點的功能,這就是端口的功能(有了端口,運輸層就能進行復用和分用)和無差錯檢測的功能。雖然UDP用戶數(shù)據(jù)報只能提供不可靠的交付,但UDP在某些方面有其特殊的優(yōu)點,例如:
(1)發(fā)送數(shù)據(jù)之前不需要建立連接(當然發(fā)送數(shù)據(jù)結(jié)束時也沒有連接需要釋放),因而減少了開銷和發(fā)送數(shù)據(jù)之前的時延。
(2)UDP沒有擁塞控制,也不保證可靠交付,因此主機不需要維持具有許多參數(shù)的、復雜的連接狀態(tài)表。
(3)UDP用戶數(shù)據(jù)報只有8個字節(jié)的首都開銷,比TCP的20個字節(jié)的首部要短。
(4)由于UDP沒有擁塞控制,因此網(wǎng)絡(luò)出現(xiàn)的擁塞不會使源主機的發(fā)送速率降低。這對某些實時應用是很重要的。很多的實時應用(如IP電話、實時視頻會議等)要求源主機以恒定的速率發(fā)送數(shù)據(jù),并且允許在網(wǎng)絡(luò)發(fā)生擁塞時丟失一些數(shù)據(jù),但不允許數(shù)據(jù)有太大的時延。UDP正好適合這種要求。
雖然某些實時應用需要使用沒有擁塞控制的UDP,但當很多的源主機同時都向網(wǎng)絡(luò)發(fā)送高速率的實時視頻流時,網(wǎng)絡(luò)就有可能發(fā)生擁塞,結(jié)果大家都無法正常接收。因此“UDP不具有擁塞控制功能”,可能會引起網(wǎng)絡(luò)產(chǎn)生嚴重的擁塞問題。
還有些使用UDP的實時應用需要對UDP的不可靠的傳輸進行適當?shù)母倪M以減少數(shù)據(jù)的丟失。在這種情況下,應用進程本身可在不影響應用的實時性的前提下增加一些提高可靠性的措施,如采用前向糾錯或重傳已丟失的報文。
用戶數(shù)據(jù)報UDP有兩個字段:數(shù)據(jù)字段和首都字段。首部字段很簡單,只有8個字節(jié)如圖8-11所示,由4個字段組成,每個字段都是兩個字節(jié)。各字段意義如下所述。
(1)源端口字段:源端口號。
(2)目的端口字段:目的端口號。
(3)長度字段:UDP用戶數(shù)據(jù)報的長度。
(4)檢驗和字段:防止UDP用戶數(shù)據(jù)報在傳輸中出錯。
圖8-7 UDP用戶數(shù)據(jù)報的首部和偽首部
UDP用戶數(shù)據(jù)報首都中檢驗和的計算方法有些特殊。在計算檢驗利時在UDP用戶數(shù)據(jù)報之前要增加12個字節(jié)的偽首部。所謂“偽首部”是因為這種偽首部并不是UDP用戶數(shù)據(jù)報真正的首部。只是在計算檢驗和時,臨時和UDP用戶數(shù)據(jù)報連接在一起,得到一個過渡的UDP用戶數(shù)據(jù)報。檢驗和就是按照這個過渡的UDP用戶數(shù)據(jù)報來計算的,偽首部既不向下傳送,也不向上遞交。圖8-7的最上面給出了偽首部各字段的內(nèi)容。
UDP計算檢驗和的方法和計算IP數(shù)據(jù)報首都檢驗和的方法相似。在發(fā)送端,首先是先將全零放入檢驗和字段。再將偽首部以及UDP用戶數(shù)據(jù)報(現(xiàn)在要包括數(shù)據(jù)字段]看成是由許多16 bit的字串接起來。若UDP用戶數(shù)據(jù)報的數(shù)據(jù)部分不是偶數(shù)個字節(jié)則要填入一個全零字節(jié)(但此字節(jié)不發(fā)送)。然后按二進制反碼計算出這些16 bit字的和。將此和的二進制反碼寫入檢驗和字段后,發(fā)送此UDP用戶數(shù)據(jù)報。在接收端,將收到的UDP用戶數(shù)據(jù)報連同偽首部(以及可能的填充全零字節(jié))一起,按二進制反碼求這些16 bit字的和。當無差錯時其結(jié)果應為全1。否則就表明有差錯出現(xiàn),接收端就應將此UDP用戶數(shù)據(jù)報丟棄(也可以上交給應用層,但附上出現(xiàn)了差錯的警告)。圖8-12給出了一個計算UDP檢驗和的例子。這里假定用戶數(shù)據(jù)報的長度是15字節(jié),因此要添加一個全0的字節(jié),讀者可以自己檢驗一下在接收端是怎樣對檢驗和進行檢驗的。不難看出,這種簡單的差錯檢驗方法的檢錯能力并不強,但它的好處是簡單,處理起來較快。
偽首都的第3字段是全0,第4個字段是IP首部中的協(xié)議字段的值。以前已講過,對于UDP,此協(xié)議字段值為17,第5字段是UDP用戶數(shù)據(jù)報的長度。因此我們可以看出,這樣的檢驗和,既檢查了UDP用戶數(shù)據(jù)報的源端口號、日的端門號以及UDP用戶數(shù)據(jù)報的數(shù)據(jù)部分,又檢查了IP數(shù)據(jù)報的源IP地址和目的址址。
TCP/IP體系中面向連接的運輸層協(xié)議,它提供全雙工的可靠交付的服務。一定要記?。篢CP與UDP最大的區(qū)別就是TCP是面向連接的,而UDP是無連接的。下面先介紹TCP的報文段首部的格式,然后再討論保證數(shù)據(jù)傳送可靠、按序、無丟失和元重復的一些機制。
傳輸?shù)目煽渴怯捎谑褂昧诵蛱柡痛_認。當TCP發(fā)送一報文段時,它同時也在重傳隊列中放入一個副本。若收到確認,則刪除此副本。若在計時器時間到之前沒有收到確隊,則重傳此報文段。TCP的確認并不保證數(shù)據(jù)已交付給端用戶,這是接收TCP的責任。
圖8-11 TCP報文段的首部
一個TCP報文段分為首部和數(shù)據(jù)兩部分,如圖8-11所示。應當指出,TCP的全部功能都體現(xiàn)在它的首都的各字段。本節(jié)先大致介紹各字段的作用,然后在后續(xù)的幾節(jié)還要結(jié)合相關(guān)的字段詳細討淪TCP的主要機制。
TCP報文段首都的前20個字節(jié)是固定的,后面有4 N字節(jié)是根據(jù)需要而增加的選項(N必須是整數(shù))。因此TCP首部的最小長度是20字節(jié)。首部固定部分各字段的意義如下所述。
(1)源端口和目的端口
各占兩個字節(jié),前面已經(jīng)講過,端口是運輸層與應用層的服務接口。16 bit的端口號加上32 bit的IP地址,構(gòu)成了插口(socket),它相當于運輸層服務訪問點TSAP的地址(總共是48bit)。這些端口用來將若干高層協(xié)議向下復用,也用來將運輸層協(xié)議向上分用。
(2)序號
占4字節(jié)。TCP是面向數(shù)據(jù)流的,TCP傳送的報文可看成為連續(xù)的數(shù)據(jù)流,其中每一個字節(jié)都對應于一個序號。首部中的“序號”則指的是本報文段所發(fā)送的數(shù)據(jù)中第一個字節(jié)的序號,例如,某報文段的序號字段的值是30l,而攜帶的數(shù)據(jù)共100字節(jié),則本報文段的數(shù)據(jù)的第一個字節(jié)的序號是301,而最后一個字節(jié)的序號是400。這樣,下一個報文段的數(shù)據(jù)序號應當從401開始,因而下一個報文段的序號字段的值應為401。
(3)確認序號
占4字節(jié),是期望收到對方的下—個報文段的數(shù)據(jù)的第一個字節(jié)的序號,也就是期望收到的下—個報文段首部的字號字段的值。例如,正確收到了一個報文段,其序號字段的值是501,而數(shù)據(jù)長度是200字節(jié),這就表明序號在501~700之間的數(shù)據(jù)均已正確收到。因此在響應的報文段中應將確認序號置為701。請注意:確認序號既不是501也不是700。
由于序號字段有32 bit長,可對4 GB(即4千兆字節(jié))的數(shù)據(jù)進行編號,這樣就可保證當序號重復使用時,舊序號的數(shù)據(jù)早已在網(wǎng)絡(luò)中消失了。
(4)數(shù)據(jù)偏移
占4bit,它指出數(shù)據(jù)開始的地方離TCP報文段的起始處有多遠。這實際上就是TCP報文段首都的長度。由于首部長度不固定(因首部中還有長度不確定的選項字段),因此致?lián)谱侄问潜匾摹5珣⑾ⅲ?#8220;數(shù)據(jù)偏移”的單位不是字節(jié),而是32 bit字(即4字節(jié)字)。由于4 bit能表示的最大十進制數(shù)是15,因此數(shù)據(jù)偏移的最大值是60字節(jié),這也是TCP首部的最大長度。
(5)保留
占6 bit,保留為今后使用,但目前應置為0。
下面有6個比特是說明本報文段性質(zhì)的控制比特,它們的意義如下。
(6)緊急比特URG(URGent)
當URG=1時,表明緊急指針字段有效。它告訴系統(tǒng)此報文段中有緊急數(shù)據(jù),應盡快傳送(相當于高優(yōu)先級的數(shù)據(jù)),而不要按原來的排隊順序來傳送。例如,已經(jīng)發(fā)送了很長的一個程序要在遠地的主機上運行。但后來發(fā)現(xiàn)了一些問題,需要取消該程序的運行。因此用戶從鍵盤發(fā)出中斷命令(Control+C)。如果不使用緊急數(shù)據(jù),那么這兩個字符將存儲在接收TCP緩存的末尾。只有在所有的數(shù)據(jù)被處理完畢后這兩個字符才被交付到接收應用進程。這樣做就浪費了許多時間。
當使用緊急比特并將URG置1時,發(fā)送應用進程就告訴發(fā)送TCP這兩個字符是緊急數(shù)據(jù)。于是發(fā)送TCP就將這兩個字符插入到報文段的數(shù)據(jù)的最前面,其余的數(shù)據(jù)都是普通數(shù)據(jù)。這時要與首部中第五個32 bit字中的一半“緊急指針”(Urgent Pointer)字段配合使用。緊急指針指出在本報文段中的緊急數(shù)據(jù)的最后一個字節(jié)的序號。緊急指針使接收方知道緊急數(shù)據(jù)共有多少個字節(jié)。緊急數(shù)據(jù)到達接收端后,當所有緊急數(shù)據(jù)都被處理完時,TCP就告訴應用程序恢復到正常操作。值得注意的是,即使窗口為零時也可發(fā)送緊急數(shù)據(jù)。
(7)確認比特ACK
只有當ACK=1時確認序號字段才有效。當ACK=0時,確認序號無效。
(8)推送比特PSH(PuSH)
當兩個應用進程進行文互式的通信時,有時在一端的應用進程希望在鍵入一個命令后立即就能夠收到對方的響應。在這種情況下,TCP就可以使用推送(push)操作。這時,發(fā)送端TCP將推送比特PSH置1,并立即創(chuàng)建一個報文段發(fā)送出上。接收TCP收到推送比特置1的報文段,就盡快(即“推送”向前)交付給接收應用進程,而不再等到整個緩存都填滿了后再向上交付。PSH比特也可叫做急迫比特。
雖然應用程序可以選擇推推送操作,但抵達操作還是往往不被人們使用。TCP可以選擇或不選擇這個操作。
(9)復位比特RST(ReSeT)
當RST=1時,表明TCP連接中出現(xiàn)嚴重差錯(如由于主機崩潰或其他原因),必須釋放連接,然后再重新建立運輸連接。復位比特還用來拒絕一個非法的報文段或拒絕打開一個連接。復位比特也可稱為重建比特或重置比特。
(10)同步比特SYN
在連接建立時用來同步序號。當SYN=1而ACK=0時,表明這是一個連接請求報文段。對方若同意建立連接,則應在響應的報文段中使SYN=1和ACK=1。因此,同步比特SYN置為1,就表示這是一個連接請求或連接接受報文。關(guān)于連接的建立和釋放,后面還要進行討論。
(11)終止比特FIN(FINal)
用來釋放一個迎接,當FIN=1時,表明此報文段的發(fā)送端的數(shù)據(jù)已發(fā)送完畢,并要求釋放運輸連接。
(12)窗口
占2字節(jié)。窗口字段用來控制對方發(fā)送的數(shù)據(jù)量,單位為字節(jié)。大家知道,計算機網(wǎng)絡(luò)經(jīng)常是用接收端的接收能力的大小來控制發(fā)送端的數(shù)據(jù)發(fā)送量。TCP也是這樣。TCP連接的一端根據(jù)自己緩存的空間大小確定自己的接收窗口大小,然后通知對方來確定對方的發(fā)送窗口。假定TCP連接的兩端是A和B。若A確定自己的接收窗口為WIN,則將窗口WIN的數(shù)值寫在A發(fā)送給B的TCP報文段的窗口字段中,這就是告訴B的TCP,“你(B)在未收到我(A)的確認時所能夠發(fā)送的數(shù)據(jù)量就是從本首部中的確認序號開始的WIN個字節(jié)。”所以A所確定的WINA是A的接收窗口,同時也就是B的發(fā)送窗口。例如,A發(fā)送的報文段首部中的窗口WIN=500,確認序號為201,則表明B可以在未收到確認的情況下,向A發(fā)送序號從201~700的數(shù)據(jù)。B在收到此報文段后,就以這個窗口數(shù)值WIN作為B的發(fā)送窗口。但應注意,B所發(fā)送的報文段中的窗口字段則是根據(jù)B的接收能力來確定A的發(fā)送窗口,不要弄混。
(13)檢驗和
占2字節(jié)。檢驗和字段檢驗的范圍包括首部和數(shù)據(jù)這兩部分。和UDP用戶數(shù)據(jù)報一樣,在計算檢驗和時,要在TCP報文段的前面加上12字節(jié)的偽首都。偽首部的格式與圖8-10中UDP用戶數(shù)據(jù)報的偽首部一樣。但應將偽首部第四個字段中的17放為6(TCP的協(xié)議號是6),將第五字段中的UDP長度改為TCP長度。接收端收到此報文段后,仍要加上這個偽首都來計算檢驗和。若使用IPV6,則相應的偽首部也要改變。
(14)選項
長度可變。TCP只規(guī)定了一種選項,即最大報文段長度MSS(Maximum Segment Size)。MSS告訴對方TCP:“我的緩存所能接收的報文段的數(shù)據(jù)字段的最大長度是MSS。”與沒有選項時,TCP的首部長度是20字節(jié)。
MSS的選擇并不簡單。若選擇較小的MSS長度,網(wǎng)絡(luò)的利用率就降低。設(shè)想在極端的情況下,當TCP報文段只含有1字節(jié)的數(shù)據(jù)時,在IP層傳輸?shù)臄?shù)據(jù)報的開銷至少有40字節(jié)(包括TCP報文段的首部和IP數(shù)據(jù)報的首都)。這樣,對網(wǎng)絡(luò)的利用率就不會超過1/41,到了數(shù)據(jù)鏈路層還要加上一些開銷。但反過來,若TCP報文段非常長,那么在IP層傳輸時就有可能要分解成多個短數(shù)據(jù)報片。在目的站要將收到的各個短數(shù)據(jù)報片裝配成原來的TCP報文段。當傳輸出錯時還要進行重傳。這些也都會使開銷增大。一般認為,MSS應盡可能大些,只要在IP層傳輸時不需要再分片就行。在連接建立的過程中,雙方都將自己能夠支持的MSS寫入這一字段。在以后的數(shù)據(jù)傳送階段,MSS取雙方提出的較小的那個數(shù)值:若主機未填寫這項,則MSS的默認值是536字節(jié)長。因此,所有要因特網(wǎng)上的主機都能接受的報文段長度是536+20=556字節(jié)。
TCP協(xié)議是面向字節(jié)的。TCP將所要傳送的整個報文(這可能包括許多個報文段)看成是一個個字節(jié)組成的數(shù)據(jù)流,并使每一個字節(jié)對應于一個序號。在連接建立時,雙方要商定初始序號。TCP誨隊所發(fā)送的報文段的首部中的序號字段數(shù)值表示該報文段中的數(shù)據(jù)部分的第一個字節(jié)的序號。
TCP的確認是對接收到的數(shù)據(jù)的最高序號(即收到的數(shù)據(jù)流中的最后一個序號)表示確認。但接收端返回的確認序號是已收到的數(shù)據(jù)的最高序號加1。也就是說,確認序號表示接收端期望下次收到的數(shù)據(jù)中的第一個數(shù)據(jù)字節(jié)的序號。
由于TCP連接能提供全雙工通信,因此通信中的每一方都不必專門發(fā)送確認報文段,而可以在傳送數(shù)據(jù)時順便把確認信息捎帶傳送,這樣做可以提高傳輸效率。
在發(fā)送端,TCP是怎樣決定發(fā)送個報文段的時機呢
TCP有三種基本機制來控制報文段的發(fā)送。第一種機制是TCP維持一個變量,它等于最大報文段長度MSS,只要發(fā)送緩存從發(fā)送進程得到的數(shù)據(jù)達到MSS字節(jié)時,就組裝成—個TCP報文段,然后發(fā)送出去。第二種機制是發(fā)送端的應用進程指明要求發(fā)送報文段,即TCP支持的推送(push)操作。第三種機制是發(fā)送端的一個計時器時間到了,這時就把當前已有的緩存數(shù)據(jù)裝入報文段發(fā)送出去。
但是,如何控制TCP發(fā)送報文段的時機仍然是一個較為復雜的問題。
例如,一個交互式用戶使用一條TELNET連接(運輸層為TCP協(xié)議)。設(shè)用戶只發(fā)—個字符。加上20字節(jié)的首部后,得到21字節(jié)長的TCP報文段。再加上20字節(jié)的IP首都,形成41字節(jié)長的IP數(shù)據(jù)報。在接收端TCP立即發(fā)出確認,構(gòu)成的數(shù)據(jù)報是40字節(jié)長(假定沒有救據(jù)發(fā)送)。若用戶要求遠地主機回送這一字符,則又要發(fā)回41字節(jié)長的IP數(shù)據(jù)報和40字節(jié)長的確認IP數(shù)據(jù)報。這樣,用戶僅發(fā)一字符時線路是就需傳送總長度為162字節(jié)共4個報文段。當線路帶寬并不富裕時,這種傳送方法的效率的確不高。因此應適當推遲發(fā)回確認報文,并盡量使用捎帶確認的方法。
在TCP的實現(xiàn)中廣泛使用Nagle算法[NAGL84]:算法是:若發(fā)送端應用進程將欲發(fā)送的數(shù)據(jù)逐個字節(jié)地達到發(fā)送端的TCP緩存,則發(fā)送端就將第一個字符(—個字符的長度是一個字節(jié))發(fā)送出去,將后面到達的字符將都緩存起來。當接收端收到對第一個字符的確認后,再將緩存中的所有字符裝成一個報文段發(fā)送出去,同時繼續(xù)對隨后到達的字符進行緩存。只有在收到對前一個報文段的確認時才繼續(xù)發(fā)送下一個報文段。當字符到達較快而網(wǎng)絡(luò)速率較慢時,用這樣的方法可明顯的減少所用的網(wǎng)絡(luò)帶寬,算法還規(guī)定,當?shù)竭_的字符已達到窗口大小的一半或己達到報文段的最大長度時,就立即發(fā)送一個報文段。
但有時不宜采用Nagle算法。例如在因特網(wǎng)上使用X Windows,并將鼠標移動的信息傳到遠地主機。若采用Nagle算法會使用戶感到無法忍受。這時最好關(guān)閉這個算法。
另一個問題叫做糊涂窗口綜合癥(silly window syndrome)[RFC 813],有時也會使TCP的性能變壞。設(shè)想這種情況:接收端的緩存已滿,而交互的應用進程一次只從緩存中讀取一個字符(這樣就在緩存產(chǎn)生1個字節(jié)的空位,然后向發(fā)送端發(fā)送確認,并將窗口設(shè)置為1個字節(jié)(但發(fā)送的數(shù)據(jù)報是40字節(jié)長)。接著,發(fā)送端又傳來1個字符(但發(fā)來的IP數(shù)據(jù)報是41字節(jié)長。接收端發(fā)回確認,仍然將窗口設(shè)置為一個字節(jié)。這樣進行下去,網(wǎng)絡(luò)的效率將會很低。
要解決這個問題,可讓接收端等待一段時間,使得或者緩存已能有足夠的空間容納—個最長的報文段,或者緩存已有一半的中間處于空的狀態(tài)。只要出現(xiàn)這兩種情況之一,就發(fā)出確認報文,并向發(fā)送端通知當前的窗口大小。此外,發(fā)送端也不要發(fā)送太小的報文段,而是將數(shù)掘積累成足夠大的報文段,或達到接收端緩存的空間的—半大小。
上述兩種方法可配合使用。使得在發(fā)送端不發(fā)送很小的報文段的同時,接收端也不要在緩存剛剛有了一點小的空位置就急忙將一個很小的窗口大小通知給發(fā)送端。
若發(fā)送方在規(guī)定的設(shè)置時間內(nèi)沒有收到確認,就要將未被確認的報文段重新發(fā)送。接收方若收到有差錯的報文段,則丟棄此報文段(不發(fā)達否認信息)。若收到重復的報文段,也要將其丟棄,但要發(fā)回(或捎帶發(fā)回)確認信息。這與數(shù)據(jù)鏈路層的情況相似。
若收到的報文段無差錯,只是未按序號,那么該如何處理?TCP對此未作明確規(guī)定,而是讓TCP的實現(xiàn)者自行確定?;蛘邔⒉话葱虻膱笪亩蝸G棄,或者先將其暫存于接收緩存內(nèi),待所缺序號的報文段收齊后再一起上交應用層。如有可能,采用后—種策略對網(wǎng)絡(luò)的性能會更好些。例如,發(fā)送端每個報文中含有100字節(jié)的數(shù)據(jù),且一連發(fā)送了8個報文段,其序號分別為1,l01,201,…,701。設(shè)接收端正確收到了其中的7個,而未收到序號為201的報文段。接收端可以將序號為30l~701的5個報文段先進行暫存,而發(fā)回確認序號為201的報文段(即序號為200及這以前的都已正確收到了)。當發(fā)送端重傳的序號為201的報文段正確到達接收端后,接收端就發(fā)回確認序號為801的確認,因而提高了傳輸效率。
為了提高報文段的傳輸效率,TCP采用大小可變的滑動窗口進行流量控制。窗口大小的單位是字節(jié)。在TCP報文段首部的窗口字段寫入的數(shù)值就是當前給對方設(shè)置的窗口數(shù)值。發(fā)送窗口在連接建立時由雙方商定。但在通信的過程中,接收端可根據(jù)自己的資源情況,隨時動態(tài)地調(diào)整對方為發(fā)送窗口(可增大或減小)。這種由接收端控制發(fā)送端的做法,在計算機網(wǎng)絡(luò)中經(jīng)常使用。圖8-12表示的是在TCP中使用的窗口概念。在TCP中接收端的接收窗口總是等于發(fā)送端的發(fā)送窗口(因為后者是由前者確定的),因此—般就只使用發(fā)送窗口這個詞匯。這一點和數(shù)據(jù)鏈路居HDLC中的滑動窗口很不一樣。在不使用選擇重傳ARQ時,通接收雙方的接收窗口都 是1,而發(fā)送窗口是由幀編號的位數(shù)確定的。
圖7-12 TCP中的窗口概念
圖8-13 利用可變窗口進行流量控制舉例
圖8-12(a)表示發(fā)送端要發(fā)送900字節(jié)長的數(shù)據(jù),劃分為9個100個節(jié)長的報文段,對方確定的發(fā)送窗口為500字節(jié)。發(fā)送端只要收到了對方的確認,發(fā)送窗口就可前移。發(fā)送端的TCP要維護一個指針。每發(fā)送一個報文段,指針就向前移動—個報文段的距離。當指針移動到發(fā)送窗口的最右端(即窗口前沿)時就不能再發(fā)送報文段了。
圖8-12(b)表示發(fā)送端已發(fā)送了400字節(jié)的數(shù)據(jù),但只收到對前200字節(jié)數(shù)據(jù)的確認,同時窗口大小不變,我們注意到,現(xiàn)在發(fā)送端還可發(fā)送300字節(jié)。
圖8-12(C)表示發(fā)送端收到了對方對前400字節(jié)數(shù)據(jù)的確認,但窗口減小到400字節(jié),于是,發(fā)送端還可發(fā)送400字節(jié)的數(shù)據(jù)。
下面通過圖8-13的例子說明利用可變窗口大小進行流量控制。
設(shè)主機A 向主機B發(fā)送數(shù)據(jù)。雙方確定的窗口值是400。再設(shè)每一個報文段為100字節(jié)長,序號的初始值為1(見8-16圖中第一個箭頭上的SEQ=1)。圖8-16中右邊的注釋可幫助理解整個的過程。我們應注意到,主機B進行了3次流量控制。第一次將窗口減小為300字節(jié),第二次又減為200字節(jié),最后減至0,即不允許對方再發(fā)送數(shù)據(jù)了。這種暫停狀態(tài)將持續(xù)到主機B重新發(fā)出一個新的窗口值為止。
實現(xiàn)流量控制并非僅僅為了使接收端來得及接收。如果發(fā)送端發(fā)出的報文過多會使網(wǎng)絡(luò)負荷過重。由此會引起報文段的時延增大。但報文段時廷的增大,將使主機不能及時地收到確認。因此會重傳更多的報文段,而這又會進一步加劇網(wǎng)絡(luò)的擁塞。為了避免發(fā)生擁塞,主機應當降低發(fā)送速率。
可見發(fā)送端的主機在發(fā)送數(shù)據(jù)時,既要考慮到接收端的接收能力,又要使網(wǎng)絡(luò)不要發(fā)生擁塞。因而發(fā)送端的發(fā)送窗口應接以下方式確定:
發(fā)送窗口=Min[通知窗口,擁塞窗口] (8-1)
這里
通知窗口(advertised window)是接收端根據(jù)其接收能力許諾的窗口值,是來自接收端的流量控制。接收端將通知窗口的值放在TCP報文的首部中,傳送給發(fā)送端。
擁塞窗口(congestion window)是發(fā)送端根據(jù)網(wǎng)絡(luò)擁塞情況得出的窗口值,是來自發(fā)送端的流量控制。
(8-1)式表明,發(fā)送端的發(fā)送窗口取“通知窗口”和“擁塞窗口”中的較小的一個。在未發(fā)生擁塞的穩(wěn)定工作狀態(tài)下,接收端通知的窗口和擁塞窗口是一致的。
為了更好地進行擁塞控制,因特網(wǎng)標準推薦使用以下三種技術(shù),即慢啟動(slow-start)、加速遞減(multiplicative decrease)和擁塞避免(congestion avoidance)。使用這些技術(shù)的前提是:由于通信線路帶來的誤碼而使得分組丟失的概率很小(遠小于1%)。因此只要出現(xiàn)分組丟失或遲延過長而引起超時重傳,就意味著在網(wǎng)絡(luò)的某處出現(xiàn)了擁塞。實現(xiàn)步驟如下所述。
(1)當一個連接初始化時,將擁塞窗口置為1(即窗口允許發(fā)送1個報文段)、并設(shè)置慢啟動的門限窗口值。
(2)發(fā)送端的發(fā)送窗口不能超過擁塞窗口和通知窗口的最小值?,F(xiàn)在假定接收端不進行流量控制。
(3)發(fā)送端若收到了對所有發(fā)出的報文段的確認,就在下一次發(fā)送時將擁塞窗口加倍,可見擁塞窗口從1開始,把指數(shù)規(guī)律增長。若出現(xiàn)了超時,則將當時的擁塞窗口減半,作為新的門限窗口值,同時擁塞窗口再次變?yōu)?。
(4)擁塞窗口重新從1開始按指數(shù)規(guī)律增長。但當增長到新的門限窗口值時,就每次只將擁塞窗口加1,使擁塞窗口按線性規(guī)律增長。當網(wǎng)絡(luò)又出現(xiàn)超時,仍重復上述過程。
(5)從以上討論可看出,“慢啟動”是指每出現(xiàn)一次超時,擁塞窗口都降低到1,使報文段慢慢注入到網(wǎng)絡(luò)中。不過這個名詞不太準確,因為擁塞窗口增長的比率并不很慢。“加速遞減”是指每出現(xiàn)一次超時,就將門限窗口值減半。若超時頻繁出現(xiàn),則門限窗口減小的速率是很快的。“擁塞避免”是指當擁塞窗口增大到門限窗口值時,就將擁塞窗口指數(shù)增長速率降低為線性增長速率,避免網(wǎng)絡(luò)再次出現(xiàn)擁塞。
采用這樣的流量控制方法使得TCP的性能有明顯的改進[STEV94][RFC2581]。重傳機制是TCP中最重要和最復雜的問題之一。TCP每發(fā)送一個報文段,就設(shè)置一次計時器。只要計時器設(shè)置的重傳時間已經(jīng)到了但還沒有收到確認,就要重傳這一報文段。
出于TCP的下層是一個互連網(wǎng)環(huán)境,發(fā)送的報文段可能只經(jīng)過一個高速率的局域網(wǎng),但也可能是經(jīng)過多個低速率的局域網(wǎng),并且數(shù)據(jù)報所選擇的路由還可能會發(fā)生變化。圖8-17畫出了數(shù)據(jù)鏈路層和運輸層的往返時延概率分布的對比。往返時延就是從數(shù)據(jù)發(fā)出到收到對方的確認所經(jīng)歷的時間。對于數(shù)據(jù)鏈路層,其往返時延的方差很小,因此將超時時間設(shè)置為如8-17圖中的T1即可。但對于運輸層來說,其往返時延的方差很大。若將超時時間設(shè)計為圖8-17中的T2,則很多報文段的重傳時間太早,因而給網(wǎng)絡(luò)增加了許多不應有的負荷。但若將超時時間選為圖中的T3,則顯然全使網(wǎng)絡(luò)的傳輸效率降低很多。
那么,運輸層的超時器的重傳時間究竟應設(shè)置為多大呢
TCP采用了一種自適應算法。這種算法記錄每一個報文段發(fā)出的時間、以及收到相應的確認報文段的時間。這兩個時間之差就是報文段的往返時延。將各個報文段的往返時延樣本加權(quán)平均,就得出報文段的平均往返時延T,每測量到一個新的往返時間樣本,就接下式重新計算一次平均往返時延:
平均往返時延T=a(舊的往返時延T))+(1-a)(新的往返時延樣本) (8-2)
在上式中,0<a<1。若a很接近于1,表示新算出的往返時延T和原來的值相比變化不大,而新的往返時延樣本的影響不大(T值更新較慢)。若選擇a接近于0,則表示加權(quán)計算的往返時延T受新的往返時延樣本的影響較大(T值的更新較快)。典型的a值為7/8。
顯然,計時器設(shè)置的重傳時間應略大于上面得出的平均往返時延,即
重傳時間=B(平均往返時延) (8-3)
這里B是個大于1的系數(shù),實際上,系數(shù)B是很難確定的,若取B很接近于1,發(fā)送端可以很及時地重傳丟失的報文段,因此效率得到提高。但若報文段并未丟失而僅僅是增加了一點時延,那么過早地重傳未收到確認的報文段,反而會加重網(wǎng)絡(luò)的負擔。因此TCP原先的標準推薦將B值取為2。但現(xiàn)在已有了更好的辦法。
上面所說的往返時間的測量,實現(xiàn)起來相當復雜,試看下面的例子。
如圖8-17所示,發(fā)送出一個TCP報文段1、設(shè)定的重傳到了,但還沒有收到確認。于是重傳此報文段,即圖中的報文段2,后來收到了確認報文段ACK?,F(xiàn)在的問題是:如何判出此確認報文段是對原來的報文段1的確認,還是對重傳的報文段2的確認?由于重傳的報文段2和原來的報文段1完全一樣,因此源站在收到確認后,就無法做出正確的判斷了。
圖8-17 收到的確認報文段ACK是對哪一個報文段的確認
若收到的確認是對重傳報文段2的確認,但被源站當成是對原來的報文段1的確認,那么這樣計算出的往返時延樣本和重傳時間就會偏大。如果后面再發(fā)送的報文段又是經(jīng)過重傳后才收到確認報文段,那么按此方法得出的重傳時間就越來越長。
同樣,若收到的確認是對原來的報文段1的確認,但被當成是對重傳報文段2的確認,則由此計算出的往返時廷樣本和重傳時間都會偏小。這就必然更加頻繁地導致報文段的重傳這樣就有可能使重傳時間越來越短。
根據(jù)以上所述,Karn提出了一個算法:在計算平均往返時延時,只要報文段重傳了,就不采用其往返時延樣本。這樣得出的平均往返時延和重傳時間當然就較準確。
但是,這又引起新的問題。設(shè)想出現(xiàn)這樣的情況:報文段的時延突然增大了很多。因此在原來得出的重傳時間內(nèi),不會收到確認報文段,于是就重傳報文段。但根據(jù)Karn算法,不考慮重傳的報文段的往返時延樣本。這樣,重傳時間就無法更新。
因此,對Karn算法進行修正的方法是:報文段重傳一次,就將重傳時間增大一些,
新的重傳時間=Y(jié)(舊的重傳時間) (8-4)
系數(shù)Y的典型值是2,當不再發(fā)生報文段的重傳時,才根據(jù)報文段的往返時延更新平均往返時延和重傳時間的數(shù)值。實踐證明,這種策略較為合理。
TCP是面向連接的協(xié)議。運輸連接的建立和釋放是每一次面向連接的通信中必不可少的過程。運輸連接的管理就是使運輸連接的建立和釋放都能正常地進行。
在連接建立過程中要解決以下三個問題。
(1)要使每一方能夠確知對方的存在。
(2)要允許雙方協(xié)商一些參數(shù)(如最大報文段長度,最大窗口大小,服務質(zhì)量等)。
(3)能夠運輸實體資源(如緩存大小,連接表中的項目等)進行分配。
TCP的連接和建立都是采用客戶服務端方式。主動發(fā)起連接建立的進程叫做客戶(client)。而被動等待正接建立的進程叫服務器(server)。
設(shè)主機B中運行一個服務器過程,如圖8-18所示,它先發(fā)出一個被動打開(passive open)命令,告訴它的TCP要準備接受客戶進程的連接請求。然后服務器進程就處于“聽”(listen)的狀態(tài),不斷檢測是否有客戶進程要發(fā)起連接請求,如有,即做出響應。
設(shè)客戶進程運行在主機A中。它先向其TCP發(fā)出主動打開(active open)命令,表明要向某個IP地址的某個端口建立運輸連接。
主機A的TCP向主機B的TCP發(fā)出連接請求報文段,其首部的同步比特SYN應置為1,同時選樣—個序號x.表明在后面?zhèn)魉蛿?shù)據(jù)時的第一個數(shù)據(jù)字節(jié)的序號是x。在圖8-19中,一個從A到B的箭頭上標有“SYN,SEQ=x”就是這個意思。
主機B的TCP收到連接請求報文段后,如同意,則發(fā)回確認。在確認報文段中應將SYN
置為1,確認序號應為x+1,同時也為自己選擇一個序號y。
主機A的TCP收到此報文段后,還要向B給出確認,其確認序號為y+1。
運行客戶進程的主機A的TCP通知上層應用進程,連接已經(jīng)建立(或打開)。
當運行服務器進程的主機B的TCP收到主機A的確認后,也通知其上層應用進程,連接已經(jīng)建立。
連接建立采用的這種過程叫做三次握手(there-way handshake),或三次聯(lián)絡(luò)。
為什么要發(fā)送這第三個報文段呢 這主要是為了防止己失效連接請求報文段突然又傳送到了主機B,因而產(chǎn)生錯誤。
所謂“已失效的連接請求報文段”是這樣產(chǎn)生的??紤]這樣一種情況。主機A發(fā)出連接請求,但因連接請求報文丟失而未收到確認。主機A于是再重傳—次。后來收到了確認,建立了連接。數(shù)據(jù)傳輸完畢后,就釋放了連接。主機A共發(fā)送了兩個連接請求報文段,其中的第二個到達了主機 B 。
圖8-19 TCP 連接釋放的過程
現(xiàn)假定出現(xiàn)另一種情況,即主機 A發(fā)出的第一個連接請求報文段并沒有丟失,而是在某些網(wǎng)絡(luò)結(jié)點滯留的時間太長,以致延誤到在這次的連接釋放以后才傳送到主機B。本來這是一個已經(jīng)失效的報文段。但主機B收到此失效的連接請求報文段后,就誤認為是主機A又發(fā)出—次新的連接請求,于是就向主機A發(fā)出確認報文段,同意建立連接。
主機A由于并沒有要求建立連接,因此不會理睬主機B的確認,也不會向主機B發(fā)送數(shù)據(jù),但主機B卻以為運輸連接就這樣建立了,并一直等待主機A發(fā)來數(shù)據(jù)。主機B的許多資源就這樣白白浪費了。
采用三次握手的辦法可以防止上述現(xiàn)象的發(fā)生。例如在剛才的情況下,主機A不會向主機B的確認發(fā)出確認。主機B收不到確認,連接就建立不起來。
在數(shù)據(jù)傳輸結(jié)束后,通信的雙方都可以發(fā)出釋放連接的請求。
設(shè)圖8-19 中的豐機A的應用進程先向其TCP發(fā)出連接釋放請求,并且不再發(fā)送數(shù)據(jù)。TCP通知對方要釋放從A到B這個方向的連接,將發(fā)往主機B的TCP報文段首部的終止比特FIN置1,其序號x等于前面已傳送過的數(shù)據(jù)的最后一個字節(jié)的序號加l。
主機B的TCP收到釋放連接通知后即發(fā)出確認,其序號為x+1,同時通知高層應用進程,如圖8-19中的箭頭①所示。這樣,從A到B的連接就釋放了,連接處于半關(guān)閉(half-close)狀態(tài),相當于主機A向主機B說:“我已經(jīng)沒有數(shù)據(jù)要發(fā)送了。但你如果還發(fā)送數(shù)據(jù),我仍接收。”
此后,主機B不再接收主機A發(fā)來的數(shù)據(jù)。但若主機B還有一些數(shù)據(jù)要發(fā)往主機A,則可以繼續(xù)發(fā)送。主機A只要收到數(shù)據(jù),仍應向主機B發(fā)送確認。
在主機B向主機A的數(shù)據(jù)發(fā)送結(jié)束后,其應用進程就通知TCP釋放連接,如圖8-20中的箭頭②所示。主機B發(fā)出的連接釋放報文段必須將終止比特FIN置1,并使其序號y等于前面已傳送過的數(shù)據(jù)的最后—個字節(jié)的序號加1,還必須重復上次已發(fā)送過的ACK=x+1。主機A必須對此發(fā)出確認,給出ACK=y(tǒng)+1,這樣才將從B到A的反方向連接釋放掉。主機A的TCP再向其應用進程報告,整個連接已經(jīng)全部釋放。
由此可見,上述連接釋放過程和連接建立時的三次握手在本質(zhì)上是一致的。
1.試說明運輸層的作用。網(wǎng)絡(luò)層提供數(shù)據(jù)報或虛電路服務對面的運輸層有何影響
2.試用示意圖來解釋運輸層的復用。一個給定的運輸連接能否分裂成許多條虛電路?請解釋之。畫圖說明許多個運輸用戶復用到一條運輸連接上,而這條運輸連接又復用到若干條網(wǎng)絡(luò)連接(虛電路)上。
3.解釋為什么突然釋放運輸連接就可能會丟失用戶數(shù)據(jù)而使用TCP的連接釋放方法就可保證不丟失數(shù)據(jù)。
4.試用具體例子說明為什么在運輸連接建立時要使用三次握手。說明如不這樣做可能會出現(xiàn)什么情況。
5.—個TCP報文段中的救據(jù)部分最多為多少個字節(jié) 為什么
6.主機A和B使用TCP通信。在B發(fā)送過的報文段中,有這樣連續(xù)的兩個:ACK=120和ACK=100。這可能嗎(前一個報文段確認的序號還大于后一個的)?試說明理由。
7.在使用TCP傳送數(shù)據(jù)時,如果有一個確認報文段丟失了,也不一定會引起對方數(shù)據(jù)的重傳。試說明理由(可結(jié)合上一題討論)。
8.在8.4.1節(jié)曾講過,若收到的報文段無差錯,只是未按序號,則TCP對此未作明確規(guī)定。何是讓TCP的實現(xiàn)者自行確定。試討論兩種可能的方法的優(yōu)劣:(1)將不按序的所文段丟棄;(2)允將不按序的報文段暫存于接收緩存內(nèi),待所缺序號的報文段收齊后再一塊上交應用層。
9.設(shè)TCP使用的最大窗口為64KB,即64x]024字節(jié),而傳輸信道的帶寬可認為是不受限制的??倛笪亩蔚钠骄禃r延為20 ms,問所能得到的最大吞量是多少?
10.試計算一個包括5段鏈路的運輸連接的單程端到端時延。5段鏈路程中有2段是衛(wèi)星鏈路。每條衛(wèi)星鏈路又由上行鏈路和下行鏈路兩部分組成??梢匀∵@兩部分的傳播時延之和為250ms。每一個局域網(wǎng)的范圍為1500 km,其傳播時延可按150000km/s來計算。各數(shù)據(jù)鏈路速率為48 Kbit/s,幀長為960 bit。
11.重復上題,但假定其中的一個陸地上的廣域網(wǎng)的傳輸時延為150 ms。
12.什么是Karn算法 在TCP的重傳機制中,若不采用Karn算法,而是在收列確認時都認為是對重傳報文段的確認,那么由此得中的往返時延樣本和重作時間都會偏小,試問:重傳時間最后會減小到什么程度
l3.若一個應用進程使用運輸層的用戶數(shù)據(jù)報UDPC但繼續(xù)向下文給IP層后,又封裝成IP數(shù)據(jù)報。既然都是據(jù)報,是否可以跳過UDP而直接交給IP層?UDP有沒有提供IP沒有提供的功能
14.使用TCP對實時話音業(yè)務的傳輸有沒有什么問題 使用UDP在傳送文件時會有什么問題?
l5.TCP在進行流量控制時是以分組的丟失作為產(chǎn)生擁塞的標志。有沒有不是因擁塞而引起的分組丟失的情況 如有,請舉出三種情況。
16.一個應用程序用UDP,到了IP層將數(shù)據(jù)報再劃分為4個數(shù)據(jù)報片發(fā)送出去。結(jié)果前兩個數(shù)據(jù)報片丟失,后兩個到達目的站。過了一段時間應用進程重傳UDP,而IP層仍然劃分為4個數(shù)據(jù)報片來傳送,結(jié)果這次前兩個到達目的站而后兩個丟失。試問:在目的站能否將這兩次傳輸?shù)?個數(shù)據(jù)報片組裝成為完整的數(shù)據(jù)報?假定目的站第—次收到的后兩個數(shù)據(jù)報片仍然保存在目的站的緩存中。
17.為什么在TCP首都中有一個首部長度字段,而UDP的首都中就沒有這個字段
l8.一個UDP用戶數(shù)據(jù)報的數(shù)據(jù)字段為8192字節(jié),要使用以太網(wǎng)來傳送、試問應當劃分為幾個數(shù)據(jù)報片 說明每一個數(shù)據(jù)報片的數(shù)據(jù)字段長度和片偏移字段的值。
19.網(wǎng)絡(luò)允許的最大報文段長度為128字節(jié),序號用8 bit表示,報文段在網(wǎng)絡(luò)中的生存時間為30秒。試求每一條TCP連接所能達到的最高數(shù)據(jù)率。
20.一個TCP連接下面使用256 Kbit/s的鏈路,其端到端時延為128 ms。經(jīng)測試,發(fā)現(xiàn)吞吐量只有120kbit/s。試問發(fā)送窗口是多少