端到端協議

端到端協議 第五章

從前幾章研究的主機到主機的分組傳遞服務到轉向進程到進程之間的通信信道,這正是網絡體系結構中傳輸層(transport)的任務,由於它支持端點應用程序之間的通信,因此傳輸層協議有時也被稱爲端到端(end to end)協議。

因特網提供盡力而爲(best-effort)的服務,爲滿足應用程序所需的高級服務,不同傳輸層協議用於不同的算法組合。代表性的4種有:一個簡單的異步多路分解服務,一個可靠的字節流服務,一個請求/應答服務和一個用於實時應用的服務。

5.1 簡單的多路分解協議 (UDP)

可能最簡單的傳輸協議是把下層網絡的主機到主機的傳遞服務擴展到進程到進程的通信服務。任何主機上都有可能運行多個進程,因此該洗衣至少需要增加一個多路分解功能,以便每臺主機上的多個進程能夠共享網絡。除此之外,傳輸協議不再下層網絡提供的服務增加任何其他功能。因特網提供的用戶數據報協議(User Datagram Protocol),就是這樣的傳輸協議。

值得注意的是標識目的進程的地址形式(可以用操作系統賦予的進程標識符pid使進程之間直接地相互識別,但無法擴展至多個不同的系統),UDP採用的方式是使用一個稱謂端口port的抽象定位器,使進程之間能夠間接的相互識別。基本思想是源進程向端口發送消息而目的進程從端口接收消息。 <主機,端口>構成了UDP協議的多路分解密鑰。

如何相互知道進程端口號? 策略是服務器進程在一個知名端口well-known port接收消息,即知名端口只有一個。有時候,知名端口僅僅是通信的開始點:客戶機和服務器用這個端口達成一致,並在另外一個端口進行後續的通信,以便釋放知名端口給其他客戶進程使用。

一般來說一個端口是由一個消息隊列實現的,當一個消息到達時,協議會把該消息加到隊列的末尾,如果隊列滿了,消息會被丟棄。這裏並沒有讓發送發減慢發送速度的流量控制機制。

雖然UDP沒有實現流量控制或可靠的/有序的傳輸,但它不僅僅是簡單地把消息多路分解給某個應用進程,而是多做了工作,通過在首部中的校驗和部分進行校驗確保消息的正確性。

5.2 可靠的字節流 Transmission Control Protocol

TCP能保證可靠的,有序的字節流傳輸,它是全雙工協議,也就是說每個TCP連接直接一對字節流,每個方向上一個字節流,他還有流量控制機制,另外,像UDP一樣,TCP支持多路分解機制。此外,TCP也實現了一個高度調整的擁塞控制機制,這種機制的思想是控制TCP發送方發送數據的速度,其目的不是爲了防止發送方發出的數據超出方的接收能力,而是防止發出方發出的數據超出網絡的容量。

流量控制與擁塞控制的區別 流量控制防止發送方發出的數據超出接收方的接收能力,擁塞控制防止過多的數據注入網絡而造成交換機或鏈路超載。因此流量控制是一個端到端的問題,而擁塞控制則是主機如何同網絡交互的問題。

5.2.1 端到端的問題

TCP的核心是滑動窗口算法。因爲TCP是在整個因特網上而不是在一個點到點鏈路上運行,所以它們存在着很多重要的差別。 在連接建立階段發生的事件之一,是雙方建立某種共享狀態使滑動窗口算法開始運行。連接斷開階段是必要的,因爲只有這樣雙方主機才知道是釋放這種狀態的時候。

TCP連接與點到點鏈路連接的區別

  1. 第二章描述的滑動窗口算法運行在總是連接兩臺計算機的一條物理鏈路上,但TCP仍然支持運行在因特網中任意兩臺計算機上的進程之間的邏輯連接。
  2. 儘管來連接兩臺相同的計算機的一條物理鏈路具有固定的RTT,但是TCP連接很可能具有差異很大的往返時延。
  3. 分組通過因特網時可能重排序,這在點到點鏈路上是不可能的,因爲在鏈路一段先發送的分組一定先到達另一端。
  4. 連接點到點鏈路的計算機通常被設計成支持這種鏈路。流量控制問題
  5. 因爲一個直連鏈路的發送方不能以超出鏈路帶寬所允許的速率發送數據,而且只有一臺主機向鏈路注入數據,所以它不可能不知道鏈路擁塞。但是TCP並不知道。

在TCP中,下層IP網絡被認爲是不可靠的,而且會使傳遞消息錯序,TCP在端到端的基礎上利用滑動窗口算法提供可靠/有序的傳送。

5.2.2 報文段格式

TCP是面向字節的協議,這就是說發送方向一個TCP連接寫入字節,接收方從這個TCP連接讀出字節。

實際上,源主機上的TCP收集發送進程交付的字節,存儲到緩衝區中,積累到足夠的數量,將其一起放入一個大小適宜的分組,再發送給目的主機上的對等實體。目的主機上的TCP把這個分組的內容存入一個接收緩衝區,接收進程在空閒時從這個緩衝區讀出字節。

5.2.3 連接的建立和終止

注意,儘管連接的建立是一個非對稱的活動(一方執行被動打開而另一方執行主動打開),但是連接的斷開則是對稱的活動(每一方必須獨立的關閉連接)。因此有可能一方已經完成了關閉連接,意味着它不再發生數據,但是另一方卻仍保持雙向連接的另一半爲打開狀態並且繼續發生數據。

三次握手

TCP使用的建立和終止連接的算法稱爲”三次握手”(three-way handshake),指客戶機和服務器之間要交換三次消息。

算法的思想是雙方需要商定一些參數,在打開一個TCP連接的時候,參數就是雙方打算爲各自的字節流使用的開始序號。首先,客戶機(主動參與方)發送一個報文段給服務器(被動參與方),聲明它將使用的初始序號(Flags = SYN,SequenceNum=x),服務器用一個報文段響應確認客戶端的序號(Flags = ACK,Ack= x+1),同時聲明自己的初始序號(Flags=SYN,SequenceNum=y),最後,客戶機用第三個報文段響應,確認服務器的序號(Flags = ACK,Ack=y+1)。每一段的確認序號比發送來的序號大一的原因是Acknowledgment字段實際指出”希望接收的下一個序號”,從而隱含地確認前面所有的序號。前兩個報文段都使用計時器,如果沒有收到所希望的應答,就會重傳報文段。

TCP規範要求連接的每一方隨機地選擇一個初始序號,是爲了防止同一個連接的兩個實例過快地重複使用同一個序號,也就是說,仍舊有可能出現以前的連接實例的一個數據段干擾後來的連接實例的情況。

狀態轉換

初始都爲closed,客戶端主動打開併發送SYN信號,客戶端進入SYN_SENT,服務器端被動打開進入LISTEN狀態,之後當服務器端收到客戶端發來的SYN,進入SYN_RCVD狀態併發送SYN+ACK報文段響應,這個報文段到達客戶端後,會使客戶端進入ESTABLISHED狀態並向服務器發送一個ACK報文段,當這個報文段到達後,服務器轉移到ESTABLISHED。到此結束三次握手的狀態轉換。

5.2.4 滑動窗口再討論

TCP窗口算法服務於這樣三個目的

  1. 保證數據的可靠傳遞
  2. 確保數據的有序傳遞
  3. 增強發送方和接收方之間的流量控制。

TCP與以前算法不同之處在於增加了流量控制功能,特別是TCP並不使用一個固定尺寸的滑動窗口,而是由接收方向發送方通知(advertise)它的窗口尺寸。這是通過TCP首部的AdvertisedWindow字段完成。接收方根據分配給連接用於緩存數據的內存數量,爲AdvertisedWindow選擇一個合適的值。

可靠和有序的傳輸

發送方的TCP維護一個發送緩衝區,該緩衝區用來存儲那些已被髮出但未被確認的數據和已被髮送應用程序寫入但未發出的數據。在接收方,TCP維護一個接收緩衝區,存放那些到達的錯序數據和那些按正確順序到達但應用進程無暇讀出的數據。

發送方緩衝區維護3個指針 LastByteAcked,LastByteWritten,LastByteSent

同樣,接收方緩衝區也維護着3個指針 LastByteRead,NextByteExpected,LastByteRcvd

流量控制

緩衝區具有有限的大小。接收方通過給發送方通知一個不大於他所能存儲數據量的窗口,就能控制發送方的發送速率。 TCP只會當接收到報文段時發出一個報文段迴應,這個響應包含AcknowledgmentAdvertisedWindow字段的最新值,即使這兩個值自上次發送以來沒有改變。問題就在於此,當窗口爲0後,就不允許發送方發送任何數據,就意味着它沒辦法發現在將來的某個時刻通知窗口不再是0.接收方的TCP不會自發的發送不包含數據的報文段,他只在響應到達的報文段時發送他們。 TCP按如下方式處理這種情況,當窗口爲0時,發送方仍然堅持不停的發送一個只有1字節的報文段。

發送方週期性的發送探測報文段的原因是:TCP被設計成使接收方儘可能的簡單,即他只響應從發送方發來的報文段,而它字節從不發起任何活動。我們稱其爲聰明的發送方/笨拙的接收方(smart sender/dumb receiver)規則。

5.2.5 觸發傳輸

TCP有三種機制觸發一個報文段的傳輸。

  1. TCP維護着一個變量,稱爲最大報文段長度(MSS),一旦TCP從發送進程收集到MSS個字節,它就發送一個報文段,通常把MSS設置爲TCP能發送而且不造成本地IP分段的最大報文段長度,也就是說,MSS被設置成直接連接網絡的MTU減去TCP和IP的首部的大小。
  2. 發送進程明確要求TCP發送一個報文段,特別是TCP支持push操作,發送進程調用這個操作能使TCP將緩衝區中所有未發送的字節發送出去,
  3. 定時器激活,結果報文段中包含當前緩衝區中所有需要被髮送出去的字節,

傻瓜窗口症狀

一味地利用任何可用窗口的策略會導致現在稱作傻瓜窗口症狀的情形。 所有問題又回到了:發送方決定什麼時候才傳輸一個報文段?

Nagle算法引入了一種完美的自計時(self-clocking)方案,其思想是隻要TCP發出了數據,發送方終究會收到一個ACK,可以把這個ACK看成激活的定時器,觸發傳輸更多的數據。 Nagle提供了一條決定何時傳輸數據的簡單統一規則:如果窗口大小允許,就可以發出一個滿載的報文段。如果當前沒有處於傳輸中的報文段,也可以立即發出一個小報文段,但是如果有傳輸的報文段,發送方就必須等待有ACK到達纔可傳輸下一個報文段。

5.2.6 自適應重傳

由於TCP保證可靠的數據傳輸,所有如果在一定的時限內沒有收到ACK,那麼它就會重傳每個報文段。TCP把這個超時設置成它期望的連接兩端的RTT函數。選擇一個合適的超時值並不容易。爲了處理這個問題,TCP使用了一種自適應重傳機制。

原始算法

維持一個RTT的平均運行值,並把超時值作爲這個RTT的一個函數計算。

Karn/Partridge算法

原始算法有個明顯的缺陷,問題是ACK實際上並不確認一次傳送,它實際上確認數據的接收,無法確定收到的ACK是針對第一個報文段還是第二個重發的報文段。 解決辦法相當簡單,當TCP重傳一個報文段時,停止計算RTT的樣本值,它只爲僅發送一次的報文段測量。同時對TCP重傳機制做了一個小修整。每次TCP重傳,它設置下次的超時值爲上次的兩倍。

發佈了49 篇原創文章 · 獲贊 1 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章