第六章TCP和UDP基本原理

    TCP/IP協議族的傳輸層協議主要包括TCP和UDP。TCP是面向連接的可靠的傳輸協議。它支持在並不可靠的網絡上實現面向連接的可靠數據傳輸。UDP是無連接的傳輸協議,主要用於支持在校可靠的鏈路上的數據傳輸,或用於對延遲敏感的應用。

TCP/IP傳輸層的作用

wKioL1ZqjBvDq5JDAAEp8hPswHw000.jpg

TCP/IP的傳輸層位於應用層和網絡層之間,爲終端主機提供端到端的連接。TCP/IP的傳輸層有TCP和UDP兩種主要協議。TCP和UDP都基於相同的網絡層協議IP。傳輸層協議的主要作用:

  • 提供面向連接或無連接的服務:傳輸層協議定義了通信兩端點之間是否需要建立可靠的連接關係。

  • 維護連接狀態:如果必須在通信前建立連接關係,傳輸層協議必須在其數據庫中記錄這種連接關係,並且通過某種機制維護連接關係,及時發現連接故障燈。

  • 對應用層數據進行分段和封裝:應用層數據往往是大塊的或持續的數據流,而網絡只能發送長度有限的數據包,傳輸層協議必須在船上應用層數據之前將其劃分成適當尺寸的段(segment),再交給IP協議發送。

  • 實現多路複用(Multiplexing):一個IP地址可以標識一個主機,一對“源-目的”IP地址可以標識一對主機的通信關係,而一個主機上卻可能同時有多個程序訪問網絡,因此傳輸層協議採用端口號(port number)來標識這些上層的應用程序,從而使這些程序可以複用網絡通道。

  • 可靠地傳輸數據:數據在跨網絡傳輸過程中可能出現錯誤、丟失、亂序等種種問題,傳輸層協議必須能夠檢測並更正這些問題。

  • 執行流量控制(flow control):當發送方的發送速率超過接收方的接收速率時,或者當資源不足以支撐數據的處理時,傳輸層負責將流量控制在合理的水平;反之,當資源允許時,傳輸層可以放開流量,使其增加到適當的水平。

TCP協議基本原理

TCP協議的特點

wKiom1Zqj6TDLOEjAAE0KmJyyAs987.jpg

RFC793定義的TCP是一種面向連接的、端到端的可靠傳輸協議。TCP的主要特點包括:

  • 三次握手(Three-Way Handshake)建立連接:確保連接建立的可靠性。

  • 端口號:通過端口號標識上層協議和服務,實現了網絡通道的多路複用。

  • 完整性校驗:通過對協議和載荷數據計算校驗和(Checksum),保證了接收方能檢測出傳輸過程中可能出現的差錯。

  • 確認機制:對於正確接收到的數據,接收方通過顯式應當通告發送方,超出一定時間之後,發送方將重傳沒有被確認的段,確保傳輸的可靠性。

  • 序列號:發送的所有數據都擁有唯一的序列號,這樣不但唯一標識了每一個段(segment),而且明確了每個段在整個數據流中的位置,接收方可以利用這些信息實現確認、丟失檢測、亂序重排等功能。

  • 窗口機制:通過可調節的窗口,TCP接收方可以通告期望的發送速度,從而控制數據的流量。

TCP封裝

wKiom1ZuawyBa4iWAAOeRbNuRAs242.jpgTCP段的頭格式如上圖所示,其協議頭最少20個字節。其中主要字段如下:

  • 源端口(Source Port):16位的源端口字段包含初始化通信的端口號。源端口和源IP地址的作用是標識報文的返回地址。

  • 目的端口(Destination Port):16位的目的端口字段定義傳輸的目的。這個端口指明接收方計算機上的應用程序接口。

  • 序列號(Sequence Number):該字段用來標識TCP源端設備向目的端設備發送的字節流,它表示在這個報文段中的第一個數據字節。如果將字節流看作在兩個應用程序間的單向流動,則TCP用序列號對每個字節進行計數。序列號是一個32位的數。

  • 確認號(Acknowledgement Number):TCP使用32位的確認號字段標識期望收到的下一個段的第一個字節,並聲明此前的所有數據都已經正確無誤地收到,因此,確認號應該是上次已成功收到的數據字節序列號加1.收到確認號的源計算機會知道特定的段已經被收到。確認號的字段只在ACK標誌被設置時纔有效。

  • 數據偏移(Data Offset):這個4位字段包括TCP頭大小,以32位數據結構爲單位。

  • 保留(Reserved):6位置0的字段。爲將來定義新的用途保留。

  • 控制位(Control Bits):共6位,每1位標誌可以打開一個控制功能,者六個標誌從左至右是URG(Urgent Pointer field signficant 緊急指針字段標誌)、ACK(Acknowledgement field significant 確認字段標識)、PSH(Push Function 推功能)、RST(Reset the connection 重置連接)、SYN(Synchronize sequence numbers 同步序列號)、FIN(No more data from sender 數據傳送完畢)。

  • 窗口(Window):目的主機使用16位的窗口字段告訴源主機它期望每次收到的數據的字節數。窗口字段是一個16位字段。

  • 校驗和(Checksum):TCP頭包括16位的校驗和字段用於錯誤檢查。源主機基於部分IP頭信息、TCP頭和數據內容計算一個校驗和,目的主機也要進行相同的計算,如果收到的內容沒有錯誤過,兩個計算結果應該完全一樣,從而證明數據的有效性。

  • 緊急指針(Urgent Pointer):緊急指針字段是一個可選的16位指針,指向段內的最後一個字節位置,這個字段只在URG標誌被設置時纔有效。

  • 選項(Option):至少1字節的可變長字段,標識哪個選項(如果有的話)有效。如果沒有選項,這個字節等於0,說明選項字段的結束。這個字節等於1表示無需再有操作;等於2表示下四個字節包括源機器的最大段長度(Maximum Segment Size,MSS),MSS是數據字段中可包含的最大數據量,源和目的機器對此達成一致。當一個TCP連接建立時,連接的雙方都要通告各自的MSS,協商可以傳輸的最大段長度。常見的MSS有1024字節,以太網可達1460字節。

  • 數據(Data):從技術上講,它並不是TCP頭的一部分,但應該瞭解到,數據字段位於緊急指針和/或選項字段之後,填充字段之前。字段的大小是最大的MSS,MSS可以在源和目的機器之間協商。數據段可能比MSS小,但不能比MSS大。

  • 填充(Padding):這個字段中加入額外的零,以保證TCP頭是32位的整數倍。

TCP/UDP端口號

wKioL1ZudcuwVXCTAAFRPLDLaXU551.jpg

    在IP網絡中,一個IP地址可以唯一地標識一個主機。但一個主機上卻可能同時又多個程序訪問網絡,要標識這些程序,只用IP地址就不夠了。因此TCP/UDP採用端口號來標識這些上層的應用程序,從而使這些程序可以複用網絡通道。而爲了區分TCP和UDP協議,IP用協議號6標識TCP,用協議號17標識UDP。

在實際的端到端通信中,通信的雙方實際上是兩個應用程序,者兩個程序都需要用各自的端口號來進行標識。所有,一個通信連接可以用雙方的IP地址以及雙方的端口號來標識,而每一個數據報內也必須包含源IP地址、源端口、目的IP地址和目的端口。IP地址在IP頭中標出,而端口號在TCP/UDP頭中標出。

    TCP/UDP的端口號是一個16位二進制數,即端口號範圍可以爲0~65535。其中,端口0~1023由IANA(Internet Assigned Number Authority ,Internet號碼分配機構)統一管理,分配或保留衆所周知的服務使用,這些端口稱爲衆所周知端口(Well-known Port).大於1023的端口號沒有統一的管理,可以由應用程式任意使用。詳細分配信息可參考RFC1700。

TCP連接的建立

wKioL1Zuekqx3qE3AAF2TgDi6CY557.jpg

由於TCP使用的網絡層協議IP只提供不可靠、無連接的傳送服務,爲確保連接的建立和終止都是可靠的,TCP使用三次握手(Three-Way Handshake)的方式來建立可靠的連接。TCP使用報頭中的SYN(Synchronization Segment,同步段)來描述創建一個連接的三次握手。另外,握手過程確保TCP只有在兩端一致同意的情況下,纔會打開一個連接。

TCP的三次握手建立連接的過程如下:

  1. 由發起方HostA向被叫方HostB發出連接請求。將段的序列號標爲a,SYN置爲。由於是雙方發的第一包,ACK無效。

  2. HostB收到連接請求後,讀出序列號爲a,發送序列號爲b的包,同時將ACK置爲有效,將確認號置爲a+1,同時將SYN置位。

  3. HostA收到HostB的連接確認後,對該確認再次作確認。HostA收到確認號爲a+1、序列號爲b的包後,發送序列號爲a+1、確認號b+1的段進行確認。

  4. HostB收到確認報文後,連接建立。

這樣,一個雙向的TCP連接就建立好了,雙方可以開始傳輸數據。

TCP連接的拆除

wKiom1ZyZczA6btMAAGFc2jAwNg182.jpg

TCP用FIN(Finish Segment,結束段)來描述關閉一個連接的消息。

上圖所示是一個常規的TCP連接終止過程。當數據傳輸結束後,需要端口連接,其過程描述如下:

  1. HostA要求終止連接,發送序列號爲p的段,FIN置爲有效,同時確認此前剛收到的段。

  2. HostB收到HostA發送的段後,發送ACK端,確認號爲p+1,同時關閉連接。

  3. HostB發送序列號爲q的段,FIN置爲有效,通知連接關閉。

  4. HostA收到HostB發送的段後,發送ACK端,確認號爲q+1,同時關閉連接。

TCP連接至此終止。可見這是一個四次握手過程。

TCP可靠傳輸機制

傳輸確認

wKiom1ZyZ8PjPhZLAAHWjddweUs797.jpg

    爲保證數據傳輸的可靠性,TCP要求對傳輸的數據進行確認。TCP協議通過序列號和確認號來確保傳輸的可靠性。每一次傳輸數據時,TCP都會標明該段的起始序列號,一遍對方確認。在TCP協議中並不直接確認收到那些段,而是通知發送方下一次該發送哪一個段,表示前面的段都已收到。序列號還可以幫助接收方對亂序到達的數據進行排序。

  收到一個段確認一個段的方法雖然簡單,但是會消耗網絡資源較多。爲了提高通信效率,TCP採取了一些提高效率的方法。

    首先,TCP並不要求對每個段一對一地發送確認。接收端可以用一個ACK確認之前收到的所有數據。例如,接收到的確認序列號爲N+1時,表示接收方對到N爲止的所有數據全部正確接收。

    另外,TCP並不要求必須單獨發送確認,而是允許將確認放在傳輸給對方的TCP數據段中。如果收到一個段後沒有段要馬上傳到對方,TCP通常會等待一個微小的延時,希望將確認與後續的數據段合併發出。

    由於每個段都有唯一的編號,這樣當對方收到了重複的段時容易發現,數據段丟失後也容易定位,亂序後也可以重新排列。在動態路由網絡中,一些數據包很可能經過不同的路徑,因此報文可能會亂序到達。32位的序列號由接收端計算機用於把段的數據重組成最初形式。

    上圖給出了一個經過簡化的TCP傳輸過程示例。爲了便於理解,本例只關注從HostA到HostB的單向傳輸。架設HostA向HostB發送的初始序列號爲1,且發送窗口爲4096字節,HostA向HostB發送的每個段數據長度爲1024字節,HostA將一次性向HostB發送4個段。而HostB收到並校驗了數據的正確性後,在回送確認時只需發送確認號4096+1=4097,就可以表示4096之前的全部數據都已經正確接收,下一次期望接收從4097開始的數據。下一次,HostA仍然一次發送總量爲4096字節的4個段給HostB。

超時重傳

wKioL1ZzYgzAP2V5AAIBsnxhHlk136.jpg

    上圖給出了一個經過簡化的典型的TCP重傳過程示例。假設HostA向HostB發送的序列號爲1025的第二個段在途中丟失。HostB只對全部按序無錯接收到的序列號最高的給以確認,即HostB只以確認號1025向HostA確認第一個段已收到。

    HostA在收到這個確認時,並不能確定HostB沒有收到第二個段,因爲也許第二個段還沒有到達HostB,或者HostB發出的第二個確認可能被延遲了,因此,HostA不能立即重傳第二個段。只有在第二個段發出超過RTT(Round Trip Time 往返時間)而仍沒有收到確認時,HostA才認爲這個段已經丟失,並重傳這個段。

    HostB收到重傳的第二個段後,按序無誤收到的最後一個段的序列號爲3073,因此向HostA發送確認號爲4097,表示之前的數據均正確無誤地收到。

    TCP接收方並不通過“錯誤通知”告知發送方重傳。如果HostA向HostB發送的序列號爲1025的第二個段到達HostB,但被檢查出校驗錯誤,HostB也不會向HostA發送“錯誤通知”要求重傳。因此,RTA仍然需要等待RTT時間後再重傳這個段。

    必須考慮的另一種情況是,HostB回送的確認段也同樣可能在傳輸中丟失或出錯。此時對HostA來說並不需求額外的機制,因爲HostA面臨的現象與此前的例子是完全相同的——沒有收到確認。HostA仍然用同樣的超時重傳機制來處理即可。而如果HostB回送的確認只是被延遲,則HostA在重傳後就可能收到兩個確認,此時HostA只需要忽略多餘的確認即可。

    因此,RTT時間就成爲一個非常重要的參數。過大的RTT導致TCP重傳非常遲緩,可能會降低傳輸的速度;過小的RTT則會導致TCP頻繁重傳,同樣降低資源的使用效率。在實際實現中,TCP通過實時跟蹤發送的段與其相應確認之間的時間間隔來動態調整RTT的數值。

滑動窗口

wKioL1ZzZreCI0FBAAIFFcGHPfI610.jpg

    TCP使用大小可變的滑動窗口,並定義了窗口尺寸的通告機制,以增強流量控制的功能。這些機制爲TCP提供了在終端系統之間調整流量的動態方法。

    TCP滑動窗口尺寸的單位爲字節,起始於確認字段指明的值,這個值是接收端正期望一次性接收的字節。窗口尺寸是一個16位字段,因而窗口最大爲65535字節。在TCP的傳輸過程中,雙方通過交換窗口的大小來表達自己剩餘的緩衝卻空間,以及下一次能夠接受的最大的數據量,避免緩衝區的溢出。

    上圖仍然通過數據單向發送的簡化示例,介紹TCP如何通過滑動窗口實現流量控制。

    假定初始的發送窗口大小爲4096,每個段的數據爲1024字節,則HostA每次發送4個段給HostB。HostB正確接收到這些數據後,應該以確認號4097進行確認。然而同時,HostB由於緩存不足或處理能力有限,認爲這個發送速度過快,並期望將窗口降低一半。此時HostB在回送的確認中將窗口降低到2048,要求HostA每次只發送2048字節。HostA收到這個確認後,便依照要求降低了發送窗口尺寸,也就降低了發送速度。

    若接收方設備要求窗口大小爲0,表明接收方已經接收了全部數據,或者接收方應用程序沒有時間讀取數據,要求暫停發送。

    TCP運行在全雙工模式,所以發送者和接收者可能在相同的線路上同時發送數據,但發送的方向相反。這暗示着,每個終端系統對每個TCP鏈接包含兩個窗口,一個用於發送,一個用於接收。

    可變滑動窗口解決了端到端流量控制問題,但是無法干預網絡。如果中間節點,例如路由器被阻塞,則沒有任何機制可以通知TCP。如果特定的TCP實現對超時設定和再傳輸具有抵抗性,則會極度增加網絡的擁擠程度。







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章