1. 程式人生 > >TCP/IP協議(一)

TCP/IP協議(一)

1、概述

1.1、分層

image

網路協議通常分不同層次進行開發,每一層分別 負責不同的通訊功能。一個協議族,比如TCP/IP,是 一組不同層次上的多個協議的組合。TCP/IP通常被認 為是一個四層協議系統,如圖1 - 1所示。

每一層負責不同的功能:

1) 鏈路層,有時也稱作資料鏈路層或網路介面層, 通常包括作業系統中的裝置驅動程式和計算機 中對應的網路介面卡。它們一起處理與電纜(或其他任何傳輸媒介)的物理介面細節。

2) 網路層,有時也稱作網際網路層,處理分組在網路中的活動,例如分組的選路。在 TCP/IP協議族中,網路層協議包括I P協議(網際協議),ICMP協議(Internet網際網路控制報文協議),以及IGMP協議(Internet組管理協議)。

3 ) 運輸層,主要為兩臺主機上的應用程式提供端到端的通訊。在TCP/IP協議族中,有兩個 互不相同的傳輸協議:TCP(傳輸控制協議)和UDP(使用者資料報協議)。 TCP為兩臺主機提供高可靠性的資料通訊。它所做的工作包括把應用程式交給它的資料分 成合適的小塊交給下面的網路層,確認接收到的分組,設定傳送最後確認分組的超時時鐘 等。由於運輸層提供了高可靠性的端到端的通訊,因此應用層可以忽略所有這些細節。 而另一方面,UDP則為應用層提供一種非常簡單的服務。它只是把稱作資料報的分組 從一臺主機發送到另一臺主機,但並不保證該資料報能到達另一端。任何必需的可靠 性必須由應用層來提供。 這兩種運輸層協議分別在不同的應用程式中有不同的用途,這一點將在後面看到。

4 ) 應用層,負責處理特定的應用程式細節。幾乎各種不同的TCP/IP實現都會提供下面這些 通用的應用程式:

• Telnet 遠端登入。
• FTP 檔案傳輸協議。
• SMTP 簡單郵件傳送協議。
• SNMP 簡單網路管理協議。

分組、分組交換:

分組交換是一種儲存轉發的交換方式,它將使用者的報文劃分成一定長度的分組,以分組為儲存轉發,因此,它比電路交換的利用率高,比報文交換的時延要小,而具有實時通訊的能力。分組交換利用統計時分複用原理,將一條資料鏈路複用成多個邏輯通道,最終構成一條主叫、被叫使用者之間的資訊傳送通路,稱之為虛電路(V.C)實現資料的分組傳送。

分組交換的本質就是儲存轉發,它將所接受的分組暫時儲存下來,在目的方向路由上排隊,當它可以傳送資訊時,再將資訊傳送到相應的路由上,完成轉發。其儲存轉發的過程就是分組交換的過程。

分組交換的實質就是將要傳輸的資料按一定長度分成很多組,為了準確的傳送到對方,每個組都打上標識,許多不同的資料分組在物理線路上以動態共享和複用方式進行傳輸,為了能夠充分利用資源,當資料分組傳送到交換機時,會暫存在交換機的儲存器中,然後根據當前線路的忙閒程度,交換機會動態分配合適的物理線路,繼續資料分組的傳輸,直到傳送到目的地。到達目地之後的資料分組再重新組合起來,形成一條完整的資料。

 

1.2網際網路的地址

網際網路上的每個介面必須有一個唯一的Internet地址(也稱作IP地址)。IP地址長32bit。Internet地址並不採用平面形式的地址空間,如1、2、3等。IP地址具有一定的結構,五類不同的網際網路地址格式

如圖1 - 5所示。

imageimage

需要再次指出的是,多介面主機具有多個I P地址,其中每個介面都對應一個I P地址。

由於網際網路上的每個介面必須有一個唯一的IP地址,因此必須要有一個管理機構為接入網際網路的網路分配IP地址。這個管理機構就是網際網路絡資訊中心(InternetNetworkInformationCentre),稱作InterNIC。InterNIC只分配網路號。主機號的分配由系統管理員來負責。

Internet註冊服務(IP地址和DNS域名)過去由NIC來負責,其網路地址是nic.ddn.mil。1993年4月1日,InterNIC成立。現在,NIC只負責處理國防資料網的註冊請求,所有其他的Internet使用者註冊請求均由InterNIC負責處理,其網址是:rs.internic.net。事實上InterNIC由三部分組成:註冊服務(rs.internic.net),目錄和資料庫服務(ds.internic.net),以及資訊服務(is.internic.net)

有三類IP地址:單播地址(目的為單個主機)、廣播地址(目的端為給定網路上的所有主 機)以及多播地址(目的端為同一組內的所有主機)。

1.3、封裝

當應用程式用TCP傳送資料時,資料被送入協議棧中,然後逐個通過每一層直到被當作一串位元流送入網路。其中每一層對收到的資料都要增加一些首部資訊(有時還要增加尾部資訊),

該過程如圖1-7所示。TCP傳給IP的資料單元稱作TCP報文段或簡稱為TCP段(TCPsegment)。IP傳給網路介面層的資料單元稱作IP資料報(IPdatagram)。通過乙太網傳輸的位元流稱作幀(Frame)。

圖1-7中幀頭和幀尾下面所標註的數字是典型乙太網幀首部的位元組長度。在後面的章節中我們將詳細討論這些幀頭的具體含義。

乙太網資料幀的物理特性是其長度必須在46~1500位元組之間。 更準確地說,圖1-7中IP和網路介面層之間傳送的資料單元應該是分組(packet)。分組既可以是一個IP資料報,也可以是IP資料報的一個片(fragment)

image

許多應用程式都可以使用TCP或UDP來傳送資料。運輸層協議在生成報文首部時要存入一個應用程式的識別符號。TCP和UDP都用一個16bit的埠號來表示不同的應用程式。TCP和UDP把源埠號和目的埠號分別存入報文首部中。

 

1.4、分用

當目的主機收到一個乙太網資料幀時,資料就開始從協議棧中由底向上升,同時去掉各層協議加上的報文首部。每層協議盒都要去檢查報文首部中的協議標識,以確定接收資料的上層協議。這個過程稱作分用(Demultiplexing),

圖1-8顯示了該過程是如何發生的。

image

2、鏈路層

2.1、最大傳輸單元MTU

任何網路結構對資料幀的長度都有一個限制,如乙太網和802. 3其最大值分別是1500和1492位元組。鏈路層的這個特性稱作MTU,最大傳輸單元。不同型別的網路大多數都有一個上限。

如果IP層有一個數據報要傳,而且資料的長度比鏈路層的MTU還大,那麼IP層就需要進行分片(fragmentation),把資料報分成若干片,這樣每一片都小於MTU。

圖2-5列出了一些典型的MTU值,它們摘自RFC1191[MogulandDeering1990]。點到點的鏈路層(如SLIP和PPP)的MTU並非指的是網路媒體的物理特性。相反,它是一個邏輯限制,目的是為互動使用提供足夠快的響應時間。

image

2.2、序列線路吞吐量計算

如果線路速率是9600b/s,而一個位元組有8bit,加上一個起始位元和一個停止位元,那麼線路的速率就是960B/s(位元組/秒)。以這個速率傳輸一個1024位元組的分組需要1066ms。如果用SLIP連結執行一個互動式應用程式,同時還執行另一個應用程式如FTP傳送或接收1024位元組的資料,那麼一般來說就必須等待一半的時間(533ms)才能把互動式應用程式的分組資料傳送出去。

必須等待一半時間的原因來自於:CSMA/CD的基本原理是:所有節點都共享網路傳輸通道,節點在傳送資料之前,首先檢測通道是否空閒,如果通道空閒則傳送,否則就等待;在傳送出資訊後,再對衝突進行檢測,當發現衝突時,則取消傳送。

CSMA/CD的基本原理是:每個節點都共享網路傳輸通道,在每個站要傳送資料之前,都會檢測通道是否空閒,如果空閒則傳送,否則就等待;在傳送出資訊後,則對衝突進行檢測,當發現衝突時,則取消傳送。我們可以藉助於生活中的一個例子來解釋:假設有這一層樓,兩旁住了幾十戶人,中間只有一條僅供一人同行的走道。我們看情況會怎麼樣:①當這些住戶要經過走道出來時,首先探出頭來看看走道上有沒有人(這就是載波監聽),如果沒有,就通過走道出來;②如果走道上有人走,那麼就一直盯著走道,直到走道上沒人時再出來(1-堅持監聽演算法);③如果有兩人同時看到走道上沒有人,而同時走向走道(衝突檢測),則兩個人發現時就馬上回到自己屋裡。在整個協議中最關鍵的是載波監聽、衝突檢測兩部分

把SLIP的MTU縮短到256就意味著鏈路傳輸一幀最長需要266ms,它的一半是133ms(這是一般需要等待的時間)。這樣情況會好一些,但仍然不完美。我們選擇它的原因(與64或128相比)是因為大塊資料提供良好的線路利用率(如大檔案傳輸)。假設CSLIP的報文首部是5個位元組,資料幀總長為261個位元組,256個位元組的資料使線路的利用率為98.1%,幀頭佔了1.9%,這樣的利用率是很不錯的。如果把MTU降到256以下,那麼將降低傳輸大塊資料的最大吞吐量。

對以上描述的理解:

1、網路的物理特性完全支援大資料塊的傳輸。

2、但是很多鏈路層協議仍然會設定最大傳輸單元,

3、原因是基於CSMA/CD原理資料塊越大,其他程式的傳輸等待就會越久(一般等待最大資料塊傳輸時間的一半時間),而這個等待時間對於互動式應用是不可容忍的。

4、如果把最大傳輸單元設定過小,傳輸頻率自然上升,碰撞發生越多,線路的利用率就會降低,因為有一部分時間在處理衝突,通道是不傳輸東西的。

5、綜上只能根據網路結構特性選擇一個合適的MTU。

6、以上例子平均等待時間的計算(傳輸最大資料幀所需時間的一半)只適用於SLIP鏈路,不同網路結構有不同的數值。

 

3、IP網際協議

3.1、引言

IP是TCP/IP協議族中最為核心的協議。所有的TCP、UDP、ICMP及IGMP資料都以IP資料報格式傳輸。IP提供不可靠、無連線的資料報傳送服務。

不可靠(unreliable)的意思是它不能保證IP資料報能成功地到達目的地。IP僅提供最好的傳輸服務。如果發生某種錯誤時,如某個路由器暫時用完了緩衝區,IP有一個簡單的錯誤處理演算法:丟棄該資料報,然後傳送ICMP訊息報給信源端。任何要求的可靠性必須由上層來提供(如TCP)。

無連線(connectionless)這個術語的意思是IP並不維護任何關於後續資料報的狀態資訊。每個資料報的處理是相互獨立的。這也說明,IP資料報可以不按傳送順序接收。如果一信源向相同的信宿傳送兩個連續的資料報(先是A,然後是B),每個資料報都是獨立地進行路由選擇,可能選擇不同的路線,因此B可能在A到達之前先到達。

3.2、IP首部

IP資料報的格式如圖3-1所示。普通的IP首部長為20個位元組,除非含有選項欄位。

image 

4個位元組的32bit值以下面的次序傳輸:首先是0~7bit,其次8~15bit,然後16~23bit,最後是24~31bit。這種傳輸次序稱作bigendian位元組序。由於TCP/IP首部中所有的二進位制整數在網路中傳輸時都要求以這種次序,因此它又稱作網路位元組序。以其他形式儲存二進位制整數的機器,如littleendian格式,則必須在傳輸資料之前把首部轉換成網路位元組序。

總長度欄位是指整個IP資料報的長度,以位元組為單位。利用首部長度欄位和總長度欄位,就可以知道IP資料報中資料內容的起始位置和長度。由於該欄位長16位元,所以IP資料報最長可達65535位元組(回憶圖2-5,超級通道的MTU為65535。它的意思其實不是一個真正的MTU—它使用了最長的IP資料報)。當資料報被分片時,該欄位的值也隨著變化。

儘管可以傳送一個長達65535位元組的IP資料報,但是大多數的鏈路層都會對它進行分片。而且,主機也要求不能接收超過576位元組的資料報。由於TCP把使用者資料分成若干片,因此一般來說這個限制不會影響TCP。在後面的章節中將遇到大量使用UDP的應用(RIP,TFTP,BOOTP,DNS,以及SNMP),它們都限制使用者資料報長度為512位元組,小於576位元組。但是,事實上現在大多數的實現(特別是那些支援網路檔案系統NFS的實現)允許超過8192位元組的IP資料報。

3.3、IP選路

image

開始討論IP選路之前,首先要理解核心是如何維護路由表的。路由表中包含的資訊決定了IP層所做的所有決策。
我們列出了IP搜尋路由表的幾個步驟:
1)搜尋匹配的主機地址;
2)搜尋匹配的網路地址;
3)搜尋預設表項(預設表項一般在路由表中被指定為一個網路表項,其網路號為0)。
匹配主機地址步驟始終發生在匹配網路地址步驟之前。IP層進行的選路實際上是一種選路機制,它搜尋路由表並決定向哪個網路介面傳送分組。這區別於選路策略,它只是一組決定把哪些路由放入路由表的規則。IP執行選路機制,而路由守護程式則一般提供選路策略

3.3、IP校驗和

為了計算一份資料報的IP檢驗和,首先把檢驗和欄位置為0。然後,對首部中每個16bit進行二進位制反碼求和(整個首部看成是由一串16bit的字組成),結果存在檢驗和欄位中。當收到一份IP資料報後,同樣對首部中每個16bit進行二進位制反碼的求和。由於接收方在計算過程中包含了傳送方存在首部中的檢驗和,因此,如果首部在傳輸過程中沒有發生任何差錯,那麼接收方計算的結果應該為全1。如果結果不是全1(即檢驗和錯誤),那麼IP就丟棄收到的資料報。但是不生成差錯報文,由上層去發現丟失的資料報並進行重傳。

3.4、IP分片

物理網路層一般要限制每次傳送資料幀的最大長度。任何時候IP層接收到一份要傳送的IP資料報時,它要判斷向本地哪個介面傳送資料(選路),並查詢該介面獲得其MTU。IP把MTU與資料報長度進行比較,如果需要則進行分片。分片可以發生在原始傳送端主機上,也可以發生在中間路由器上。

把一份IP資料報分片以後,只有到達目的地才進行重新組裝(這裡的重新組裝與其他網路協議不同,它們要求在下一站就進行進行重新組裝,而不是在最終的目的地)。重新組裝由目的端的IP層來完成,其目的是使分片和重新組裝過程對運輸層(TCP和UDP)是透明的,除了某些可能的越級操作外。已經分片過的資料報有可能會再次進行分片(可能不止一次)。IP首部中包含的資料為分片和重新組裝提供了足夠的資訊。

回憶IP首部,下面這些欄位用於分片過程。對於傳送端傳送的每份IP資料報來說,其標識欄位都包含一個唯一值。該值在資料報分片時被複制到每個片中(我們現在已經看到這個欄位的用途)。標誌欄位用其中一個位元來表示“更多的片”。除了最後一片外,其他每個組成資料報的片都要把該位元置1。片偏移欄位指的是該片偏移原始資料報開始處的位置。另外,當資料報被分片後,每個片的總長度值要改為該片的長度值。

最後,標誌欄位中有一個位元稱作“不分片”位。如果將這一位元置1,IP將不對資料報進行分片。相反把資料報丟棄併發送一個ICMP差錯報文

當IP資料報被分片後,每一片都成為一個分組,具有自己的IP首部,並在選擇路由時與其他分組獨立。這樣,當資料報的這些片到達目的端時有可能會失序,但是在IP首部中有足夠的資訊讓接收端能正確組裝這些資料報片。

使用UDP很容易導致IP分片(在後面我們將看到,TCP試圖避免分片,但對於應用程式來說幾乎不可能強迫TCP傳送一個需要進行分片的長報文段)

4、UDP使用者資料報協議

4.1、引言

DP是一個簡單的面向資料報的運輸層協議:程序的每個輸出操作都正好產生一個UDP資料報,並組裝成一份待發送的IP資料報。這與面向流字元的協議不同,如TCP,應用程式產生的全體資料與真正傳送的單個IP資料報可能沒有什麼聯絡。

應用程式必須關心I P資料報的長度。如果它超過網路的MTU(2. 8節),那麼就要對IP數 據報進行分片。

4.2、UDP首部

image

UDP長度欄位指的是UDP首部和UDP資料的位元組長度。該欄位的最小值為8位元組(傳送一份0位元組的UDP資料報是OK)。這個UDP長度是有冗餘的。IP資料報長度指的是資料報全長,因此UDP資料報長度是全長減去IP首部的長度(該值在首部長度欄位中指定)    。

 

4.3UDP校驗和

UDP檢驗和覆蓋UDP首部和UDP資料。回想IP首部的檢驗和,它只覆蓋IP的首部—並不覆蓋IP資料報中的任何資料。

UDP和TCP在首部中都有覆蓋它們首部和資料的檢驗和。UDP的檢驗和是可選的,而TCP的檢驗和是必需的。

儘管UDP檢驗和的基本計算方法與我們在上文中描述的IP首部檢驗和計算方法相類似(16bit字的二進位制反碼和),但是它們之間存在不同的地方。首先,UDP資料報的長度可以為奇數字節,但是檢驗和演算法是把若干個16bit字相加。解決方法是必要時在最後增加填充位元組0,這只是為了檢驗和的計算(也就是說,可能增加的填充位元組不被傳送)。

其次,UDP資料報和TCP段都包含一個12位元組長的偽首部,它是為了計算檢驗和而設定的。偽首部包含IP首部一些欄位。其目的是讓UDP兩次檢查資料是否已經正確到達目的地(例如,IP沒有接受地址不是本主機的資料報,以及IP沒有把應傳給另一高層的資料報傳給UDP)。UDP資料報中的偽首部格式如圖11-3所示。

image

5、TCP連結的建立與終止

5.1、TCP通訊過程

在一個TCP連線中,僅有兩方進行彼此通訊。在第12章介紹的廣播和多播不能用於TCP。TCP通過下列方式來提供可靠性:

•應用資料被分割成TCP認為最適合傳送的資料塊。這和UDP完全不同,應用程式產生的資料報長度將保持不變。由TCP傳遞給IP的資訊單位稱為報文段或段(segment)。

•當TCP發出一個段後,它啟動一個定時器,等待目的端確認收到這個報文段。如果不能及時收到一個確認,將重發這個報文段。在第21章我們將瞭解TCP協議中自適應的超時及重傳策略。

•當TCP收到發自TCP連線另一端的資料,它將傳送一個確認。這個確認不是立即傳送,通常將推遲幾分之一秒。

•TCP將保持它首部和資料的檢驗和。這是一個端到端的檢驗和,目的是檢測資料在傳輸過程中的任何變化。如果收到段的檢驗和有差錯,TCP將丟棄這個報文段和不確認收到此報文段(希望發端超時並重發)。

•既然TCP報文段作為IP資料報來傳輸,而IP資料報的到達可能會失序,因此TCP報文段的到達也可能會失序。如果必要,TCP將對收到的資料進行重新排序,將收到的資料以正確的順序交給應用層。

•既然IP資料報會發生重複,TCP的接收端必須丟棄重複的資料。

•TCP還能提供流量控制。TCP連線的每一方都有固定大小的緩衝空間。TCP的接收端只允許另一端傳送接收端緩衝區所能接納的資料。這將防止較快主機致使較慢主機的緩衝區溢位。

5.2、TCP首部

image

1、序號用來標識從TCP發端向TCP收端傳送的資料位元組流,它表示在這個報文段中的的第一個資料位元組。如果將位元組流看作在兩個應用程式間的單向流動,則TCP用序號對每個位元組進行計數。序號是32bit的無符號數,序號到達232-1後又從0開始。

2、當建立一個新的連線時,SYN標誌變1。序號欄位包含由這個主機選擇的該連線的初始序號ISN(InitialSequenceNumber)。該主機要傳送資料的第一個位元組序號為這個ISN加1,因為SYN標誌消耗了一個序號(將在下章詳細介紹如何建立和終止連線,屆時我們將看到FIN標誌也要佔用一個序號)。

3、既然每個傳輸的位元組都被計數,確認序號包含傳送確認的一端所期望收到的下一個序號。因此,確認序號應當是上次已成功收到資料位元組序號加1。只有ACK標誌(下面介紹)為1時確認序號欄位才有效。

4、TCP為應用層提供全雙工服務。這意味資料能在兩個方向上獨立地進行傳輸。因此,連線的每一端必須保持每個方向上的傳輸資料序號。

在TCP首部中有6個標誌位元。它們中的多個可同時被設定為1。
URG緊急指標(urgentpointer)有效。
ACK確認序號有效。
PSH接收方應該儘快將這個報文段交給應用層。
RST重建連線。
SYN同步序號用來發起一個連線。
FIN發端完成傳送任務。

 

5.3、連線的建立與終止

為了瞭解一個TCP連線在建立及終止時發生了什麼,我們在系統svr4上鍵入下列命令:

image

以上是telnet 建立一條連結和斷開一條連結的過程;

 

tcpdump的輸出:

image

對於TCP段,每個輸出行開始按如下格式顯示:源> 目的: 標誌

這裡的標誌代表TCP首部(圖1 7 - 2)中6個標誌位元中的4個。圖1 8 - 2顯示了表示標誌的5 個字元的含義。

image

在第1行中,欄位1415531521:1415531521(0)表示分組的序號是1415531521,而報文段中資料位元組數為0。
tcpdump顯示這個欄位的格式是開始的序號、一個冒號、隱含的結尾序及圓括號內的資料位元組數。顯示序號和隱含結尾序號的優點是便於瞭解資料位元組數大於0時的隱含結尾序號。
這個欄位只有在滿足條件:
       (1)報文段中至少包含一個數據位元組;
或者(2)SYN、FIN或RST被設定為1時才顯示。
圖18-1中的第1、2、4和6行是因為標誌位元被置為1而顯示這個欄位的,在這個例子中通訊雙方沒有交換任何資料。
在第2行中,欄位ack1415531522表示確認序號。它只有在首部中的ACK標誌位元被設定1時才顯示。
每行顯示的欄位win4096表示發端通告的視窗大小。在這些例子中,我們沒有交換任何資料,視窗大小就維持預設情況下的4096。
圖18-1中的最後一個欄位<mss1024>表示由發端指明的最大報文段長度選項。發端將不接收超過這個長度的TCP報文段。這通常是為了避免分段

5.4、建立連結協議

1)請求端(通常稱為客戶)傳送一個SYN段指明客戶打算連線的伺服器的埠,以及初始序號(ISN,在這個例子中為1415531521)。這個SYN段為報文段1。
2)伺服器發回包含伺服器的初始序號的SYN報文段(報文段2)作為應答。同時,將確認序號設定為客戶的ISN加1以對客戶的SYN報文段進行確認。一個SYN將佔用一個序號。
3)客戶必須將確認序號設定為伺服器的ISN加1以對伺服器的SYN報文段進行確認(報文段3)。
這三個報文段完成連線的建立。這個過程也稱為三次握手(three-wayhandshake)。

image

傳送第一個SYN的一端將執行主動開啟(activeopen)。接收這個SYN併發回下一個SYN的另一端執行被動開啟(passiveopen)

當一端為建立連線而傳送它的SYN時,它為連線選擇一個初始序號。ISN隨時間而變化,因此每個連線都將具有不同的ISN。RFC793[Postel1981c]指出ISN可看作是一個32位元的計數器,每4ms加1。這樣選擇序號的目的在於防止在網路中被延遲的分組在以後又被傳送,而導致某個連線的一方對它作錯誤的解釋。

5.5、連線協議終止

建立一個連線需要三次握手,而終止一個連線要經過4次握手。這由TCP的半關閉(half-close)造成的。

既然一個TCP連線是全雙工(即資料在兩個方向上能同時傳遞),因此每個方向必須單獨地進行關閉。這原則就是當一方完成它的資料傳送任務後就能傳送一個FIN來終止這個方向連線。當一端收到一個FIN,它必須通知應用層另一端幾經終止了那個方向的資料傳送。傳送FIN通常是應用層進行關閉的結果。

首先進行關閉的一方(即傳送第一個F I N)將執行主動關閉,而另一方(收到這個F I N)執行被動關閉。通常一方完成主動關閉而另一方完成被動關閉

image

當伺服器收到這個FIN,它發回一個ACK,確認序號為收到的序號加1(報文段5)。和SYN一樣,一個FIN將佔用一個序號。同時TCP伺服器還向應用程式(即丟棄伺服器)傳送一個檔案結束符。接著這個伺服器程式就關閉它的連線,導致它的TCP端傳送一個FIN(報文段6),客戶必須發回一個確認,並將確認序號設定為收到序號加1(報文段7)

圖18-4顯示了終止一個連線的典型握手順序。我們省略了序號。在這個圖中,傳送FIN將導致應用程式關閉它們的連線,這些FIN的ACK是由TCP軟體自動產生的。

image

5.6、連線建立超時

有很多情況導致無法建立連線。一種情況是伺服器主機沒有處於正常狀態。為了模擬這種情況,我們斷開伺服器主機的電纜線,然後向它發出telnet命令。圖18-6顯示了tcpdump的輸出。

image

在這個輸出中有趣的一點是客戶間隔多長時間傳送一個SYN,試圖建立連線。第2個SYN與第1個的間隔是5.8秒,而第3個與第2個的間隔是24秒。

這是因為BSD版的TCP軟體採用一種500ms的定時器。這種500ms的定時器用於確定本章中所有的各種各樣的TCP超時。當我們鍵入telnet命令,將建立一個6秒的定時器(12個時鐘滴答(tick)),但它可能在之後的5.5秒~6秒內的任意時刻超時。圖18-7顯示了這一發生過程。儘管定時器初始化為12個時鐘滴答,但定時計數器會在設定後的第一個0~500ms中的任意時刻減1。從那以後,定時計數器大約每隔500ms減1,但在第1個500ms內是可變的(我們使用限定詞“大約”是因為在TCP每隔500ms獲得系統控制的瞬間,系統核心可能會優先處理其他中斷)。

image

當滴答計數器為0時,6秒的定時器便會超時(見圖18-7),這個定時器會在以後的24秒(48個滴答)重新復位。之後的下一個定時器將更接近24秒,因為當TCP的500ms定時器被核心呼叫時,它就會被修改一次。

5.7、最大報文長度

最大報文段長度(MSS)表示TCP傳往另一端的最大塊資料的長度。當一個連線建立時,連線的雙方都要通告各自的MSS。我們已經見過MSS都是1024。這導致IP資料報通常是40位元組長:20位元組的TCP首部和20位元組的IP首部。

在有些書中,將它看作可“協商”選項。它並不是任何條件下都可協商。當建立一個連線時,每一方都有用於通告它期望接收的MSS選項(MSS選項只能出現在SYN報文段中)。如果一方不接收來自另一方的MSS值,則MSS就定為預設值536位元組(這個預設值允許20位元組的IP首部和20位元組的TCP首部以適合576位元組IP資料報)。

只有當一端的主機以小於576位元組的MTU直接連線到一個網路中,避免這種分段才會有效。如果兩端的主機都連線到乙太網上,都採用536的MSS,但中間網路採用296的MTU,也將會出現分段。使用路徑上的MTU發現機制關於這個問題的唯一方法。

5.8、TCP的半關閉

image

5.9、TCP兩邊同時開啟

兩個應用程式同時彼此執行主動開啟的情況是可能的,儘管發生的可能性極小。每一方必須傳送一個SYN,且這些SYN必須傳遞給對方。這需要每一方使用一個對方熟知的埠作為本地埠。這又稱為同時開啟(simultaneousopen)。例如,主機A中的一個應用程式使用本地埠7777,並與主機B的埠8888執行主動開啟。主機B中的應用程式則使用本地埠8888,並與主機A的埠7777執行主動開啟。

這與下面的情況不同:主機A中的Telnet客戶程式和主機B中Telnet的伺服器程式建立連線,與此同時,主機B中的Telnet客戶程式與主機A的Telnet伺服器程式也建立連線。在這個Telnet例子中,兩個Telnet伺服器都執行被動開啟,而不是主動開啟,並且Telnet客戶選擇的本地埠不是另一端Telnet伺服器程序所熟悉的埠。

TCP是特意設計為了可以處理同時開啟,對於同時開啟它僅建立一條連線而不是兩條連線(其他的協議族,最突出的是OSI運輸層,在這種情況下將建立兩條連線而不是一條連線)。

 

當出現同時開啟的情況時,狀態變遷與圖18-13所示的不同。兩端幾乎在同時傳送SYN,並進入SYNSENT狀態。當每一端收到SYN時,狀態變為SYNRCVD(如圖18-12),同時它們都再發SYN並對收到的SYN進行確認。當雙方都收到SYN及相應的ACK時,狀態都變遷為ESTABLISHED。圖18-17顯示了這些狀態變遷過程。

image

一個同時開啟的連線需要交換4個報文段,比正常的三次握手多一個。此外,要注意的是我們沒有將任何一端稱為客戶或伺服器,因為每一端既是客戶又是伺服器。

5.10、TCP兩邊同時關閉

我們在以前討論過一方(通常但不總是客戶方)傳送第一個FIN執行主動關閉。雙方都執行主動關閉也是可能的,TCP協議也允許這樣的同時關閉(simultaneousclose)。

在圖18-12中,當應用層發出關閉命令時,兩端均從ESTABLISHED變為FIN_WAIT_1。這將導致雙方各發送一個FIN,兩個FIN經過網路傳送後分別到達另一端。收到FIN後,狀態由FIN_WAIT_1變遷到CLOSING,併發送最後的ACK。當收到最後的ACK時,狀態變化為TIMEWAIT。圖18-19總結了這些狀態的變化。

image

5.11、TCP狀態變遷

imageimage

TCP首部中的RST位元是用於“復位”的。一般說來,無論何時一個報文段發往基準的連線(referencedconnection)出現錯誤,TCP都會發出一個復位報文段(這裡提到的“基準的連線”是指由目的IP地址和目的埠號以及源IP地址和源埠號指明的連線。

6、TCP的成塊資料流與超時重傳

6.1、Nagle演算法

該演算法要求一個TCP連線上最多隻能有一個未被確認的未完成的小分組,在該分組的確認到達之前不能傳送其他的小分組。相反,TCP收集這些少量的分組,並在確認到來時以一個分組的方式發出去。該演算法的優越之處在於它是自適應的:確認到達得越快,資料也就傳送得越快。而在希望減少微小分組數目的低速廣域網上,則會發送更少的分組

Nagle演算法描述的分組就是TCP的成塊資料。

6.2、視窗的概念

理解:視窗類似傳送方或接收方的一塊快取,傳送放用來存放需要傳送的資料,等待ACK到來時把資料成塊的傳送出去。接收方用來存放接收到的資料,把接收到的資料進行重新排序。視窗的大小就是這塊快取的大小。

滑動視窗:

image

在這個圖中,我們將位元組從1至11進行標號。接收方通告的視窗稱為提出的視窗(offeredwindow),它覆蓋了從第4位元組到第9位元組的區域,表明接收方已經確認了包括第3位元組在內的資料,且通告視窗大小為6。

1)稱視窗左邊沿向右邊沿靠近為視窗合攏。這種現象發生在資料被髮送和確認時。
2)當視窗右邊沿向右移動時將允許傳送更多的資料,我們稱之為視窗張開。這種現象發生在另一端的接收程序讀取已經確認的資料並釋放了TCP的接收快取時。
3)當右邊沿向左移動時,我們稱之為視窗收縮。HostRequirementsRFC強烈建議不要使用這種方式。但TCP必須能夠在某一端產生這種情況時進行處理。

6.3、慢啟動/擁塞避免/快速恢復演算法工作過程

需要知道幾個定義:

1)擁塞視窗cwnd:TCP傳送端建立的一個視窗,當TCP連結建立時,擁塞視窗被初始化為1個報文段(即另一端通告的報文段大小),傳送端每次傳送擁塞視窗大小的資料。該視窗是傳送方的流量控制。

2)慢啟動演算法:傳送方開始傳送一個報文段(擁塞視窗初始化的大小),等待接收ACK;第一次可接收一個ACK,每接收一個ACK擁塞視窗大小加一個報文段 即第二次可傳送兩個報文段;再次等待接收ACK,第二次可接收兩個ACK,擁塞視窗變為四個報文段即第三次可傳送四個報文段;以此類推,每次傳送的報文段為1,2,4,8,16….成指數增長

3)慢啟動門限ssthresh:TCP維護的一個變數,以位元組為單位,用來標識TCP傳輸資料的某個介限。擁塞演算法裡使用的變數。

4)擁塞避免演算法:參照慢啟動演算法理解,傳送方每接收一個ACK,cwnd(擁塞視窗)就增加 1/cwnd。與慢啟動的指數增加比起來,這是一種加性增長。我們希望在一個往返時間內最多為cwnd增加1個報文段(不管在這個RTT中收到了多少個ACK),然而慢啟動將根據這個往返時間中所收到的確認的個數增加cwnd。

5)通告視窗:TCP接收端建立的一個視窗,是描述接收端快取大小的視窗,每次ACK資料都會包含通告視窗的可用大小資料。該視窗是接收方可用快取大小。

演算法工作過程如下:

擁塞避免演算法和慢啟動演算法需要對每個連線維持兩個變數:一個擁塞視窗cwnd和一個慢啟動門限ssthresh。這樣得到的演算法的工作過程如下:

1)對一個給定的連線,初始化cwnd為1個報文段,ssthresh為65535個位元組。

2) TCP輸出程序的輸出不能超過cwnd和接收方通告視窗中較小的一方的大小。

3)TCP以慢啟動演算法傳送資料量指數上漲,當上漲到cwnd>ssthresh時TCP傳送資料量以擁塞避免演算法加性增長。

4)當資料量上漲到一定程度(最大也不可能超過cwnd或接收方通告視窗大小),擁塞發生時(收到重複確認)ssthresh被設定為當前視窗(cwnd和接收方通告視窗較小的一方)大小的一半,但最小是2個報文段。之後根據第3條可得會繼續執行擁塞避免演算法。

5)如果是超時引起了擁塞cwnd會設定為1個報文段,根據第3條可得會繼續執行慢啟動演算法。

image

 

快速重傳:TCP接收方在收到一個失序的報文段時,需要立即產生一個ACK(一個重複的ACK)。該重複的ACK目的在於讓傳送方知道自己收到了一個失序的報文段,並告訴對方自己希望收到的序號。

快速恢復演算法:假如這只是一些報文段的重新排序,則在重新排序的報文段被處理併產生一個新的ACK之前,只可能產生1~2個重複的ACK。如果一連串收到3個或3個以上的重複ACK,就非常可能是一個報文段丟失了,於是我們就重傳丟失的資料報文段,而無需等待超時定時器溢位。這就 是快速重傳演算法。

1)當收到第一個ACK開始cwnd保持不變(ACK變計數),當收到第3個重複的ACK時,將ssthresh設定為當前擁塞視窗cwnd的一半。重傳丟失的報文段。設定cwnd為ssthresh加上三個報文段大小。

2)之後每次收到一個重複的ACK時,cwnd增加1個報文段大小併發送1個分組(如果新的cwnd允許傳送)。

3)當下一個確認新資料的ACK到達時這個ACK應該是在進行重傳後的一個往返時間內對步驟1中重傳的確認。另外,這個ACK也應該是對丟失的分組和收到的第1個重複的ACK之間的所有中間報文段的確認設定cwnd為ssthresh(在第1步中設定的值,注意整個過程ssthresh只在第一步變化了一次)。並進入正常擁塞避免演算法。

image

 

內容摘自:TCP-IP詳解卷1:協議