【計算機網絡】傳輸層
傳輸層協議概述
傳輸層協議為運行在不同host上的進程提供了一種邏輯通信機制。使得端到端不需要關心中間的過程,直接可以看作是可以通信的進程。
網絡層和傳輸層的區(qū)別
網絡層是為主機之間提供邏輯通信,運輸層為應用進程之間提供端到端的邏輯通信。
傳輸層對收到的報文進行差錯檢測,IP數據報首部中的校驗和字段只檢驗頭部是否出現差錯,而不檢查數據部分。
傳輸層位于網絡層之上,依賴于網絡層服務,對網絡層服務進行增強,向高層屏蔽了下面網絡核心的細節(jié)。它使應用進程看見的就好像在兩個運輸層實體之間有一條端到端的邏輯通信信道。
傳輸層的協議
兩個對等運輸實體在通信時傳送的數據單元叫做運輸協議數據單元TPDU,但在TCP/IP體系中,TCP叫報文段,UDP叫數據報。
- UDP
- 不需要先建立連接
- 遠程主機的傳輸層在收到UDP報文后,不需要給出任何確認
- 不可靠的交付服務
- 基于“盡力而為”的網絡層,沒有做可靠性方面的擴展
- TCP
- 可靠、按序的交付服務
- 擁塞控制
- 流量控制
- 連接建立、數據報傳送結束后要釋放連接
- 額外開銷:確認、流量控制、計時器、連接管理
兩種服務均不保證:延遲、帶寬

傳輸層的端口
在協議棧層間的抽象的協議端口是軟件端口,硬件端口是不同硬件設備進行交互的接口,而軟件端口是應用層的各種協議進程與傳輸實體間進行層間交互的一種地址。端口號只具有本地意義。
兩大類端口號:
- 服務器使用的端口號
- 熟知端口號
- 系統端口號
- 客戶端使用的端口號
多路復用和多路分用
如果某層的一個協議對應直接上層的多個協議/實體,則需要復用/分用。
接收端進行多路分用:傳輸層依據頭部信息將接收到的Segment交給正確的Socket,即不同的進程
發(fā)送端進行多路復用:從多個Socket接收數據,為每塊數據封裝上頭部信息,生成Segment,交給網絡層。
分用的流程:
- 主機接收到IP數據報
- 每個數據報攜帶源IP地址,目的IP地址
- 每個數據報攜帶一個傳輸層的段
- 每個段攜帶源端口號和目的端口號
- 主機收到Segment后,傳輸層協議提取IP地址和端口號信息,將Segment導向相應的Socket
- TCP更多處理
無連接分用:
- 利用端口號創(chuàng)建Socket
- UDP的Socket用二元組標識(目的IP地址,目的端口號)
- 主機收到UDP段后
- 檢查段中的目的端口號
- 將UDP段導向綁定在該端口號的Socket
- 來自同源的IP地址和端口號的IP數據報被導向同一個Socket
- 源端口號提供“返回地址”,返回數據
面向連接的分用:
- TCP的Socket的四元組標識
- 源IP地址
- 源端口號
- 目的IP地址
- 目的端口號
- 接收端利用所有的四個值將Segment導向合適的Socket
- 服務器可能同時支持多個TCP Socket
- Web服務器為每個客戶端開不同的Socket

用戶數據包協議UDP
UDP概述
用戶數據包協議UDP只在IP的數據報服務上增加了很少一點的功能,就是復用和分用的功能記憶差錯檢測功能。
UDP的特點
- 無連接
- 不需要握手
- 每個UDP段的處理獨立于其他段
- 減少了開銷和發(fā)送數據之前的時延
- "盡力而為"服務
- 丟失
- 非按序到達
- 不需要維持復雜的連接狀態(tài)表
- 面向報文
- 對應用層的報文,添加首部后就向下交付給IP層,UDP對于應用層的報文既不合并,也不拆分,保留這些報文的邊界。應用層給多長的報文,UDP就照發(fā),即一次發(fā)送一個報文。交付時也是一次交付一整個報文。因此應用層需要選擇合適大小的報文,若報文太長,IP層在發(fā)送時可能要進行分片,會降低IP層的效率
- 沒用擁塞控制
- 網絡的擁塞不會使源主機的發(fā)送速率降低,允許丟失一些數據
- UDP支持一對一、一對多、多對一和多對多的交互通信
- UDP首部開銷小
- 只有8字節(jié),TCP20字節(jié)

UDP的首部格式
UDP有兩個字段:數據字段和首部字段。
首部字段有8字節(jié):
- 源端口
- 目的端口
- 長度
- 校驗和:檢測UDP用戶數據包在傳輸中是否有錯,有錯就丟棄

如果接收方UDP的目的端口號不正確,就丟棄該報文,并有ICMP發(fā)送“端口不可達“差錯報文給發(fā)送方。
UDP 校驗和(checksum)
目的:檢查UDP段在傳輸中是否發(fā)生錯誤(如位翻轉)
發(fā)送方:
- 將段的內容視為16-bit整數
- 校驗和計算:計算所有整數的和,進位加在和的后面,將得到的值按位求反,得到校驗和
- 發(fā)送方將校驗和放入校驗和字段
接收方:
- 計算所收到段的校驗和
- 將其與校驗和字段進行對比
- 不相等:檢測出錯誤
- 相等:沒有檢測出錯誤(但有可能有錯誤)

TCP 概述
TCP主要特點
- 面向連接
- 必須建立連接和釋放連接
- 每條TCP連接只能有兩個端點,每條TCP連接只能是點對點
- TCP提供可靠交付的服務
- 無差錯
- 不丟失
- 不重復
- 按序到達
- 全雙工通信
- TCP允許通信雙方的應用進程在任何時候都能發(fā)送數據,TCP連接的兩端都舍友發(fā)送緩存和接收緩存
- 發(fā)送時,應用程序在把數據傳送給TCP的緩存后,就可以做自己的事情,而TCP在合適的時候把數據發(fā)送出去。接收時同理。
- 面向字節(jié)流
- ”流“指的是流入到進程或從進程流出的字節(jié)序列。
- 雖然應用程序和TCP的交互式一次一個數據塊(大小不等),但TCP把應用程序交下來數據看成僅僅是一連串的無結構的字節(jié)流。TCP并不知道所傳送的字節(jié)流的含義。
- TCP不保證接收方收到的數據塊和應用方所發(fā)出的數據塊具有對應大小的關系(例如發(fā)送方發(fā)給TCP10各數據塊,但接收方TCP可能只用了4個數據塊就把所有字節(jié)流交付給上層了)
- 注意:TCP連接是一條虛連接而不會一條真正的物理連接。
- TCP對應用進程一次把多長的報文發(fā)送到TCP的緩存中是不關心的,TCP根據對方給出的窗口值和當前網絡擁塞程序決定報文段包含多少字節(jié)(UDP的報文長度直接由應用進程決定)。如果TCP緩存的數據塊太長,TCP就可以把它劃分短一些再傳送,如果進程只發(fā)送一個字節(jié),TCP也會等待積累有足夠字節(jié)后再構成報文段發(fā)送出去。

TCP連接
TCP 把連接作為最基本的抽象。
每條TCP連接都有兩個端點,這兩個端點叫做套接字socket。端口號拼接到IP地址即構成了socket。
可靠傳輸的工作原理
理想傳輸條件的兩個特點:
- 傳輸信道不產生差錯
- 不管發(fā)送方以多塊的速率發(fā)送數據,接收方總是來得及處理收到的數據
停止等待協議
”停止等待“就是每發(fā)送完一個分組就停止發(fā)送,等待對方的確認,在收到確認后再發(fā)送下一個分組。
無差錯情況

出現差錯
如果接收方接收到數據時,檢測出了錯誤,就丟棄數據,其他什么都不做,也可能是數據報在傳輸過程中丟失了。這兩種情況,接收方不發(fā)送任何信息。
可靠傳輸協議是這么設計的:發(fā)送方超過一段時間仍然沒有收到確認消息,就認為剛發(fā)送的分組丟失了,因而重傳前面發(fā)送過的分組,這就是超時重傳。
完成超時重傳,就要每發(fā)送完一個分組設置一個定時器。如果在超時計時器到期之前就收到了對方的確認,就撤銷已設置的超時計時器。
注意點:
- 發(fā)送方發(fā)送完一個分組后,必須暫時保留已發(fā)送的分組的副本(為發(fā)生超時重傳時使用),只有在收到相應的確認后才能清除暫時保留的分組副本
- 分組和確認分組都必須進行編號,這樣才能明確是哪一個發(fā)送出去的分組收到了確認,而哪一個沒收到。對于等待停止協議,只要用1位編號(0和1)即可,可重復使用,但這種編號不能保證可靠傳輸。
- 超時計時器設置的重傳時間應當比數據在分組傳輸的平均往返時間更長一些。如果太長,通信效率就很低,太短,就產生必須要的重傳,浪費網絡資源。
確認丟失和確認遲到
確認丟失時,發(fā)送方重傳數據,接收方丟失這個重復的分組,并且要再次向發(fā)送方發(fā)送確認

上訴的這種可靠傳輸協議稱為自動重傳請求ARQ
信道利用率
停止等待協議的優(yōu)點就是簡單,但缺點就是信道利用率低。
流線線協議
- 允許發(fā)送方在收到ACK之前連續(xù)發(fā)送多個分組
- 更大的序列號范圍
- 發(fā)送方和接收方需要更大的存儲空間以及緩存分組
連續(xù)ARQ協議、滑動窗口協議
為提高傳輸效率,可采用流水線傳輸,采用連續(xù)ARQ協議或滑動窗口協議,滑動窗口協議較復雜,是TCP協議的精髓,后面介紹。
連續(xù)ARQ協議,發(fā)送方維持發(fā)送窗口,意義是:位于發(fā)送窗口內的5個分組都可以連續(xù)發(fā)送出去,而不需要等待對方的確認。這樣,信道利用率就提高了。發(fā)送方每收到一個確認,就把發(fā)送方窗口向前滑動一個分組的位置。

接收方一般采用累積確認的方式,接收方不必對收到的分組逐個發(fā)送確認,而可以在收到幾個分組后,對按序到達的最后一個分組發(fā)送確認,表示到這個分組為止的所有分組都已正確收到了。
累計確認優(yōu)點容易實現,缺點不能向發(fā)送方反映出接收方已經確認收到的所有分組的信息。比如,發(fā)送方發(fā)送了5個分組,但中間的第三個丟失了,這時接收方只能對前兩個分組發(fā)出確認,發(fā)送方無法知道后面三個分組的下落,只好把后面的三個分組都重發(fā),浪費網絡資源。
滑動窗口協議
- 窗口
- 允許使用的序列號范圍
- 窗口尺寸為N,最多有N個等待確認的消息
- 滑動窗口
- 隨著協議的運行,窗口在序列號空間內向前滑動
- 滑動窗口協議:GBN,SR
Selctive Repeat 協議
- 接收方對每個分組單獨進行確認
- 設置緩存機制,緩存亂序到達的分組
- 發(fā)送方只重傳那些沒收到ACK的分組
- 為每個分組設置定時器
- 發(fā)送方窗口
- N個連續(xù)的序列號
- 限制已發(fā)送未確認的分組

TCP報文段的首部格式
TCP首部的20個字節(jié)是固定的,后面4N字節(jié)是根據需要而增加的。

各個字段:
- 源端口和目的端口
-
序號(seq)
- 范圍0-2的32次方-1,序列號增加到最大,下一個序號就返回0。
- TCP是面向字節(jié)流的,在TCP連接中傳送的字節(jié)流中的每一個字節(jié)都按順序編號,整個要傳送的字節(jié)流的起始序列號必須在連接建立時設置。首部中的序號字段值指的是本報文段所發(fā)送的數據的第一個字節(jié)的序號。
- 例如,一報文段的序號字段值是 301,攜帶的數據共有100字節(jié)。這表明:這個報文段的第一個字節(jié)的序號是301,最后一個字節(jié)的序號是400,顯然,下一段報文段的序號應當從401開始。
-
確認號(ack)
- 占4個字節(jié),期望收到對方下一個報文段的第一個數據字節(jié)的序號
- 例如,接收方收到一個報文段,其序號字段值是501,而數據長度是200字節(jié),這表明接收方收到了900為止的數據,所以接收方期望收到的下一個數據序號是701,接收方發(fā)送給發(fā)送方的確認報文段中把確認號置為701。
- 記住:若確認號 = N,表明到序號N-1為止的所有數據都已正確收到。
- 數據偏移
- TCP首部長度
- 保留
- 緊急URG
- 確認ACK
- 僅當ACK = 1時,確認號字段才有效,當ACK = 0,確認號無效
- TCP規(guī)定,連接建立后所有傳送的報文段都必須把ACK置1
- 推送PSH
- 盡快交付,不等到整個緩存填滿再發(fā)送
- 復位RST
- RST = 1,TCP連接出現嚴重錯誤,必須釋放連接,在重新建立運輸連接。
- 同步SYN
- 在連接建立時用來同步序號,當SYN = 1 而ACK = 0時,表明這是一個請求報文段。
- 對方若同意建立,則SYN = 1,ACk = 1,發(fā)送響應報文段
- SYN = 1就表示連接請求或連接接受報文
- 終止FIN
- FIN = 1,釋放一個連接
- 窗口
- 指的是發(fā)送報文段的一方的接收窗口,窗口值:允許對方發(fā)送的數據量。
- 因為接收方有緩存空間的限制。
- 窗口值作為接收方讓發(fā)送方設置其發(fā)送窗口的依據
- 校驗和
- 檢驗首部和數據
- 緊急指針
- 選項
- TCP最初只規(guī)定了一種選項,最大報文段長度 MSS,MSS是每個TCP報文段中的數據字段的最大長度
TCP可靠傳輸的實現
以字節(jié)為單位的滑動窗口
舉例:A收到B發(fā)來的確認報文段,其中窗口是20字節(jié),確認號是21(表明B期望的下一個序號是31,30之前的數據已經收到了),下圖就是A構造的自己的發(fā)送窗口

發(fā)送窗口:在沒有收到B的確認的情況下,A可以連續(xù)把窗口內的數據都發(fā)送出去,凡是發(fā)送過的數據,在未收到確認之前都必須暫時保留,以便超時重傳時使用。
發(fā)送窗口的位置由窗口前沿和后沿的位置共同確定。前沿可能向后收縮,發(fā)生在對方通知的窗口縮小。
緩存空間和序號空間都是有限的,并且都是循環(huán)使用的。
發(fā)送緩存用來暫時存放:
- 發(fā)送應用程序傳送給發(fā)送方TCp準備發(fā)送的數據
- TCP已發(fā)送出但尚未收到確認的數據
接收方緩存:
- 按序到達的,但尚未被應用程序讀取的數據
- 未按序到達的數據
超時重傳時間的選擇
TCP采用一種自適應的算法,它記錄一個報文段發(fā)出的時間,以及收到相應的確認的時間,這兩個時間之差就是報文段的往返時間RTT。
選擇確認SACK
若收到的報文段無差錯,只是未按序號,中間缺少一些序號的數據,那么能否只重傳未正確達到的數據,選擇確認就是一種處理方法。
如果要使用選擇確認,在建立連接時,在TCP首部增加”允許SACK“的選項。
TCP的流量控制
利用滑動窗口實現流量控制
流量控制就是讓發(fā)送方的發(fā)送速率不要太快,要讓接收方來得及接收。
利用滑動窗口機制可以很方便地在TCP連接上實現對發(fā)送方的流量控制。在建立連接時,接收方要告訴發(fā)送方自己的接收窗口,發(fā)送方的發(fā)送窗口不能超過接收方給出的接收窗口的數值。
持續(xù)計時器(防止非零窗口的通知丟失):只要TCP連接的一方收到對方的零窗口通知,就啟動持續(xù)計時器,若持續(xù)計時器設置的時間到期,就發(fā)送一個零窗口探測報文段(僅1字節(jié)),而對方就在確認這個探測報文段時給出了現在的窗口值,如果窗口仍然為0,那就重置這個持續(xù)計時器,如果窗口不是0,那么死鎖的僵局就打破了。
考慮傳輸效率
TCP報文段發(fā)送時機的三種機制:
- TCP維持一個變量,表示當前放入緩存是數據,它等于最大報文段長度MSS時,就組裝成一個TCP報文段發(fā)出去
- 由發(fā)送方應用進程明確要求發(fā)送報文段,即TCP支持的推送操作。
- 發(fā)送方的一個計時器期限到了,就把當前已有的緩存數據裝入報文段發(fā)出。
TCP擁塞控制
擁塞控制的一般原理
若網絡中的許多資源同時呈現供應不足,網絡的性能就要明顯變壞,整個網絡的吞吐量將隨輸入負荷的增大而下降,這種情況叫做擁塞。
吞吐量:網絡中的數據是由一個個數據包組成,防火墻對每個數據包的處理要耗費資源。吞吐量是指在沒有幀丟失的情況下,設備能夠接受的最大速率。其測試方法是:在測試中以一定速率發(fā)送一定數量的幀,并計算待測設備傳輸的幀,如果發(fā)送的幀與接收的幀數量相等,那么就將發(fā)送速率提高并重新測試;如果接收幀少于發(fā)送幀則降低發(fā)送速率重新測試,直至得出最終結果。吞吐量測試結果以比特/秒或字節(jié)/秒表示。
擁塞控制就是防止過多的數據注入到網絡中,這樣就可以使網絡中的路由器或鏈路不止過載。流量控制往往指點對點通信量的控制,是個端到端的問題,流量控制就是要做抑制發(fā)送方數據的速率,以便接收到來得及接收。
造成擁塞的原因很復雜:
- 結點路由器緩存的存儲空間太小
- 處理機處理的速率太慢
- ...

擁塞控制是一個動態(tài)的問題,分為開環(huán)控制和閉環(huán)控制兩種方法。開環(huán)控制方法就是在設置網絡事先將有關擁塞的因素考慮周到,力求網絡在工作時不產生擁塞。
閉環(huán)控制的措施:
- 檢測網絡系統以便檢測到擁塞在何時何處發(fā)生
- 把擁塞發(fā)生的信息傳送到可采取行動的地方
- 調整網絡系統的運行以解決出現的問題
幾種擁塞控制方法
四種算法:
- 慢開始
- 擁塞避免
- 快重傳
- 快恢復
慢開始和擁塞避免
發(fā)送方維持一個擁塞窗口的狀態(tài)變量,擁塞窗口的大小取決于網絡的擁塞程序,并動態(tài)變化,發(fā)送方讓自己的發(fā)送窗口等于擁塞窗口。只要網絡沒出現擁塞,擁塞窗口就再增大一些。
慢開始算法:由小到大逐漸增大發(fā)送窗口,通常在剛剛開始發(fā)送時,先把擁塞窗口cwnd設置為一個最大報文段MSS,每收到一個確認后,擁塞窗口增加至多一個MSS,每經過一個傳輸輪次,擁塞窗口cwnd就加倍。發(fā)生擁塞(計時器超時還未收到確認)就將擁塞窗口值減到1,再開始慢開始算法。
擁塞避免算法:慢開始之后,進入擁塞避免階段,擁塞窗口每次增加1,按線性規(guī)律慢慢增長。

快重傳和快恢復
快重傳:要求接收方每收到一個失序的報文段 就立即發(fā)出重復確認,盡早重傳未確認的報文段
TCP的連接管理
TCP連接過程解決的問題:
- 要是每一方能夠確知對方的存在
- 要允許雙方協商一些參數(最大窗口值等)
- 能夠對運輸實體資源進行分配
TCP連接建立

流程:
- B的TCP服務進程先創(chuàng)建傳輸控制塊TCB,準備接受客戶進程的連接請求,服務器進程處于LISTEN狀態(tài),等待客戶的連接請求
- A的TCP客戶進程也首先創(chuàng)建傳輸控制模塊TCB,向B發(fā)出連接請求。首部中的同步位 SYN = 1,同時選擇一個初始序號 seq = x。TCP規(guī)定,SYN = 1的報文段不能攜帶數據,但要消耗掉一個序號。TCP客戶端進入 SYN-SENT(同步已發(fā)送)狀態(tài)。
- B收到連接請求報文段后,如同意建立連接,則向A發(fā)送確認,在確認報文段中把 SYN 和 ACK(大寫)都置為1,確認號ack(小寫)= x + 1,同事也為自己選擇一個初始序號seq = y。注意,這個報文段也不攜帶數據,同樣消耗一個序號,這時TCP服務器進程進入 SYN-RCVD(同步收到)狀態(tài)。
- TCP客戶端進程收到B的確認后,還要向B給出確認。確認報文段的ACK = 1,確認號ack = y + 1,自己的序號seq = x + 1。注意:ACK報文段可以攜帶數據,但如果不攜帶數據則不消耗序號,這種情況下,下一個數據報文段的序號仍是seq = x + 1。這時TCP連接已建立,A進入ESTABLISHED狀態(tài)。
說明:A還要發(fā)送一次確認,是為了防止已失效的連接請求報文段突然又傳送了B,因而產生錯誤。具體情況:A發(fā)出第一個連接請求,但延遲了,A就重發(fā)了一個請求,第一個請求延誤到連接釋放后的某個時間才到達B,這本來是一個失效的連接請求,但B以為是一個新的請求,就會給A一個確認,如果沒有第三次握手,那么連接就建立了,會造成資源浪費,有了第三次握手,A并不會理財B的確認,這樣連接就不會建立。
TCP連接釋放

流程:
- 數據傳輸結束后,通信的雙方都可釋放連接。
- A和B都處于ESTABLISHED狀態(tài),A的應用進程先向其TCP發(fā)出連接釋放報文段,并停止再發(fā)送數據,主動關閉TCP。A把連接釋放報文段 FIN 置1,其序號seq = u,它等于前面已傳送過的數據的最后一個字節(jié)的序號加1,這時A進入FIN-WAIT-1(終止等待1)狀態(tài),等待B的確認。注意:TCP規(guī)定,FIN報文段即使不攜帶數據,也消耗一個序號。
- B收到連接釋放報文段后,即發(fā)出確認,確認號ack = u+1,自己的序號seq = v,等于B前面已傳送過的數據的最后一個字節(jié)的序號加1,B就進入 CLOSE-WAIT(關閉等待)狀態(tài)。TCP服務器進程這時通知高層應用進程,從A到B這個方向的連接就釋放了。這時TCP處于半關閉狀態(tài),即A已經沒有數據要發(fā)送,但B發(fā)送數據,A還能接收。
- A收到來自B的確認后,就進入FIN-WAIT-2(終止等待2)狀態(tài),等待B發(fā)出的連接釋放報文段。
- 若B已經沒有要向A發(fā)送的數據,就發(fā)出連接釋放報文段,FIN = 1,B進入(LAST-ACK)狀態(tài),等待A確認
- A發(fā)送確認報文段,ACK = 1,進入TIME-WAIT狀態(tài),這時TCP還沒有釋放掉,必須經過時間等待計時器設置的時間后,A才能進入CLOSE狀態(tài)。
TCP的有限狀態(tài)機
