傳輸層提供的服務
????傳輸層的功能
從通信和信息處理的角度看 ,傳輸層向它上面的應用層提供通信服務,它屬于面向通信部分的最高層,同時也是用戶功能中的最低層 。
傳輸層位于網絡層之上 ,它為運行在不同主機上的進程之間提供了邏輯通信,而網絡層提供了主機之間的邏輯通信? 。顯然,即使當網絡層協議是不可靠的 ,也就是即使網絡層協議會使分組丟失、混亂和重復 ,傳輸層同樣也能為應用程序提供可靠的服務 。
從下圖可以看出,網絡的邊緣部分中的兩個主機使用網絡的核心部分的功能進行端到端的通信時 ,只有主機的協議棧才有傳輸層和應用層 ,而路由器在轉發分組時都只用到下三層的功能
( 即在通信子網中沒有傳輸層 ,傳輸層只存在于通信子網以外的主機中)。
傳輸層的功能 :
1)????傳輸層提供應用進程之間的邏輯通信 (即端到端的通信)。與網絡層的區別是 ,網絡層提供的是主機之間的邏輯通信 。
從網絡層來說 ,通信的雙方是兩個主機 ,IP 數據報的首部給出了這兩個主機的 IP 地址。但 “兩個主機之間的通信” 實際上是兩個主機中的應用進程之間的通信 ,應用進程之間的通信又稱端到端的邏輯通信 。這里“邏輯通信”? 的意思是:傳輸層之間的通信好像是沿水平方向傳送數據, 但事實上這兩個傳輸層之間并沒有一條水平方向的物理連接? 。
2) 復用和分用 。復用是指發送方不同的應用進程都可以使用同一個傳輸層協議傳送數據;分用是指接收方的傳輸層在剝去報文的首部后能夠把這些數據正確交付到目的應用進程。
注意:傳輸層的復用分用功能與網絡層的復用分用功能不同 。網絡層的復用是指發送方不同協議的數據都可以封裝成 IP 數據報發送出去 ,分用是指接收方的網絡層在剝去首部后把數據交付給相應的協議。
3) 傳輸層還要對收到的報文進行差錯檢測 (首部和數據部分) 。而網絡層只檢查 IP 數據報的首部,不檢驗數據部分是否出錯。
4) 提供兩種不同的傳輸協議 ,即面向連接的 TCP 和無連接的 UDP 。而網絡層無法同時實現兩種協議(即在網絡層要么只提供面向連接的服務,如虛電路 ,要么只提供無連接服務 ,如數據報,而不可能在網絡層同時存在這兩種方式) 。
傳輸層向高層用戶屏蔽了底層網絡核心的細節 ( 如網絡拓撲 、路由協議等) ,它使應用進程看見的就是好像在兩個傳輸層實體之間有一條端到端的邏輯通信信道 ,這條邏輯通信信道對上層的表現卻因傳輸層協議不同而有很大的差別 。當傳輸層采用面向連接的 TCP時,盡管下面的網絡是不可靠的 ,但這種邏輯通信信道就相當于是一條全雙工的可靠信道。但當傳輸層采用無連接的UDP 時,這種邏輯通信信道仍然是一條不可靠信道 。
傳輸層的尋址與端口
????端口的作用
端口能夠讓應用層的各種應用進程將其數據通過端口向下交付給傳輸層 ,以及讓傳輸層知道應當將其報文段中的數據向上通過端口交付給應用層相應的進程 。端口就是傳輸層服務訪問點 TSAP ,它在傳輸層的作用類似于 IP 地址在網絡層的作用或 MAC 地址在數據鏈路層的作用 ,只不過 IP 地址和 MAC 地址標識的是主機 ,而端口標識的是主機中的應用進程 。
數據鏈路層的 SAP 是 MAC 地址,網絡層的 SAP 是 IP 地址,傳輸層的SAP是端口。?
在協議棧層間的抽象的協議端口是軟件端口 ,和路由器或交換機上的硬件端口是完全不同的概念。硬件端口是不同硬件設備進行交互的接口? ,而軟件端口是應用層的各種協議進程與傳輸實體進行層間交互的一種地址 。傳輸層使用的是軟件端口 。
端口號只具備本地意義 ,即端口號只是為了標志本計算機應用層中的各進程? 。在因特網中不同計算機的相同端口號是沒有聯系的 。
????端口號
應用進程通過端口號進行標識 ,端口號長度為 16bit,能夠表示 65536 (2^16)個不同的端口號。端口號只具有本地意義,即端口號只是為標志本計算機應用層中的各進程 ,不同計算機的相同端口號是沒有聯系的? 。根據端口號范圍可將端口分為兩類:
1) 服務端使用的端口號 。這里又分為兩類 ,最重要的一類是熟知端口號 ,數值為 0 ~1023, IANA ( 互聯網地址指派機構) 把這些端口號指派給了 TCP/IP 最重要的一些應用程序 ,讓所有的用戶都知道 。另一類叫做登記端口號 ,數值為 1024~ 49151 。它是為沒有熟知端口號的應用程序使用的,使用這類端口號必須在IANA登記,以防止重復。
一些常用的熟知端口號如下 :
2) 客戶端使用的端口號 ,數值為 49152 ~ 65535 ,由于這類端口號僅在客戶進程運行時才動態選擇 ,因此又叫短暫端口號( 也稱臨時端口)。通信結束后 ,剛才使用過的客戶端口號就不復存在,這個端口號就可以供其他客戶進程使用 。
????套接字
在網絡中通過 IP 地址來標識和區別不同的主機 ,通過端口號來標識和區分一臺主機中的不同應用進程。在網絡中采用發送方和接收方的套接宇 ( Socket ) 組合來識別端點 。所謂套接字實際上是一個通信端點 ,即,
套接字=( 主機 IP 地址 ,端口號) 它唯一地標識了網絡中的一個主機和其上的一個應用(進程)。
在網絡通信中 ,主機 A 發給主機 B 的報文段包含目的端口號和源端口號 ,源端口號是作為 “ 返回地址” 的一部分,即當B需要發回給一個報文段給 A 時,B 到 A 的報文段中目的端口號便是 A 到 B 報文段中源端口號 (完全的返回地址是 A 的 IP 地址和源端口號) 。
無連接服務與面向連接服務
面向連接的服務就是在通信雙方進行通信之前? ,必須先建立連接 ,在通信過程中 ,整個連接的情況一直被實時地監控和管理 。當通信結束后 ,則應該釋放這個連接 。
而無連接的服務,兩個實體之間的通信不需要先建立好連接,需要通信的時候,直接將信息發送到? “ 網絡”? 中,讓該信息的傳遞在網上盡力而為地往目的地傳送。
TCP/IP 協議族在 IP 層之上使用了兩個傳輸協議 :一個是面向連接的傳輸控制協議 TCP ,當采用 TCP 時,傳輸層向上提供的是一條全雙工的可靠邏輯信道;另一個是無連接的用戶數據報協議 UDP,當采用UDP 時,傳輸層向上提供的是一條不可靠的邏輯信道 。
TCP 提供面向連接的服務 ,在傳送數據之前必須先建立連接,數據傳送結束后要釋放連接 。 TCP 不提供廣播或組播服務 。由于 TCP 提供面向連接的可靠的傳輸服務 ,因此不可避免地增加了許多開銷,如確認、流量控制 、計時器以及連接管理等 。這不僅使協議數據單元的頭部增大很多,還要占用許多的處理機資源。因此 TCP 主要適用于可靠性更重要的場合 ,如文件傳輸協議 FTP 、超文本傳輸協議 HTTP、遠程登錄 TELNET 等。
UDP 是一個無連接的非可靠的傳輸層協議 。它在 IP 之上僅提供兩個附加服務 :多路復用和對數據的錯誤檢查 。IP 知道怎樣把分組投遞給一臺主機 ,但不知道怎樣把它們投遞給主機上的具體的應用 。UDP 在傳送數據之前不需要先建立連接 ,遠程主機的傳輸層收到 UDP 報文后 ,不需要給出任何確認 。由于UDP 比較簡單,其執行速度就比較快 、實時性好 。使用 UDP 的應用主要包括小文件傳送協議 ( TFTP )、DNS 、SNMP 和實時協議( RTP )。
注意:? IP 數據報和 UDP 數據報的區別 :IP 數據報在網絡層要經過路由的存儲轉發 ;而 UDP 數據報是在傳輸層的端到端的邏輯信道中傳輸 ,而封裝成 IP 數據報在網絡層傳輸時 ,UDP 數據報的信息對路由是不可見的 。
UDP 協議
UDP 概述
[RFC 768]定義的 UDP 只是做了傳輸協議能夠做的最少工作 ,只在 IP 的數據報服務之上增加了兩個最基本的服務 :復用和分用以及差錯檢測。如果應用程序開發者選擇UDP 而不是 TCP,則應用程序幾乎是直接與 IP 打交道。
也許你想知道 ,為什么應用開發人員寧愿在 UDP 之上構建應用 ,也不選擇 TCP?既然 TCP 提供可靠的服務 ,而 UDP 不提供,那么TCP 總是首選嗎?答案是否定的 ,因為有很多應用更適合用 UDP ,主要是因為 UDP 有下列的優點 :
1)? ?UDP 無需建立連接 。因此 UDP 不會引入建立連接的時延 。試想如果 DNS 運行在 TCP 之上而不是 UDP ,則 DNS 的速度會慢很多 。HTTP 使用 TCP 而不是 UDP ,是因為對于基于文本數據的 Web 網頁來說,可靠性是至關重要的 。
2)無連接狀態 。TCP 需要在端系統中維護連接狀態 。此連接狀態包括接收和發送緩存 、擁塞控制參數和序號與確認號的參數 。而 UDP 不維護連接狀態 ,也不跟蹤這些參數 。因此,某些專用應用服務器使用 UDP 時,一般都能支持更多的活動客戶機 。
3)分組首部開銷小 。TCP 有 20 字節的首部開銷 ,而 UDP 僅有 8 字節的開銷。
4)應用層能更好地控制要發送的數據和發送時間 。UDP 沒有擁塞控制 ,因此網絡中的擁塞也不會影響主機的發送效率 。某些實時應用要求以穩定的速度發送 ,能容忍一些數據的丟失 ,但不允許有較大的時延 ,而 UDP 正好滿足這些應用的需求 。
UDP 常用于一次性傳輸比較少量數據的網絡應用 ,如 DNS、SNMP 等,因為對于這些應用,若采用 TCP ,則將為連接創建 、維護和拆除而帶來不小的開銷 。UDP 也常用于多媒體應用 ( 如 IP 電話、實時視頻會議 、流媒體等),顯然,可靠數據傳輸對這些應用來說并不是最重要的 ,但 TCP 的擁塞控制會導致數據出現較大的延遲 ,這是它們不可容忍的 。
UDP 提供盡最大努力的交付 ,即不保證可靠交付,但這并不意味著應用對數據的要求是不可靠的,因此所有維護傳輸可靠性的工作需要用戶在應用層來完成。應用實體可以根據應用的需求來靈活設計自己的可靠性機制 。
UDP 是面向報文的 。發送方 UDP 對應用層交下來的報文 ,在添加首部后就向下交付給 IP 層 ,既不合并,也不拆分 ,而是保留這些報文的邊界;接收方 UDP 對 IP 層交上來 UDP 用戶數據報 ,在去除首部后就原封不動地交付給上層應用進程 ,一次交付一個完整的報文 。因此報文不可分割 ,是UDP 數據報處理的最小單位 。
UDP 的首部格式
UDP 數據報包含兩個部分 :UDP 首部和用戶數據 ,整個 UDP 數據報作為 IP 數據報的數據部分封裝在 IP 數據報中 ,如圖所示。UDP 首部有 8 個字節,由4 個字段組成 ,每個字段的長度都是兩個字節 ,各字段意義如下 :
1)? ?源端口? 源端口號。在需要對方回信時選用?。不需要時可用全 0。
2)?目的端口? 目的端口號。這在終點交付報文時必須要使用到?。
3)?長度? UDP?數據報的長度?(包括首部和數據)?,其最小值是?8(僅有首部)。
4)?校驗和? 檢測?UDP 數據報在傳輸中是否有錯?。有錯就丟棄。該字段是可選的,當源主機不想計算校驗和?,則直接令該字段為全?0。
當傳輸層從?IP?層收到?UDP?數據報時?,就根據首部中的目的端口,把?UDP?數據報通過相應的端口,上交給應用進程,如圖所示。
如果接收方 UDP 發現收到的報文中的目的端口號不正確 (即不存在對應于端口號的應用進程),就丟棄該報文,并由 ICMP發送 “端口不可達” 差錯報文給發送方 。
UDP 校驗
在計算校驗和時 ,要在UDP 數據報之前增加 12 個字節的偽首部 ,偽首部并不是 UDP 真正的首部。只是在計算校驗和時 ,臨時添加在 UDP 數據報的前面 ,得到一個臨時的 UDP 數據報。 校驗和就是按照這個臨時的 UDP 數據報計算的 。偽首部既不向下傳送也不向上遞交,而僅僅是為了計算校驗和 。這樣的校驗和 ,既檢查了 UDP 數據報,又對 IP 數據報的源 IP 地址和目的 IP 地址進行了檢驗 。下圖給出了 UDP 數據報的偽首部各宇段的內容 。
UDP 校驗和的計算方法和 IP 數據報首部校驗和的計算方法相似 ,都使用二進制反碼運算求和再取反 。但不同的是 :IP數據報的校驗和只檢驗 IP 數據報的首部 ,但UDP 的校驗和是把首部和數據部分一起都檢驗 。
在發送方 ,首先是把全零放入校驗和字段并且添加偽首部 。然后,把 UDP? 數據報看成是由許多 16 位的字串連接起來 。若 UDP 數據報的數據部分不是偶數個字節 ,則要在數據部分末尾增加一個全零字節 (但此字節不發送)。接下來就按二進制反碼計算出這些16 位字的和。將此和的二進制反碼寫入校驗和字段 。在接收方 ,把收到的 UDP 數據報加上偽首部 (如果不為偶數個字節,還需要補上全零字節)后,按二進制反碼計算出這些 16 位字的和 。當無差錯時其結果應全為 1。否則就表明有差錯出現 ,接收方就應該丟棄這個 UDP 數據報。
下圖給出了一個計算 UDP 校驗和的例子 。本例中,UDP 數據報的長度是 15 字節 (不含偽首部),因此需要添加一個全 0 字節。
注意:1) 校驗時 ,若 UDP 數據報部分的長度不是偶數個字節 ,則需要填入一個全 0 字節 ,如上圖所示。但是此字節和偽首部一樣,是不發送的。
2) 如果 UDP 校驗和校驗出 UDP 數據報是錯誤的 ,可以丟棄 ,也可以交付給上層 ,但是需要附上錯誤報告 ,即告訴上層這是錯誤的數據報 。
3) 通過偽首部 ,不僅可以檢查源端口號 、目的端口號和 UDP 用戶數據報的數據部分 ,還可以檢查 IP 數據報的源 IP 地址和目的地址。
這種簡單的差錯檢驗方法的檢錯能力并不強? ,但它的好處是簡單 ,處理速度快。
TCP 協議
TCP 協議的特點
TCP? 是在不可靠的 IP 層之上實現的可靠的數據傳輸協議 ,它主要解決傳輸的可靠 、有序、 無丟失和不重復的問題 。TCP 是 TCP/IP 體系中非常復雜的一個協議 ,主要特點有 :
1)? TCP 是面向連接的傳輸層協議 。
2)每一條 TCP 連接只能有兩個端點 ,每一條 TCP 連接只能是點對點的 (一對一)。
3)? TCP 提供可靠的交付服務 ,保證傳送的數據無差錯 、不丟失 、不重復且有序 。
4)TCP 提供全雙工通信 ,TCP 允許通信雙方的應用進程在任何時候都能發送數據 ,為此 TCP連接的兩端都設有發送緩存和接收緩存 ,用來臨時存放雙向通信的數據 。 發送緩存用來暫時存放以下數據 :①發送應用程序傳送給發送方TCP準備發送的數據 ;②TCP 已發送但尚未收到確認的數據 。接收緩存用來暫時存放以下數據 :①按序到達的但尚未被接收應用程序讀取的數據 ;②不按序到達的數據 。
5)? TCP 是面向字節流的 ,雖然應用程序和 TCP 的交互是一次一個數據塊( 大小不等),但TCP 把應用程序交下來的數據看成僅僅是一連串的無結構的字節流 。
TCP 報文段
TCP 傳送的數據單元稱為報文段 。一個 TCP 報文段分為 TCP 首部和 TCP 數據兩部分 ,整個 TCP 段作為 IP 數據報的數據部分封裝在 IP 數據報中 ,如圖所示。其首部的前 20 字節是固定的。TCP 報文段的首部最短為 20 字節 ,后面有 4N 字節是根據需要而增加的選項 ,通常長度為 4 字節的整數倍 。
TCP 報文段既可以用來運載數據 ,也可以用來建立連接 、釋放連接和應答 。 各字段意義如下 :
1)? ?源端口和目的端口字段 各占 2 字節。端口是運輸層與應用層的服務接口 。運輸層的復用和分用功能都要通過端口才能實現 。
2) 序號字段 占 4 字節。TCP 是面向字節流的 (就是說 TCP 傳送時是按照一個一個字節來傳送的),所以TCP 連接中傳送的數據流中的每一個字節都編上一個序號 。序號字段的值則指的是本報文段所發送的數據的第一個字節的序號 。
例如 ,一報文段的序號字段值是 301,而攜帶的數據共有 100 字
節,這就表明本報文段的數據的最后一個字節的序號是 400 ,故下一個報文段的數據序號應從 401 開始。
3) 確認號字段 占 4 字節,是期望收到對方的下一個報文段的數據的第一個字節的序號? 。 若確認號 N ,則表明到序號 N-1? 為止的所有數據都已正確收到 。
例如,B 正確收到了 A 發送過來的一個報文段 ,其序號字段是指501 ,而數據長度是200 字節 (序號 501 ~ 700 ) ,這表明 B 正確收到了 A 發送的到序號 700 為止的數據。因此 B 期望收到 A 的下一個數據序號是 701,于是 B 在發送給 A? 的確認報文段中把確認號置為 701 。
4) 數據偏移(即首部長度) 占 4 位,這里不是 IP 數據報分片的那個數據偏移 ,而是表示首部長度 ,它指出 TCP 報文段的數據起始處距離 TCP 報文段的起始處有多遠 。
“數據偏移” 的單位是 2 位 ( 以4字節為計算單位) 。因此當此字段的值為 15 時,達到TCP首都的最大長度 60 字節。
5) 保留字段 占 6 位,保留為今后使用 ,但目前應置為 0,該字段可以忽略不計 。
6) 緊急位 URG? 當 URG=1 時,表明緊急指針字段有效。它告訴系統此報文段中有緊急數據 ,應盡快傳送 (相當于高優先級的數據)。但是 URG? 需要和緊急指針配套使用 ,也就是說數據從第一個字節到緊急指針所指字節就是緊急數據? 。
7) 確認位 ACK? 只有當 ACK=1? 時確認號字段才有效 。當 ACK=0 時,確認號無效 。
TCP 規定,在連接建立后所有傳送的報文段都必須把 ACK 置 1 。
8) 推送位 PSH? (Push)? 接收 TCP 收到 PSH=1 的報文段,就盡快地交付接收應用進程 ,而不再等到整個緩存都填滿了后再向上交付 。
9) 復位位 RST? ( Reset )? ? 當 RST=1 時,表明TCP 連接中出現嚴重差錯 (如由于主機崩潰或其他原因),必須釋放連接,然后再重新建立運輸連接? 。
10) 同步位 SYN? ?同步 SYN=1 表示這是一個連接請求或連接接收報文 。
當 SYN=1,ACK=0 時,表明這是一個連接請求報文 ,對方若同意建立連接 ,則在響應報文中使用 SYN=1 ,? ACK=1 。即,SYN=1 就表示這是一個連接請求或連接接收報文 。
11)? ?終止位 FIN(Finish )? ? 用來釋放一個連接 。FIN=1 表明此報文段的發送方的數據己發送完畢 ,并要求釋放傳輸連接 。
12) 窗口字段? ?占 2 字節。它指出了現在允許對方發送的數據量,接收方的數據緩存空間是有限的,故用窗口值作為接收方讓發送方設置其發送窗口的依據 ,單位為字節 。
例如,設確認號是 701 ,窗口字段是 1000。這就表明 ,從 701 號算起,發送此報文段的一方還有接收 1000 字節數據 (字節序號是 701 ~ 1700) 的接收緩存空間。
13) 檢驗和? 占 2 字節。檢驗和字段檢驗的范圍包括首部和數據這兩部分。在計算檢驗和時 , 和 UDP 一樣,要在TCP 報文段的前面加上 12 字節的偽首部(只需將 UDP 偽首部的第 4 個字段, 即協議字段的 17 改成 6,其他的和 UDP? 一樣)。
14) 緊急指針字段? 占 16 位,指出在本報文段中緊急數據共有多少個字節 (緊急數據放在本報文段數據的最前面) 。
15) 選項字段? 長度可變 。TCP? 最初只規定了一種選項 ,即最大報文段長度 ( MaximumSegment Size, MSS ) 。MSS 是 TCP 報文段中的數據字段的最大長度 。
16) 填充字段? 這是為了使整個首部長度是 4 字節的整數倍 。
TCP 連接管理
TCP 是面向連接的協議 。因此每一個 TCP 連接都有三個階段 :連接建立、數據傳送和連接釋放。TCP? 連接的管理就是使運輸連接的建立和釋放都能正常進行 。
在 TCP 連接建立的過程中要解決以下三個問題 :
1)? ?要使每一方都能夠確知對方的存在 。
2) 要允許雙方協商一些參數 ( 如最大窗口值 、是否使用窗口擴大選項 、時間戳選項以及服務質量等)。
3) 能夠對運輸實體資源 (如緩存大小、連接表中的項目等)進行分配。
TCP 把連接作為最基本的抽象 ,每一條 TCP 連接有兩個端點 ,TCP 連接的端點不是主機 , 不是主機的 IP 地址 ,不是應用進程 ,也不是傳輸層的協議端口 。TCP 連接的端口叫做套接字(socket)或插口 。端口拼接到 IP 地址即構成了套接字 。
每一條 TCP 連接唯一地被通信兩端的兩個端點 (即兩個套接字) 所確定。
TCP 連接的建立采用客戶/服務器方式 。主動發起連接建立的應用進程叫做客戶機 (Client ),而被動等待連接建立的應用進程叫做服務器 ( Server )。
?TCP 連接的建立
連接的建立經歷以下 3 個步驟,通常稱為 “三次握手”,如圖所示
第一步?:客戶機的?TCP?首先向服務器的?TCP?發送一個連接請求報文段?。這個特殊的報文段中不含應用層數據?,其首部中的SYN?標志位被置為 1。另外,客戶機會隨機選擇一個起始序號?seq=x?(?連接請求報文不攜帶數據?,但要消耗掉一個序號)?。
第二步?:服務器的?TCP?收到連接請求報文段后?,如同意建立連接?,就向客戶機發回確認?,?并為該?TCP?連接分配?TCP 緩存和變量?。在確認報文段中?,SYN?和?ACK?位都被置為?1,確認號字段的值為?x + 1,并且服務器隨機產生起始序號?seq=y ( 確認報文不攜帶數據?,但也要消耗掉一個序號)。確認報文段同樣不包含應用層數據 。
第三步 :當客戶機收到確認報文段后 ,還要向服務器給出確認 ,并且也要給該連接分配緩存和變量 。這個報文段的 ACK? 標志位被置1,序號字段為 x+1 ,確認號字段 ack=y+1 。該報文段可以攜帶數據,如果不攜帶數據則不消耗序號 。
在成功進行了以上三步之后 ,TCP 連接就建立了 ,接下來就可以傳送應用層數據了 。TCP 提供的是全雙工通信 ,因此通信雙方的應用進程在任何時候都能發送數據 。
另外值得注意的是 ,服務器端的資源是在完成第二次握手時分配的,而客戶端的資源是在完成第三次握手時分配的 。這就使得服務器易于受到 SYN 洪泛攻擊 。
TCP 連接的釋放
天下沒有不散的宴席 ,對于 TCP 也是如此 。參與 TCP 連接的兩個進程中的任何一個都能終止該連接 。TCP 連接釋放的過程通常稱為 “四次揮手”。如圖所示。
第一步:客戶機打算關閉連接,就向其 TCP 發送一個連接釋放報文段 ,并停止再發送數據, 主動關閉 TCP 連接,該報文段的FIN 標志位被置 1, seq=u,它等于前面己傳送過的數據的最后一個字節的序號加 1? ( FIN 報文段即使不攜帶數據 ,也要消耗掉一個序號)。TCP? 是全雙工的 , 即可以想象成是一條 TCP 連接上有兩條數據通路 。當發送 FIN 報文時 ,發送 FIN 的一端就不能再發送數據,也就是關閉了其中一條數據通路 ,但對方還可以發送數據 。
第二步:服務器收到連接釋放報文段后即發出確認,確認號是ack=u+1,而這個報文段自己的序號是 v,等于它前面已傳送過的數據的最后一個字節的序號加 1。此時,從客戶機到服務器這個方向的連接就釋放了 ,TCP 連接處于半關閉狀態 。但服務器若發送數據 ,客戶機仍要接收 ,即從服務器到客戶機這個方向的連接并未關閉 。
第三步:若服務器己經沒有要向客戶機發送的數據 ,就通知 TCP 釋放連接 ,此時其發出 FIN=1的連接釋放報文段 。
第四步 :客戶機收到連接釋放報文段后 ,必須發出確認 。在確認報文段中 ,ACK 字段被置為 1,確認號 ack=w+1,序號 seq=u+1 。此時 TCP 連接還沒有釋放掉 ,必須經過時間等待計時器設置的時間 2MSL 后,A 才進入到連接關閉狀態 。
對上述 TCP 連接建立和釋放的總結如下:
TCP 可靠傳輸
TCP? 的任務是在 IP 層的不可靠的、盡力而為服務的基礎上建立一種可靠數據傳輸服務 。TCP 提供的可靠數據傳輸服務就是要保證接收方進程從緩存區讀出的字節流與發送方發出的字節流是完全一樣的 。TCP 使用了校驗 、序號 、確認和重傳等機制來達到這個目的。其中,TCP 的校驗機制與 UDP 校驗一樣 ,這里不再贅述。
????序號
TCP? 首部的序號字段用來保證數據能有序提交給應用層 ,TCP 把數據看成一個無結構但是有序的宇節流 ,而序號是建立在傳送的字節流之上 ,而不是建立在報文段之上 。
TCP? 連接中傳送的數據流中的每一個字節都編上一個序號 。序號字段的值則指的是本報文段所發送的數據的第一個字節的序號 。如圖所示,假設 A 和 B 之間建立了一條 TCP 連接, A 的發送緩存區中總共有 10 個字節,序號從 0 開始標號 ,第一個報文包含第 0 ~? 2 個字節 ,則該 TCP 報文段的序號是 0;第二個報文段的序號是 3。
????確認
TCP 首部的確認號是期望收到對方的下一個報文段的數據的第一個字節的序號 。上圖中, 如果接收方 B 已收到第一個報文段 ,此時 B 希望收到的下一個報文段的數據是從第 3 個字節開始的,于是B 發送給 A 的報文中的確認號字段應該為 3。發送方緩存區會繼續存儲那些已經發送但未收到確認的報文段 ,以便在需要的時候重傳 。
TCP? 默認使用累計確認,即TCP 只確認數據流中至第一個丟失字節為止的字節 。例如,上圖中,接收方 B 收到了 A 發送的包含字節 0 ~ 2 以及字節 6 ~ 7 的報文段。由于某種原因,B 還沒有收到字節 3 ~ 5 的報文段,此時 B 仍在等待字節 3 (和其后面的字節),因此,B 到 A 的下一個報文段將確認號字段置為 3。
????重傳
有兩種事件會導致 TCP 對報文段進行重傳 :超時和冗余 ACK。
(1) 超時
TCP 每發送一個報文段 ,就對這個報文段設置一次計時器 。只要計時器設置的重傳時間到期但還沒有收到確認 ,就要重傳這一報文段 。
由于 TCP? 的下層是一個互聯網環境 ,IP 數據報所選擇的路由變化很大 。因而傳輸層的往返時延的方差也很大 。為了計算超時計時器的重傳時間,TCP? 采用一種自適應算法 ,它記錄一個報文段發出的時間 ,以及收到相應確認的時間 ,這兩個時間之差叫做報文段的往返時間 ( Round-Trip Time,? RTT) 。TCP 保留了 RTT 的一個加權平均往返時間 RTTs ,當第一次測量RTT 樣本時 ,RTTs 值就為所測量到的 RTT 樣本的值,但以后每測量一個新的RTT樣本,就按下式重新計算一次RTTs:
在上式中 0<= α<1 。若α很接近于零 ,表示新的 RTTs 值和舊的 RTTs 值相比變化不大 ,而受新的 RTT 樣本影響不大 (RTT 值更新較慢)。若選擇α接近于1,則表示新的RTTs 值受新的 RTT 樣本的影響較大 (RTT 值更新較快)。[RFC 2988]推薦的α值為 0.125。
顯然,超時計時器設置的超時重傳時間 ( Retransmission Time-Out, RTO ) 應略大于上面得出的加權平均往返時間 RTTs 。使用下式計算 :
????????????????????????????????????????????????????????????????????RTO=RTTs+4xRTTD
式中,RTTD 是 RTT的偏差的加權平均值 ,它與RTTs 和新的 RTT 樣本之差有關 。當第一次測量時 ,RTTD 取為測量到的 RTT 樣本值的一半 ,以后測量中,使用下式計算 :
(2) 冗余 ACK (冗余確認)
超時觸發重傳存在的一個問題就是超時周期往往太長 。幸運的是,發送方通常可在超時事件發生之前通過注意所謂冗余 ACK 來較好地檢測丟包情況 。冗余 ACK 就是再次確認某個報文段的ACK,而發送方先前已經收到過該報文段的確認。例如,發送方A 發送了序號為 1、2、3、4、5 的 TCP 報文段 ,其中 2 號報文段在鏈路中丟失 ,它將無法到達接收方 B。因此3、4、5 號報文段對于 B 來說就成了失序報文段 。TCP 規定每當比期望序號大的失序報文段到達時 ,發送一個冗余 ACK ,指明下一個期待字節的序號[ RFC 1122,RFC 2581] 。在本例中 ,3、4、5 號報文到達B,但它們不是 B 所期望收到的下一個報文 ,于是 B 就發送 3 個對 1 號報文段的冗余 ACK ,表 示自己期望接收 2 號報文段 。TCP 規定當發送方收到對同一個報文段的 3 個冗余 ACK 時,就可以認為跟在這個被確認報文段之后的報文段已經丟失 。就前面的例子而言 ,當 A 收到對于 1 號報文段的 3 個冗余 ACK 時,則它可以認為 2 號報文段已經丟失 。這時發送方 A 可以立即對 2 號報文段執行重傳 ,這種技術通常稱為快速重傳 。當然,冗余 ACK 還被用在擁塞控制中 ,這將在后面的內容中討論。
TCP 流量控制
TCP? 提供了流量控制服務以消除發送方使接收方緩存區溢出的可能性? ,因此可以說流量控制是一個速度匹配服務 (匹配發送方的發送速率與接收方的讀取速率) 。
TCP? 提供一種基于滑動窗口協議的流量控制機制 ,滑動窗口的基本原理己在數據鏈路層介紹過了 ,這里要介紹的是 TCP? 是如何使用窗口機制來實現流量控制的 。
在通信過程中 ,接收方根據自己接收緩存的大小 ,動態地調整發送方的發送窗口大小 ,這就是接收窗口rwnd,即調整 TCP? 報文段首部中的 “窗口” 字段值,來限制發送方向網絡注入報文的速率。同時,發送方根據其對當前網絡擁塞程序的估計而確定的窗口值 ,稱為擁塞窗口 cwnd(后面會講到),其大小與網絡的帶寬和時延密切相關。
例如,在通信中 ,有效數據只從 A 發往 B,而 B 僅向 A 發送確認報文 ,這時,B 就可以通過設置確認報文段首部的窗口字段來將 rwnd 通知給 A。rwnd即接收方允許連續接收的最大能力 , 單位是字節 。發送方 A 總是根據最新收到的 rwnd 值來限制自己發送窗口的大小 ,這樣可以將未確認的數據量控制在rwnd大小之內 ,保證了 A 不會使 B 的接收緩存溢出 。當然,A 的發送窗口的實際大小是取 rwnd 和 cwnd 中的最小值。
下圖的例子說明了如何利用滑動窗口機制進行流量控制 。設主機 A 向主機B 發送數據, 在連接建立時 ,B 告訴 A:“我的接收窗口rwnd=400( 字節)”。
傳輸層和數據鏈路層的流量控制的區別在于:傳輸層定義了端到端用戶之間的流量控制 ,數據鏈路層定義了兩個中間的相鄰結點的流量控制 。另外,數據鏈路層的滑動窗口協議的窗口大小不能動態變化 ,傳輸層的可以動態變化 。
TCP 擁塞控制
所謂擁塞控制就是防止過多的數據注入網絡中 ,這樣可以使網絡中的路由器或鏈路不致過載。當出現擁塞時 ,端點并不能了解到擁塞發生的細節 ,對通信連接的端點來說 ,擁塞往往表現為通信時延的增加 。當然擁塞控制和流量控制也有相似的地方,都是通過控制發送方發送數據的速率來達到效果的 。
擁塞控制與流量控制的區別 :擁塞控制是讓網絡能夠承受現有的網絡負荷 ,它是一個全局性的過程,涉及所有的主機 、所有的路由器 ,以及與降低網絡傳輸性能有關的所有因素 。相反,流量控制往往是指點對點的通信量的控制 ,即接收端控制發送端,它所要做的就是抑制發送端發送數據的速率 ,以便使接收端來得及接收 。
例如 ,某個鏈路傳輸速率為 10Gb/s ,某巨型機向一個 PC 以 1Gb/s 的速率傳送文件 ,顯然網絡的帶寬是足夠大的 ,即不存在擁塞問題 ,但如此高的發送速率將導致 PC 可能來不及接收 ,因此流量控制是必需的 。但若有 100 萬個 PC 在此鏈路上以 1Mb/s 的速率傳送文件 ,則現在的問題就變成了網絡的負載是否超過了現有網絡所能承受的范圍。
為了更好地對傳輸層進行擁塞控制 ,因特網建議標準定義了以下四種算法:慢開始、擁塞避免、快重傳、快恢復。
發送方在確定發送報文段的速率時 ,既要根據接收方的接收能力,又要從全局考慮不要使網絡發生擁塞 。因此,TCP 協議要求發送方維護以下兩個窗口 :
1) 接收窗口 rwnd ,接收方根據目前接收緩存大小所許諾的最新的窗口值 ,反映了接收方的容量。由接收方根據其放在 TCP 報文的首部的窗口字段通知發送方 。
2)? 擁塞窗口 cwnd ,發送方根據自己估算的網絡擁塞程度而設置的窗口值 ,反映了網絡的當前容量 。只要網絡沒有出現擁塞? ,擁塞窗口就再增大一些,以便把更多的分組發送出去。但只要網絡出現擁辜,擁塞窗口就減小一些 ,以減少注入網絡中的分組數 。
發送窗口的上限值應當取接收窗口 rwnd 和擁塞窗口 cwnd 中較小的一個,即:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 發送窗口的上限值 = Min[rwnd,? cwnd]
注意:接收方總是有足夠大的緩存空間 ,因而發送窗口大小由網絡的擁塞程度來決定 ,也就是說可以將發送窗口等同于為擁塞窗口 。
接收窗口的大小可以根據 TCP? 報文首部的窗口字段通知發送方 ,而發送方怎么去維護擁塞窗口呢?這就是下面講解的慢開始和擁塞避免算法 。
????慢開始和擁塞避免
(1) 慢開始算法
在 TCP 剛剛連接好,開始發送TCP 報文段時 ,先令擁塞窗口 cwnd=1 ,即一個最大報文段長度 MSS 。而在每收到一個對新的報文段的確認后 ,將 cwnd 加 1,即增大一個 MSS 。用這樣的方法逐步增大發遠方的擁塞窗口 cwnd ,可以便分組注入到網絡的速率更加合理 。
例如,A 向B 發送數據 ,當發送時 A 的擁塞窗口為 2,那么 A 一次可以發送兩個 TCP 報文段 ,當經過一個 RTT 后 (也稱為一個傳輸輪次) ,A 收到 B 對剛才兩個報文的確認 ,于是就把擁塞窗口調整為 4,下一次發送時就可以一次發送 4 個報文段。
使用慢開始算法后 ,每經過一個傳輸輪次 ( 即往返時延 RTT) ,擁塞窗口 cwnd? 就會加倍, 即 cwnd? 的大小呈指數形式增長 。這樣慢開始一直把擁塞窗口 cwnd? 增大到一個規定的慢開始門限 ssthresh (闕值),然后改用擁塞避免算法 。
(2) 擁塞避免算法
擁塞避免算法的做法是 :發送端的擁塞窗口 cwnd 每經過一個往返時延 RTT 就增加一個 MSS 的大小,而不是加倍 ,使 cwnd 按線性規律緩慢增長 (即加法增大),而當出現一次超時 ( 網絡擁塞) 時,則令慢開始門限 ssthresh 等于當前 cwnd? 的一半 (即乘法減小)。
根據 cwnd 的大小執行不同的算法 ,可歸納如下 :
?當 cwnd<ssthresh時,使用慢開始算法。
?當 cwnd>ssthresh 時,停止使用慢開始算法而改用擁塞避免算法 。
?當 cwnd=ssthresh 時,既可使用慢開始算法 ,也可使用擁塞避免算法(通常做法)。
(3)網絡擁塞的處理
當網絡出現擁塞時? ,無論在慢開始階段還是在擁塞避免階段,只要發送方檢測到超時事件的發生 (沒有按時收到確認 ,重傳計時器超時) ,就要把慢開始門限 ssthresh? 設置為出現擁塞時的發遠方 cwnd 值的一半 (但不能小于 2 )。然后把擁塞窗口 cwnd 重新設置為 1,執行慢開始算法 。 這樣做的目的就是要迅速減少主機發送到網絡中 的分組數,使得發生擁靠的路由器有足夠時間把隊列中積壓的分組處理完畢 。
擁塞避免并非完全能避免擁塞? 。利用以上措施要完全避免網絡擁塞是不可能的 。擁塞避免是指在擁塞避免階段把擁塞窗口控制為接線性規律增長,使網絡比較不容易出現擁塞 。
慢開始和擁塞避免算法的實現過程如圖所示。
?初始時 ,擁塞窗口置為1,即cwnd=1 ,慢開始門限置為16,即ssthresh=16 。慢開始階段, cwnd 初值為 1,以后發送方每收到一個確認 ACK, cwnd 值加 1,也即經過每個傳輸輪次 (RTT) , cwnd 呈指數規律增長 。
?當擁塞窗口 cwnd 增長到慢開始門限 ssthresh 時 (即當 cwnd=16 時),就改用擁塞避免算法,cwnd 按線性規律加性增長 。
?假定 cwnd=24 時,網絡發生擁塞,更新 ssthresh 值為 12 ( 即變為超時時 cwnd 值 24的一 半),cwnd 重置 1,并執行慢開始算法 ,當 cwnd=12 時,改為擁塞避免算法 。
注意,在慢開始 (指數級增長) 階段,若 2*cwnd>ssthresh ,則下一個RTT 的 cwnd 應等于 ssthresh ,而不是 2*cwnd ,即 cwnd 不能躍過 ssthresh 值。上圖中,在第 16 個輪次時 ,cwnd=8、 ssthresh=12 ,第 17 個輪次時 ,cwnd=12 ,而不是 16。
在慢開始和擁塞避免算法中使用了 “乘法減小” 和 “加法增大” 方法。“乘法減小”是指不論在慢開始階段還是擁塞避免階段 ,只要出現一次超時 (即很可能出現了網絡擁塞) ,就把慢開始門限值 ssthresh 設置為當前的擁塞窗口值的一半 。當網絡頻繁出現擁塞時 ,ssthresh 值就下降得很快,以大大減少注入到網絡中的分組數 。而“加法增大” 是指執行擁塞避免算法后 ,在收到對所有報文段的確認后 ( 即經過一個 RTT ) ,就把擁事窗口 cwnd 增加一個 MSS 大小,使擁塞窗口緩慢增大,以防止網絡過早出現擁塞? 。
????快重傳和快恢復?
快重傳和快恢復算法是對慢開始和擁塞避免算法的改進 。
(1) 快重傳
在上一節 TCP 可靠傳輸機制中 ,快速重傳技術使用了用冗余 ACK? 來檢測丟包的發生 。同樣, 冗余 ACK 也用于網絡擁塞的檢測 ( 丟了包當然意味著網絡可能出現了擁塞) 。快重傳并非取消重傳計時器 ,而是在某些情況下可更早地重傳去失的報文段? 。
當發送方連續收到三個重復的 ACK? 報文時 ,直接重傳對方尚未收到的報文段? ,而不必等待那個報文段設置的重傳計時器超時 。
(2) 快恢復
快恢復算法原理:當發送端收到連續三個冗余 ACK ( 即重復確認) 時,就執行 “乘法減小” 算法 ,把慢開始門限 ssthresh? 設置為出現擁塞時發送方 cwnd? 的一半。與慢開始 (慢開始算法將擁塞窗口 cwnd 設置為 1) 不同之處是它把 cwnd 的值設置為慢開始門限 ssthresh 改變后的數值 , 然后開始執行擁塞避免算法 (“加法增大”),使擁塞窗口緩慢地線性增大 。
由于跳過了 cwnd 從 1 起始的慢開始過程 ,所以被稱為快恢復 。快恢復算法的實現過程如圖所示,作為對比 ,虛線為慢開始的處理過程 。
在流量控制中 ,發送方發送數據的量由接收方決定 ,而在擁塞控制中,由發送方自己通過檢測網絡狀況而決定 。實際上 ,慢開始、擁塞避免算法 、快重傳和快恢復幾種算法應該是同時應用在擁塞控制機制之中的 ,當發送方檢測到超時的時候就采用慢開始和擁塞避免 ,當發送方接收到冗余 ACK 的時候就采用快重傳和快恢復 。
在本節的最后,再次提醒讀者:發送方發送窗口的實際大小由流量控制和擁塞控制共同決定。 因此,發送方實際的發送窗同大小是由 rwnd? 和 cwnd? 中較小的那一個確定的 。
補充問題
1. MSS 設置的太大或者太小會有什么影響 ?
答:規定最大報文段 MSS 的大小并不是考慮到接收方的緩存可能放不下 TCP 報文段 。實際上,MSS 與接收窗口沒有關系 。TCP 的報文段的數據部分,至少要加上40 字節的首部 ( TCP 首部至少 20 字節和 IP 首部至少 20 字節),才能組裝成一個 IP 數據報。若選擇較小的 MSS 值,網絡的利用率就很低 。設想在極端情況下 ,當 TCP 報文段中只含有 1 字節的數據時 ,在 IP 層傳輸的數據報的開銷至少有 40 字節。這樣,網絡的利用率就不會超過 1/41。到了數據鏈路層還要加 上一些開銷 ,網絡的利用率進一步降低 。但反過來 ,若 TCP 報文段很長 ,那么在 IP 層傳輸時有可能要分解成多個短數據報片 ,在終端還要把收到的各數據報片裝配成原來的 TCP 報文段 。當傳輸有差錯時 ,還要進行重傳 。這些都會使開銷增大 。
因此,MSS 應盡量大些 ,只要在四層傳輸時不要再分片就行 。由于IP 數據報所經歷的路徑是動態變化的 ,在一條路徑上確定的不需要分片的 MSS ,如果改走另一條路徑就可能需要進行分片。因此,最佳的 MSS 是很難確定的 。MSS 的默認值為 536 字節 ,因此在因特網上的所有主機都能接收的報文段長度是 536+20 ( TCP 固定首部長度) =556 字節。
2.? 為什么不采用 “三次握手” 釋放連接,且發送最后一次握手報文后要等待2MSL( 最長報文段壽命 ,Maximum Segment Lifetime )的時間呢?
答:原因有兩個 :
第一、為了保證 A 發送的最后一個確認報文段能夠到達 B。如果 A 不等待 2MSL ,若 A 返回的最后確認報文段丟失 ,則 B 不能進入正常關閉狀態 ,而 A 此時已經關閉 ,也不可能再重傳 。
第二、防止出現 “己失效的連接請求報文段”。 A 在發送完最后一個確認報文段后 ,再經過 2MSL? 可保證本連接持續的時間內所產生的所有報文段從網絡中消失。造成錯誤的情形與不采用 “兩次握手” 建立連接的原因所述的情形相同 。
注意:服務器結束 TCP 連接的時間要比客戶端早一些 ,因為客戶機最后要等待 2MSL 后才可以進入 CLOSED 狀態。
3.? 如何判定此確認報文段是對原來的報文段的確認 ,還是對重傳的報文段的確認 ?
答:由于對于一個重傳報文的確認來說 ,很難分辨它是原報文的確認還是重傳報文的確認? ,使用修正的 Karn? 算法作為規則 :在計算平均往返時間RTT時,只要報文段重傳了 ,就不采用其往返時間樣本 ,且報文段每重傳一次 ,就把 RTO 增大一些。
4. TCP 使用的是 GBN 還是選擇重傳呢 ?
答:這是一個有必要弄清的問題。在前面講過 ,TCP 使用累計確認 ,這看起來像是 GBN 的風格。但是,正確收到但失序的報文并不會被丟棄 ,而是緩存起來 ,并且發送冗余 ACK 指明期望收到的下一個報文段 ,這是 TCP 方式和 GBN 的顯著區別。例如,A 發送了 N 個報文段 ,其中第 k ( k < N ) 個報文段丟失 ,其余 N-1 個報文段正確地按序到達接收方 B。當使用 GBN 時,A 需要重傳分組 k,以及所有后繼分組 k + 1,k +2 ,… ,N 。相反,TCP 卻至多重傳一個報文段 ,即報文段 k。另外,TCP 中提供一個 SACK ( Selective ACK ) 選項,也就是選擇確認選項 。當使用選擇確認選項的時候 ,TCP 看起來就和 SR 非常相似了。因此,TCP 的差錯恢復機制可以看成是 GBN 和 SR 協議的混合體 。
5.?為什么超時時間發生時?cwnd?被置為?1,而收到?3?個冗余?ACK?時?cwnd?減半???
答:大家可以從這個角度考慮?:超時事件發生和收到?3?個冗余?ACK?,哪個意味著網絡擁塞程度更嚴重??通過分析不難發現?,在收到?3?個冗余?ACK?的情況,網絡雖然擁塞,但是至少還有?ACK?報文段能夠被正確交付?。而當超時發生時?,說明網絡可能己經擁塞得連ACK?報文段都傳輸不了了?,發送方只能等待超時后重傳數據?。因此,超時時間發生時?,網絡擁塞更嚴重?,那么發送方就應該最大限度地抑制數據發送量?,所以?cwnd?置為?1;收到?3?個冗余?ACK?時,網絡擁塞不是很嚴重,發送方稍微抑制一下發送的數據量即可?,所以?cwnd?減半。
6. ?為什么不采用?“兩次握手”?建立連接呢??
答:這主要是為了防止兩次握手情況下己失效的連接請求報文段突然又傳送到服務端,而產生了錯誤?。考慮下面這種情況?:客戶?A?向服務器?B?發出?TCP?連接請求?,第一個連接請求報文在網絡的某個結點長時間滯留?,A?超時后認為報文丟失?,于是再重傳一次連接請求?,B?收到后建立連接。數據傳輸完畢后雙方斷開連接。而此時,前一個滯留在網絡中的連接請求到達了服務端B,?而?B?認為?A?又發來連接請求?,此時若是使用?“三次握手”則?B?向?A?返回確認報文段?,由于是一個失效的請求?,因此?A?不予理睬?,建立連接失敗?。若采用的是?“兩次握手”,則這種情況下?B認為傳輸連接已經建立?,并一直等待?A?傳輸數據?,而?A?此時并無連接請求?,因此不予理睬?,這樣就造成了?B?的資源白白浪費了。
7. ?是否?TCP?和?UDP?都需要計算往返時間?RTT?
答:往返時間?RTT 只是針對傳輸層?TCP?協議才很重要?,因為?TCP?要根據?RTT?的值來設置超時計時器的超時時間?。
UDP?沒有確認和重傳機制?,因此?RTT?對?UDP?沒有什么意義?。
因此,不能籠統地說“往返時間?RTT?對傳輸層來說很重要”?,因為只有?TCP?才需要計算?RTT,而 UDP?不需要計算?RTT?。
8. ??為什么?TCP?在建立連接時不能每次都選擇相同的?、固定的初始序號??
答:1)?假定主機?A?和?B?頻繁地建立連接?,傳送一些?TCP?報文段后?,再釋放連接?,然后又不斷地建立新的連接?、傳送報文段和釋放連接?。
2)?假定每一次建立連接時?,主機?A?都選擇相同的?、固定的初始序號,如選擇 1。
3)?假定主機?A?發送出的某些?TCP?報文段在網絡中會滯留較長的時間?,以致造成主機?A?超時重傳這些?TCP?報文段?。
4)假定有一些在網絡中滯留時間較長的?TCP?報文段最后終于到達了主機?B,但這時傳送該報文段的那個連接早己釋放了?,而在到達主機?B?時的?TCP?連接是一條新的?TCP?連接。
這樣?,工作在新的?TCP?連接的主機?B?就有可能會接收在舊的連接傳送的?、已經沒有意義的、 過時的?TCP?報文段?(因為這個?TCP 報文段的序號有可能正好處在現在新的連接所使用的序號范圍之中),結果產生錯誤?。
因此,必須使得遲到的 TCP 報文段的序號不處在新的連接中所使用的序號范圍之中 。 這樣 ,TCP 在建立新的連接時所選擇的初始序號一定要和前面的那些連接所使用過的序號不一樣 。因此,不同的TCP 連接不能使用相同的初始序號。
9. 假定在一個互聯網中 ,所有的鏈路的傳輸都不出現差錯,所有的結點也都不會發生故障。 試問在這種情況節 ,TCP 的 “可靠交付” 的功能是否就是多余的 ?
答:不是多余的 。TCP? 的 “可靠交付” 功能在互聯網中起著至關重要的作用 。至少在以下列舉的情況下, TCP 的 “可靠交付” 功能是必不可少的 。
1) 每個 IP 數據報獨立地選擇路由 ,因此在到達目的主機時有可能出現失序 。
2)? 由于路由選擇的計算出現錯誤 ,導致IP 數據報在互聯網中轉圈 。最后數據報首部中的生存時間 TTL 的數值下降到零。這個數據報在中途就被丟失了 。
3) 在某個路由器突然出現很大的通信量 ,以致路由器來不及處理到達的數據報 。因此有的數據報被丟棄 。
以上列舉的問題表明了 :必須依靠 TCP “可靠交付” 功能才能保證在目的主機的目的進程中接收到正確的報文。
本節的知識架構圖如下 :