《圖解TCP/IP》讀書筆記六:TCP與UDP

衣舞晨風發表於2018-02-13

這裡寫圖片描述

6.1 傳輸層的作用

    TCP提供可靠的通訊傳輸,而UDP則常被用於讓廣播和細節控制交給應用的通訊傳輸。

6.1.3 兩種傳輸層協議TCP和UDP

TCP

    TCP是面向連線的、可靠的流協議。流就是指不間斷的資料結構,你可以把它想象成排水管道中的水流。TCP為提供可靠性傳輸,實行“順序控制”或“重發控制”機制。此外還具備“流控制(流量控制)”、“擁塞控制”、提高網路利用率等眾多功能。

UDP

    UDP是不具有可靠性的資料包協議。細微的處理它會交給上層的應用去完成。UDP情況下,雖然可以確保傳送訊息的大小,卻不能保證訊息一定會到達。因此,應用有時會根據自己的需要進行重發處理。

6.1.4 TCP與UDP區分

    TCP用於在傳輸層有必要實現可靠性傳輸的情況。由於它是面向有連線並具備順序控制、重發控制等機制的。所以它可以為應用提供可靠傳輸。

    UDP主要用於那些對高速傳輸和實時性有較高要求的通訊或廣播通訊。舉一個IP電話進行通話的例子。如果使用TCP,資料在傳送途中如果丟失會被重發,但是這樣無法流暢地傳輸通話人的聲音,會導致無法進行正常交流。而採用UDP,它不會進行重發處理。從而也就不會有聲音大幅度延遲到達的問題。即使有部分資料丟失,也只是影響某一小部分的通話。此外,在多播與廣播通訊中也使用UDP而不是TCP。RIP、DHCP等基於廣播的協議也要依賴於UDP。

6.2 埠號

6.2.1 埠號定義

    資料鏈路和IP中的地址,分別指的是MAC地址和IP地址。前者用來識別同一鏈路中不同的計算機,後者用來識別TCP/IP網路中互連的主機和路由器。傳輸層也有類似概念,就是埠號。埠號用來識別同一臺計算機中進行通訊的不同應用程式。因此,它也被稱為程式地址。

6.2.3 通過IP地址、埠號、協議號進行通訊識別

    TCP/IP或UDP/IP通訊中通常採用5個資訊來識別一個通訊。它們是“源IP地址”、“目標IP地址”、“協議號”、“源埠號”、“目標埠號”。 只要其中某一項不同,則被認為是其他通訊。

6.2.5 埠號與協議

    埠號由其使用的傳輸層協議決定。因此,不同的傳輸協議可以使用相同的埠號。 例如,TCP與UDP使用同一個埠號,但使用目的各不相同。

    資料到達IP層後,會先檢查IP首部中的協議號,再傳給相應協議的模組。傳給TCP或UDP去做埠號處理。即使是同一個埠號,由於傳輸協議是各自獨立地進行處理,因此相互之間不會影響。

6.3 UDP

    UDP是User Datagram Protocol的縮寫,即使用者資料包協議。
    UDP不提供複雜控制機制,利用IP提供面向無連線的通訊服務。且它是將應用程式發來的資料在收到的那一刻,立即按照原樣傳送到網路上的一種機制。

    UDP面向無連線,可以隨時傳送資料。它常用於幾個方面:

  • 包總量較少的通訊(DNS、SNMP等)
  • 視訊、音訊等多媒體通訊(即時通訊)
  • 限定於LAN等特定網路中的應用通訊
  • 廣播通訊(廣播、多播)

6.4 TCP

    TCP是Transmission Control Protocol的縮寫,傳輸控制協議。
    TCP充分實現了資料傳輸時各種控制功能,可以進行丟包的重發控制,還可以對次序亂掉的分包進行順序控制。此外,TCP作為一種面向有連線的協議,只有在確認通訊對端存在時才會傳送資料,從而可以控制通訊流量的浪費。

連線

    連線是指各種裝置、線路,或網路中進行通訊的兩個應用程式為了相互傳遞訊息而專有的、虛擬的通訊線路,也叫做虛擬電路。

    一旦建立了連線,進行通訊的應用程式只是用這個虛擬的通訊線路傳送和接收資料,就可以保障資訊的傳輸。應用程式不用顧慮IP網路上可能發生的各種問題,依然可以轉發資料。TCP則負責控制連結的建立、斷開、保持等管理工作。

這裡寫圖片描述

6.4.1 TCP的特點及其目的

     為了通過資料包實現可靠性傳輸,需要考慮很多事情,例如資料的破壞、丟包、重複記憶分片順序混亂等問題。如不能解決這些問題,也就無從談起可靠傳輸。

    TCP通過檢驗和、序列號、確認應答、重發控制、連線管理以及視窗控制等機制實現可靠性傳輸。

6.4.2 通過序列號與確認應答提高可靠性

    在TCP中,當傳送端資料到達接受主機時,接收端主機會返回一個已收到的訊息的通知。這個訊息叫做確認應答(ACK Positive Acknowledgement)。

    TCP通過肯定的確認應答(ACK)實現可靠的資料傳輸。當傳送端將資料發出之後會等待對端的確認應答。如果有確認應答,說明資料已經成功到達對端。

    在一定時間內沒有等到確認應答,傳送端就可以認為資料已經丟失,並進行重發。由此,即使產生了丟包,仍然能夠保證資料能夠到達對端,實現可靠傳輸。

    未確認應答並不意味著資料一定丟失。也有可能是資料對方已經收到,只是返回的確認應答在途中丟失。

    為了防止出現隨意重發的情況,就需要引入一種機制,它能夠識別是否已經接收資料,又能判斷是否需要接收。

    這些確認應答處理、重發控制以及重複控制等功能都可以通過序列號實現。序列號是按照順序給傳送資料的每個位元組(8位位元組)都標上號碼的編號(序列號的初始值並非為0。而是在建立連線以後由隨機數生成。而後面的計算則是對每一位元組加一)。接收端查詢接收資料TCP首部中序列號和資料的長度,將自己下一步應該接收的序列號作為確認應答返送回去。這樣,通過序列號和確認應答號,TCP可以實現可靠傳輸。
這裡寫圖片描述

6.4.3 重發超時如何確定

    重發超時是指在重發資料之前,等待確認應答到來的那個特定時間間隔。如果超過了這個時間仍未收到確認應答,傳送端將進行資料重發。那麼這個重發超時的具體時間長度又是如何確定的呢?

    最理想的是,找到一個最小時間,它能保證“確認應答一定能在這個時間內返回”。然而這個時間長短隨著資料包途徑的網路環境的不同而有所變化。例如在高速的LAN中時間相對較短,而在長距離的通訊當中應該比LAN要長一些。即使是在同一個網路中,根據不同時段的網路堵塞程度時間的長短也會發生變化。TCP要求不論處在何種網路環境下都要提供高效能通訊,並且無論網路擁堵情況發生何種變化,都必須保持這一特性。為此,它在每次發包時都會計算往返時間及其偏差。將這個往返時間和偏差相加重發超時的時間,就是比這個總和要稍大一點的值。
這裡寫圖片描述
    在BSD的Unix以及Windows系統中,超時都以0.5秒為單位進行控制,因此重發超時都是0.5秒的整數倍。不過,由於最初的資料包還不知道往返時間,所以其重發超時一般設定為6秒左右。資料被重發之後若還是收不到確認應答,則進行再次傳送。此時,等待確認應答的時間將會以2倍、4倍的指數函式延長。此外,資料也不會被無限、反覆地重發。達到一定重發次數之後,如果仍沒有任何確認應答返回,就會判斷為網路或對端主機發生了異常,強制關閉連線。並且通知應用通訊異常強行終止。

6.4.4 連線管理

    TCP提供面向有連線的通訊傳輸。面向有連線是指在資料通訊開始之前先做好通訊兩端之間的準備工作。

    UDP是一種面向無連線的通訊協議,因此不檢查對端是否可以通訊,直接將UDP包發出去。TCP與此相反,它會在資料通訊之前,通過TCP首部傳送一個SYN包作為建立連線的請求等待確認應答(TCP中傳送第一個SYN包的一方叫客戶端,接收這個的一方叫服務端)。如果對端發來確認應答,則認為可以進行資料通訊。如果對端的確認應答未能到達,就不會進行資料通訊。此外,在通訊結束時會進行斷開連線的處理(FIN包)。

    可以使用TCP首部用於控制的欄位來管理TCP連線(也叫控制域)。一個連線的建立與斷開,正常過程至少需要來回傳送7個包才能完成。(建立一個TCP連線需要傳送3個包,這個過程也稱為3次握手)
這裡寫圖片描述

6.4.5 TCP以段為單位傳送資料

    在建立TCP連線的同時,也可以確定傳送資料包的單位,我們也可以稱其為“最大訊息長度”(MSS:Maximum Segment Size)。 最理想的情況是,最大訊息長度正好是IP中不會被分片處理的最大資料長度。

    TCP在傳輸大朗資料時,是以MSS的大小將資料進行分割傳送的。進行重發時也是以MSS為單位。

    MSS是在三次握手的時候,在兩端主機之間被計算得出。兩端的主機在發出建立連線的請求時,會在TCP首部中寫入MSS選項,告訴對方自己的介面能夠適應的MSS的大小(為附加MSS選項,TCP首部將不再是20位元組,而是4位元組的整數倍)。然後會在兩者之間選擇一個較小的值投入使用。
這裡寫圖片描述

6.4.6 利用視窗控制提高速度

    TCP以1個段為單位,每發一個段進行一次確認應答的處理,如下圖,這樣傳輸的缺點是,包的往返時間越長通訊效能就越低。
這裡寫圖片描述
    為解決這個問題,TCP引入了視窗這個概念。如下圖,確認應答不再是以每個分段,而是以更大的單位進行確認時,轉發時間將會被大幅度的縮短。就是說,傳送端主機,在傳送了一個段以後不必要一直等待確認應答,而是繼續傳送。

    視窗大小就是指無需等待確認應答而可以繼續傳送資料的最大值。 如下圖中,視窗大小為4個段。

    這個機制實現了使用大量的緩衝區(Buffer 在此處標識臨時儲存收發資料的場所。通常是在計算機記憶體中開闢的一部分空間),通過對多個段同時進行確認應答的功能。

    用滑動視窗方式並行處理:
這裡寫圖片描述

    下面的圖中傳送資料中高亮圈起的部分正是前面所提到的視窗。在這個視窗內的資料即便沒有收到確認應答也可以傳送出去。此外,從該視窗中能看到的資料因其某種資料已在傳輸中丟失,所以傳送端才能收到確認應答,這種情況也需要重發。為此,傳送端主機在等到確認應答返回之前,必須在緩衝區中保留這部分資料。

    在滑動視窗以外的部分包括尚未傳送的資料以及已經確認對端已收到的資料。當資料發出後若如期收到確認應答就可以不用再重發,此時資料皆可以從緩衝區清除。

    收到確認應答,將視窗滑動到確認應答中的序列號的位置。這樣可以順序地將多個段同時傳送提高通訊效能。這種機制也被稱為滑動視窗控制。

    滑動視窗方式:
這裡寫圖片描述

6.4.7 視窗控制與重發控制

    使用視窗控制中, 如果出現段丟失怎麼辦?

    首先考慮確認應答未能返回的情況。這種情況下,資料已經達到對端,是不需要進行重發的。然而,在沒有使用視窗控制的時候,沒有收到確認應答的資料會被重發。而使用了視窗控制,如下圖,某些確認應答即便丟失也無需重發。
這裡寫圖片描述
    其次,考慮一下某個報文段丟失的情況。如下圖,接收主機如果收到一個自己應該接收的序號以外的資料時,會針對當前位置收到資料返回確認應答(不過即使接收端主機收到的包序號並不連續,也不會將資料丟棄而是暫時儲存至緩衝區中)。

    當某一報文段丟失後,傳送端會一直收到序號為1001的確認應答,這個確認應答好像在提醒傳送端“我想接收的是從1001開始的資料”。因此,在視窗比較大,又出現報文段丟失的情況下,同一個序號的確認應答將會被重複不斷地返回。而傳送端主機如果連續3次收到同一個確認應答(之所以連續收到3次而不是兩次的理由是因為,即使資料段的序號被替換兩次也不會觸發重發機制)。就會將其所對應的資料進行重發。這種機制比之前提到的超時管理更加高效,因此也被稱作高速重發控制。

    高速重發控制(Fast Retransmission)
這裡寫圖片描述

6.4.8 流控制

    傳送端根據自己的實際情況傳送資料。但是,接收端可能收到的是一個毫無關係的資料包有可能會在處理其他問題上花費一些時間。因此在為這個資料包做其他處理時會耗費一些時間,甚至在高負荷情況下無法接收任何資料。如此一來,如果接收端將本應該接收的資料丟棄的話,就又會觸發重發機制,從而導致網路流量的浪費。

    為了防止這種現象發生,TCP提供一種機制可以讓傳送端根據接收端的實際接收能力控制傳送的資料量。這就是所謂的流控制。它的具體操作時,接收端主機向傳送端主機通知自己可以接收資料的大小,於是傳送端會傳送不超過這個限制的資料。該大小限度就被稱為視窗大小。

    TCP首部中,專門有一個欄位用來通知視窗大小。接收主機將自己的可以接收的緩衝區大小放入這個欄位通知給傳送端。這個值越大,說明網路的吞吐量越高。

    不過,接收端這個緩衝區一旦面臨資料溢位時,視窗大小的值也會隨之被設定為一個更小的值通知給傳送端,從而控制資料傳送量。就是說,傳送端主機會根據接收端主機的指示,對傳送資料的量進行控制。這也形成了一個完整的TCP流控制(流量控制)。

    根據視窗大小控制流量過程示例:
這裡寫圖片描述

    當接收端收到從3001號開始的資料段後其緩衝區即滿,不得不暫時停止接收資料。之後,在收到傳送視窗更新通知後通訊才得以繼續進行。如果這個視窗更新通知在傳輸途中丟失,可能會導致無法繼續通訊。為避免此類問題,傳送端主機會時不時傳送一個叫做視窗探測的資料段,此資料段僅含一個位元組以獲取最新的視窗大小資訊。

6.4.9 擁塞控制

    有了TCP視窗控制,收發主機之間即使不再以一個資料段為單位傳送確認應答,也能夠連續傳送大量資料包。然而,如果在通訊剛開始就傳送大量資料,也可能會引發其他問題。

    TCP為了防止該問題的出現,在通訊一開始就會通過一個叫做慢啟動的演算法得出的數值,對傳送資料量進行控制。

    首先,為了在傳送端調節所要傳送資料的量,定義了一個叫做“擁塞視窗”的概念。於是在慢啟動的時候,將這個擁塞視窗的大小設定為1個資料段(1MSS)傳送資料,之後每收到一次確認應答(ACK),擁塞視窗的值就加1.在傳送資料包時,將擁塞視窗的大小與接收端主機通知的視窗大小做比較,然後按照它們當中較小的那個值,傳送比其還要小的資料量。

這裡寫圖片描述

    如果重發採用超時機制,那麼擁塞視窗的初始值可以設定為1以後再進行慢啟動修正。有了上述這些機制,就可以有限的減少通訊開始時連續發包導致的網路擁堵,還可以避免網路擁塞情況的發生。

    不過,隨著包的每次往返,擁塞視窗也會以1、2、4等指數函式的增長,擁堵狀況激增甚至導致網路擁塞的發生。為了防止這些,引入了慢啟動閥值的概念。只要擁塞視窗的值超出這個閥值,在每收到一次確認應答時,只允許以下面這種比例方法擁塞視窗:
這裡寫圖片描述
TCP的視窗變化:
這裡寫圖片描述
    擁塞視窗越大,確認應答的數目也會增加,不過隨著每收到一個確認應答,其漲幅也會逐漸減少,甚至小過比一個資料段還要小的位元組數。所以,擁塞視窗的大小會呈直線上升的趨勢。

    TCP通訊開始時,並沒有設定相應的慢啟動閾值(與視窗的最大值相同),而是在超時重發時才會設定為當時擁塞視窗一半的大小。

    由重發確認應答而觸發的高速重發與超時重發機制的處理多少有些不同。因為前者要求至少3次的確認應答資料段到達對方主機後才會觸發,相比後者網路的擁堵要輕一些。

    而由重複確認應答進行高速重發控制時,慢啟動閾值的大小被設定為當時視窗大小的一半(嚴格來說,是設定為“實際已傳送但未收到確認應答的資料量”的一半)。然後將視窗的大小設定為該慢啟動閾值+3個資料段的大小。

    有了這樣一種控制,TCP的擁塞視窗如上圖所示發生變化。由於視窗的大小會直接影響資料被轉發的吞吐量,所以一般情況下,視窗越大,越會形成高吞吐量的通訊。

    當TCP通訊開始以後,網路吞吐量會逐漸上升,但是隨著網路擁堵的發生吞吐量也會急劇下降。於是會再次進入吞吐量慢慢上升的過程。因此所謂TCP的吞吐量的特點就好像是在逐步佔領網路頻寬的感覺。

6.6 UDP首部的格式

    下圖展示了UDP首部的格式。除去資料的部分正式UDP的首部。UDP首部由源埠號,目標埠號,包長和校驗和組成。
這裡寫圖片描述

源埠號(Source Port)

    表示傳送端埠號,欄位長16位。該欄位是可選項,有時可能不會設定源埠號。沒有源埠號的時候該欄位的值設定為0。可用於不需要返回的通訊中。

目標埠號(Destination Port)

    表示接收端埠,欄位長度16位。

包長度(Length)

    該欄位儲存了UDP首部的長度跟資料的長度之和。單位為位元組(8位位元組)。

校驗和(Checksum)

    校驗和是為了提供可靠的UDP首部和資料而設計。在計算校驗和時,附加在UDP偽首部與UDP資料包之前。通過在最後一位增加一個“0”將全長增加16倍。此時將UDP首部的校驗和欄位設定為“0”。然後以16位元為單位進行1的補碼和,並將所得到的1的補碼和寫入校驗和欄位。

這裡寫圖片描述

    接收主機在收到UDP資料包以後,從IP首部獲知IP地址資訊構造UDP偽首部,再進行校驗和計算。校驗和制度按的值是校驗和欄位以外餘下部分的1的補碼和。因此,包括校驗和欄位在內的所有資料之和結果為“16位全部為1”時,才會被認為所收到的資料時正確的。

    另外,UDP也可有可能不用校驗和。此時,校驗和欄位中填入0.這種情況下,由於不進行校驗和計算,協議處理的開銷(在處理實際資料之外,為了進行通訊控制的處理而不得不付出的必要的消耗部分)就會降低,從而提高資料轉發的速度。然而,如果UDP首部的埠號或是IP首部的IP地址遇到損壞,那麼可能會對其他通訊造成不好的影響。因此,在網際網路中比較推薦使用校驗和檢查。

校驗和計算中計算UDP偽首部的理由
TCP/IP中識別一個通訊的應用需要5大要素,它們分別是“源IP地址”、“目標IP地址”、“源埠”、“目標埠”、“協議號”。然而,在UDP的首部中只包含它們當中的兩項(源埠和目標埠),餘下的3項都包含在IP首部裡。
假定其他3項都被破壞?顯然,這極有可能會導致應該收包的應用收不到包,不該收到包的應用卻收到了包。
為了避免這類問題,有必要驗證一個通訊中必要的5項識別碼是否正確。為此,在校驗和的計算中就引入和偽首部的概念。
此外,IPv6中的IP首部沒有檢驗和欄位。TCP和UDP通過偽首部,得以對5項數字進行校驗,從而實現即使在IP首部並不可靠的情況下仍然能夠提供可靠的通訊傳輸。

6.7 TCP首部格式

這裡寫圖片描述

    TCP中沒有表示包長度和資料長度的欄位。可由IP層獲知TCP的包長,由TCO的包長可知資料的長度。

源埠號(Source Port)

    表示傳送端埠號,欄位長16位。

目標埠號(Destination Port)

    表示接收端埠號,欄位長度16位。

序列號(Sequence Number)

    欄位長32位。序列號(序號)是指傳送資料的位置,每傳送一次資料,就累加一次該資料位元組數的大小。

    序列號不會從0或1開始,而是建立連線時由計算機生成的隨機數作為其初始值,通過SYN包傳給接收端主機。然後再將每轉發過去的位元組數累加到初始值上表示資料的位置。此外,在建立連線和斷開連線時傳送的SYN包和FIN包雖然並不攜帶資料,但是也會作為一個位元組增加對應的序列號。

確認應答號(Acknowledgement Number)

    確認應答號欄位長度32位。是指下一次應該受到的資料的序列號。實際上,它是指已收到確認應答號減一為止的資料。傳送端收到這個確認應答以後可以認為在這個序號以前的資料都已經被正常接收。

資料偏移(Data Offset)

    該欄位表示TCP所傳輸的資料部分應該從TCP包的哪個位開始計算,當然也可以把它看做TCP首部的長度。該欄位長4位,單位為4位元組(即32位)。

保留(Reserved)

    該欄位主要是為了以後擴充套件時使用,其長度為4位。一般設定為0,但即使收到的包在該欄位不為0,此包也不會被丟棄。

控制位(Control Flag)

    欄位長為8位,每一位從左至右分別為CWR、ECE、URG、ACK、PSH、RST、SYN、FIN。這些控制標誌也叫作控制位。
這裡寫圖片描述

  • CWR(Congestion Window Reduced)
        CWR標誌與後面的ECE標誌都用於IP首部的ECN欄位。ECE標誌為1時,則通知對方已將擁塞視窗縮小。
  • ECE(ECN-Echo)
        ECE標誌表示ECN-Echo。置為1會通知通訊對方,從對方到這邊的網路有擁塞。在收到資料包的IP首部中ECN為1時將TCP首部中的ECE設定為1。
  • URG(Urgent Flag)
        該位為1時,確認應答的欄位變為有效。TCP規定除了最初建立連線時的SYN包之外該位必須設定為1。
  • PSH(Push Flag)
        該位為1時,表示需要將受到的資料立即傳給上層應用協議。PSH為0時,則不需要立即傳而是先進性快取。
  • RST(Reset Flag)
        該位為1時表示TCP連線中出現異常必須強制斷開連線。
  • SYN(Synchronize Flag)
        用於建立連線。SYN為1 表示希望建立連線,並在其序列號的欄位進行序列號初始值的設定。
  • FIN(Fin Flag)
        該位為1時,表示今後不會再有資料傳送,希望斷開連線。
    視窗大小(Window Size)

    該欄位長為16位。用於通知從相同TCP首部的確認應答號所指位置開始能夠接收的資料大小(8位位元組)。TCP不允許傳送超過此處所示大小的資料。不過,如果視窗為0,則表示可以傳送視窗探測,以瞭解最新的視窗大小。但這個資料必須是1個位元組。

校驗和(Checksum)

    TCP的校驗和與UDP相似,區別在於TCP的校驗和無法關閉。
    TCP和UDP一樣在計算校驗和的時候使用TCP偽首部。

    接收端在收到TCP資料段以後,從IP首部獲取IP地址資訊構造TCP偽首部,再進行校驗和計算。由於校驗和欄位裡儲存著除本欄位以外洽談部分的和的補碼值,一次如果計算校驗和欄位在內的所有資料的16位和以後,得出的結果是“16位全部為1”說明所收到資料是正確的。

緊急指標(Urgent Pointer)

選項(Options)

《圖解TCP/IP:第5版》下載地址:
http://download.csdn.net/download/xunzaosiyecao/10245906

個人微信公眾號:
這裡寫圖片描述

作者:jiankunking 出處:http://blog.csdn.net/jiankunking

相關文章