計算機網絡之TCP(三次握手、四次揮手等),UDP及DNS

目錄

一、TCP

數據包說明

TCP 對應的應用層協議

TCP 頭部

TCP 三次握手

三次握手的原因

TCP 四次揮手

四次揮手的原因

TCP數據傳輸

TCP 數據傳輸丟失怎麼辦(T即CP重傳,通過定時器實現)

TCP 滑動窗口

滑動窗口的原理

TCP 擁堵

解決方案

二、UDP

UDP在應用層協議中的應用

TCP 與 UDP 的區別

TCP數據流模式和UDP數據報模式

UDP 報文的格式

三、DNS

主機解析域名的順序

DNS 使用的協議


一、TCP

TCP(Transmission Control Protocol),傳輸控制協議,是一種面向連接的、可靠的、基於字節流的傳輸層通信協議。主要特點如下:

  • TCP 是面向連接的。

    就好像打電話一樣,通話前需要先撥號建立連接,通話結束後要掛機釋放連接

  • 每一條 TCP 連接只能有兩個端點,每一條TCP連接只能是點對點的(一對一)。

  • TCP 提供可靠交付的服務。通過TCP連接傳送的數據,無差錯、不丟失、不重複、並且按序到達。

  • TCP 提供全雙工通信。TCP 允許通信雙方的應用進程在任何時候都能發送數據。TCP 連接的兩端都設有發送緩存和接收緩存,用來臨時存放雙方通信的數據。

  • 面向字節流。

    TCP 中的“流”(Stream),指的是流入進程或從進程流出的字節序列。

    “面向字節流”的含義是:雖然應用程序和 TCP 的交互是一次一個數據塊(大小不等),但 TCP 把應用程序交下來的數據僅僅看成是一連串的無結構的字節流。

數據包說明

  1. 源端口號( 16 位):它(連同源主機 IP 地址)標識源主機的一個應用進程。

  2. 目的端口號( 16 位):它(連同目的主機 IP 地址)標識目的主機的一個應用進程。這兩個值加上 IP 報頭中的源主機 IP 地址和目的主機 IP 地址唯一確定一個 TCP 連接。

  3. 順序號 seq( 32 位):用來標識從 TCP 源端向 TCP 目的端發送的數據字節流,它表示在這個報文段中的第一個數據字節的順序號。如果將字節流看作在兩個應用程序間的單向流動,則 TCP 用順序號對每個字節進行計數。序號是 32bit 的無符號數,序號到達 2 的 32 次方 - 1 後 又從 0 開始。當建立一個新的連接時, SYN 標誌變 1 ,順序號字段包含由這個主機選擇的該 連接的初始順序號 ISN ( Initial Sequence Number )。

  4. 確認號 ack( 32 位):包含發送確認的一端所期望收到的下一個順序號。因此,確認序號應當是上次已成功收到數據字節順序號加 1 。只有 ACK 標誌爲 1 時確認序號字段纔有效。 TCP 爲 應用層提供全雙工服務,這意味數據能在兩個方向上獨立地進行傳輸。因此,連接的每一端必 須保持每個方向上的傳輸數據順序號。

  5. TCP 報頭長度( 4 位):給出報頭中 32bit 字的數目,它實際上指明數據從哪裏開始。需要這 個值是因爲任選字段的長度是可變的。這個字段佔 4bit ,因此 TCP 最多有 60 字節的首部。然 而,沒有任選字段,正常的長度是 20 字節。

  6. 保留位( 6 位):保留給將來使用,目前必須置爲 0 。

  7. 控制位( control flags , 6 位):在 TCP 報頭中有 6 個標誌比特,它們中的多個可同時被設置爲 1 。依次爲:

  8. URG :爲 1 表示緊急指針有效,爲 0 則忽略緊急指針值。

  9. ACK :爲 1 表示確認號有效,爲 0 表示報文中不包含確認信息,忽略確認號字段。

  10. PSH :爲 1 表示是帶有 PUSH 標誌的數據,指示接收方應該儘快將這個報文段交給應用層而不用等待緩衝區裝滿。

  11. RST :用於復位由於主機崩潰或其他原因而出現錯誤的連接。它還可以用於拒絕非法的報文段和拒絕連接請求。一般情況下,如果收到一個 RST 爲 1 的報文,那麼一定發生了某些問題。

  12. SYN :同步序號,爲 1 表示連接請求,用於建立連接和使順序號同步( synchronize )。

  13. FIN :用於釋放連接,爲 1 表示發送方已經沒有數據發送了,即關閉本方數據流。

  14. 窗口大小( 16 位):數據字節數,表示從確認號開始,本報文的源方可以接收的字節數,即源 方接收窗口大小。窗口大小是一個 16bit 字段,因而窗口大小最大爲 65535 字節。

  15. 校驗和( 16 位):此校驗和是對整個的 TCP 報文段,包括 TCP 頭部和 TCP 數據,以 16 位字 進行計算所得。這是一個強制性的字段,一定是由發送端計算和存儲,並由接收端進行驗證。

  16. 緊急指針(16位):只有當URG標誌置1時緊急指針纔有效。TCP的緊急方式是發送端向另 一端發送緊急數據的一種方式。

  17. 選項:最常見的可選字段是最長報文大小,又稱爲MSS(MaximumSegmentSize)。每個連 接方通常都在通信的第一個報文段(爲建立連接而設置 SYN 標誌的那個段)中指明這個選項, 它指明本端所能接收的最大長度的報文段。選項長度不一定是 32 位字的整數倍,所以要加填充 位,使得報頭長度成爲整字數。

  18. 數據: TCP 報文段中的數據部分是可選的。在一個連接建立和一個連接終止時,雙方交換的報 文段僅有 TCP 首部。如果一方沒有數據要發送,也使用沒有任何數據的首部來確認收到的數 據。在處理超時的許多情況中,也會發送不帶任何數據的報文段。

TCP 對應的應用層協議

  • FTP :定義了文件傳輸協議,使用 21 端口。常說某某計算機開了 FTP 服務便是啓動了文件傳輸服務。下載文件,上傳主頁,都要用到 FTP 服務。

  • Telnet :它是一種用於遠程登陸的端口,用戶可以以自己的身份遠程連接到計算機上,通過這種端口可以提供一種基於 DOS 模式下的通信服務。如以前的 BBS 是純字符界面的,支持 BBS 的服務器將 23 端口打開,對外提供服務。

  • 郵箱

    • SMTP :定義了簡單郵件傳送協議,現在很多郵件服務器都用的是這個協議,用於發送郵件。如常見的免費郵件服務中用的就是這個郵件服務端口,所以在電子郵件設置-中常看到有這麼 SMTP 端口設置這個欄,服務器開放的是 25 號端口。

    • POP3 :它是和 SMTP 對應,POP3 用於接收郵件。通常情況下,POP3 協議所用的是 110 端口。也是說,只要你有相應的使用 POP3 協議的程序(例如 Foxmail 或 Outlook),就可以不以 Web 方式登陸進郵箱界面,直接用郵件程序就可以收到郵件(如是 163 郵箱就沒有必要先進入網易網站,再進入自己的郵箱來收信)。

  • HTTP :從 Web 服務器傳輸超文本到本地瀏覽器的傳送協議。

TCP 頭部

參照下面:

TCP 三次握手

三次握手,簡單來說,就是:

TCP 三次握手的漫畫

  • 發送方:我要和你建立鏈接?

  • 接收方:你真的要和我建立鏈接麼?

  • 發送方:我真的要和你建立鏈接,成功。

詳細來說,步驟如下:

ACK :爲 1 表示確認號有效,爲 0 表示報文中不包含確認信息,忽略確認號字段。

SYN :同步序號,爲 1 表示連接請求,用於建立連接和使順序號同步( synchronize )。

順序號 seq( 32 位):用來標識從 TCP 源端向 TCP 目的端發送的數據字節流,它表示在這個報文段中的第一個數據字節的順序號。如果將字節流看作在兩個應用程序間的單向流動,則 TCP 用順序號對每個字節進行計數。序號是 32bit 的無符號數,序號到達 2 的 32 次方 - 1 後 又從 0 開始。當建立一個新的連接時, SYN 標誌變 1 ,順序號字段包含由這個主機選擇的該 連接的初始順序號 ISN ( Initial Sequence Number )。

確認號 ack( 32 位):包含發送確認的一端所期望收到的下一個順序號。因此,確認序號應當是上次已成功收到數據字節順序號加 1 。只有 ACK 標誌爲 1 時確認序號字段纔有效。 TCP 爲 應用層提供全雙工服務,這意味數據能在兩個方向上獨立地進行傳輸。因此,連接的每一端必 須保持每個方向上的傳輸數據順序號。

  • 第一次握手:Client 將標誌位 SYN=1 ,隨機產生一個值 seq=J ,並將該數據包發送給 Server 。此時,Client 進入SYN_SENT 狀態,等待 Server 確認。

  • 第二次握手:Server 收到數據包後由標誌位 SYN=1 知道Client請求建立連接,Server 將標誌位 SYNACK 都置爲 1 ,ack=J+1,隨機產生一個值 seq=K ,並將該數據包發送給 Client 以確認連接請求,Server 進入 SYN_RCVD 狀態。此時,Server 進入 SYC_RCVD 狀態。

  • 第三次握手:Client 收到確認後,檢查ack是否爲J+1,ACK是否爲 1 。

    • 如果正確,則將標誌位 ACK 置爲 1 ,ack=K+1 ,並將該數據包發送給 Server 。此時,Client 進入 ESTABLISHED 狀態。

    • Server 檢查 ack 是否爲 K+1ACK 是否爲 1 ,如果正確則連接建立成功。此時 Server 進入 ESTABLISHED 狀態,完成三次握手,隨後 Client 與 Server 之間可以開始傳輸數據了。

  • 仔細看來,Client 會發起兩次數據包,分別是 SYNCACK ;Server 會發起一次數據包,包含 SYNCACK 。也就是說,三次握手的過程中,Client 和 Server 互相做了一次 SYNCACK

三次握手的原因

第三次握手是爲了防止失效的連接請求到達服務器,讓服務器錯誤打開連接。

客戶端發送的連接請求如果在網絡中滯留,那麼就會隔很長一段時間才能收到服務器端發回的連接確認。客戶端等待一個超時重傳時間之後,就會重新請求連接。但是這個滯留的連接請求最後還是會到達服務器,如果不進行三次握手,那麼服務器就會打開兩個連接。如果有第三次握手,客戶端會忽略服務器之後發送的對滯留連接請求的連接確認,不進行第三次握手,因此就不會再次打開連接。

爲了防止已失效的連接請求報文突然又傳送到了服務端,因而產生錯誤,TCP 連接需要三次握手

客戶端發出的連接請求報文並未丟失,而是在某個網絡節點長時間滯留了,以致延誤到鏈接釋放以後的某個時間纔到達 Server 。

  • 若不採用“三次握手”,那麼只要 Server 發出確認數據包,新的連接就建立了。由於 Client 此時並未發出建立連接的請求,所以其不會理睬 Server 的確認,也不與 Server 通信;而這時 Server 一直在等待 Client 的請求,這樣 Server 就白白浪費了一定的資源。

  • 若採用“三次握手”,在這種情況下,由於 Server 端沒有收到來自客戶端的確認,則就會知道 Client 並沒有要求建立請求,就不會建立連接。

《通俗大白話來理解 TCP 協議的三次握手和四次揮手》 中,搜 “爲什麼要三次握手” 關鍵字,也有非常好的解答。

  • 這就很明白了,防止了服務器端的一直等待而浪費資源

TCP 四次揮手

四次揮手,簡單來說,就是:

  • 發送方:我要和你斷開連接!

  • 接收方:好的,斷吧。

  • 接收方:我也要和你斷開連接!

  • 發送方:好的,斷吧。

詳細來說,步驟如下:

如下使用 Client 和 Server 的方式,僅僅是爲了方便,也是可以從 Server 向 Client 發起。

  • 第一次揮手:Client 發送一個 FIN=M ,用來關閉 Client 到 Server 的數據傳送。此時,Client 進入FIN_WAIT_1 狀態。

  • 第二次揮手,Server 收到 FIN 後,發送一個 ACK 給 Client ,確認序號ack爲 M+1(與 SYN 相同,一個 FIN 佔用一個序號)。此時,Server 進入 CLOSE_WAIT 狀態。注意,TCP 鏈接處於半關閉狀態,即客戶端已經沒有要發送的數據了,但服務端若發送數據,則客戶端仍要接收。

  • 第三次揮手,Server 發送一個 FIN=N ,用來關閉 Server 到 Client 的數據傳送。此時 Server 進入 LAST_ACK 狀態。

  • 第四次揮手,Client 收到 FIN 後,此時 Client 進入 TIME_WAIT 狀態(此時 TCP 連接還沒有釋放掉,然後經過時間等待計時器設置的 2MSL 後,A 才進入到close 狀態)。接着,Client 發送一個 ACK 給 Server ,確認序號爲 N+1 。Server 接收到後,此時 Server 進入 CLOSED 狀態,完成四次揮手。

    去向ACK消息最大存活時間(MSL) + 來向FIN消息的最大存活時間(MSL)。恰恰就是2MSL( Maximum Segment Life)。

    等待2MSL時間,客戶端就可以放心地釋放TCP佔用的資源、端口號,此時可以使用該端口號連接任何服務器。

四次揮手的原因

TCP 協議是一種面向連接的、可靠的、基於字節流的運輸層通信協議。TCP 是全雙工模式,這就意味着:

  • 當主機 1 發出 FIN 報文段時,只是表示主機 1 已經沒有數據要發送了,主機 1 告訴主機 2 ,它的數據已經全部發送完畢了;但是,這個時候主機 1 還是可以接受來自主機 2 的數據;當主機 2 返回 ACK 報文段時,表示它已經知道主機 1 沒有數據發送了,但是主機 2 還是可以發送數據到主機 1 的。

  • 當主機 2 也發送了 FIN 報文段時,這個時候就表示主機 2 也沒有數據要發送了,就會告訴主機 1 ,我也沒有數據要發送了,之後彼此就會愉快的中斷這次 TCP 連接。

TCP 建立連接要進行三次握手,而斷開連接要進行四次。這是由於 TCP 的半關閉造成的。因爲 TCP 連接是全雙工的(即數據可在兩個方向上同時傳遞)所以進行關閉時每個方向上都要單獨進行關閉。這個單方向的關閉就叫半關閉。當一方完成它的數據發送任務,就發送一個 FIN 來向另一方通告將要終止這個方向的連接。

如果要正確的理解四次的原理,就需要了解四次揮手過程中的狀態變化。

主動方=發送方;被動方=接收方。

狀態前面的(主動方)(被動方),表示該狀態屬於誰。

  • (主動方)FIN_WAIT_1 :其實 FIN_WAIT_1 和 FIN_WAIT_2 狀態的真正含義都是表示等待對方的FIN報文。而這兩種狀態的區別是:

    • FIN_WAIT_1 狀態實際上是當 Socket 在 ESTABLISHED 狀態時,它想主動關閉連接,向對方發送了 FIN 報文,此時該 Socket 即進入到 FIN_WAIT_1 狀態。

    • 當對方迴應 ACK 報文後,則進入到 FIN_WAIT_2 狀態,當然在實際的正常情況下,無論對方何種情況下,都應該馬上回應ACK 報文。所以, FIN_WAIT_1 狀態一般是比較難見到的,而 FIN_WAIT_2 狀態還有時常常可以用 netstat 看到。

  • (主動方)FIN_WAIT_2 :上面已經詳細解釋了這種狀態,實際上 FIN_WAIT_2 狀態下的 Socket,表示半連接,也即有一方要求 close 連接,但另外還告訴對方,我暫時還有點數據需要傳送給你(ACK 信息),稍後再關閉連接。

  • (被動方)CLOSE_WAIT :這種狀態的含義其實是表示在等待關閉。即當對方 close 一個 Socket 後發送 FIN 報文給自己,你係統毫無疑問地會迴應一個 ACK 報文給對方,此時則進入到 CLOSE_WAIT 狀態。接下來呢,實際上你真正需要考慮的事情是察看你是否還有數據發送給對方,如果沒有的話,那麼你也就可以 close 這個 Socket ,發送 FIN 報文給對方,也即關閉連接。所以你在 CLOSE_WAIT 狀態下,需要完成的事情是等待你去關閉連接。

  • (被動方)LAST_ACK :這個狀態還是比較容易好理解的,它是被動關閉一方在發送 FIN 報文後,最後等待對方的 ACK 報文。當收到 ACK 報文後,也即可以進入到 CLOSED 可用狀態了。

  • (主動方)TIME_WAIT :表示收到了對方的 FIN 報文,併發送出了 ACK 報文,就等 2MSL 後即可回到 CLOSED 可用狀態了。如果 FIN_WAIT_1 狀態下,收到了對方同時帶 FIN 標誌和 ACK 標誌的報文時,可以直接進入到 TIME_WAIT 狀態,而無須經過 FIN_WAIT_2 狀態。

    2MSL的作用

    如果不等,釋放的端口可能會重連剛斷開的服務器端口,這樣依然存活在網絡裏的老的 TCP 報文可能與新 TCP 連接報文衝突,造成數據衝突,爲避免此種情況,需要耐心等待網絡老的 TCP 連接的活躍報文全部死翹翹,2MSL 時間可以滿足這個需求(儘管非常保守)!

    更多,可以看看知乎 《爲什麼 TCP 4 次揮手時等待爲 2MSL?》 的討論。

  • CLOSED :表示連接中斷。

另外,關於 TIME_WAIT 和 CLOSE_WAIT 狀態的區別《TIME_WAIT 和 CLOSE_WAIT 狀態區別》

TCP數據傳輸

建立連接後,兩臺主機就可以相互傳輸數據了。如下圖所示:

  • 上圖給出了主機 A 分 2 次(分 2 個數據包)向主機 B 傳遞 200 字節的過程。

  • 首先,主機 A 通過 1 個數據包發送 100 個字節的數據,數據包的Seq號設置爲 1200 。主機 B 爲了確認這一點,向主機 A 發送ACK包,並將Ack號設置爲 1301 。

    • 爲了保證數據準確到達,目標機器在收到數據包(包括 SYN 包、FIN 包、普通數據包等)包後必須立即回傳ACK包,這樣發送方纔能確認數據傳輸成功。

    • 此時Ack號爲 1301 而不是 1201,原因在於Ack號的增量爲傳輸的數據字節數。假設每次Ack號不加傳輸的字節數,這樣雖然可以確認數據包的傳輸,但無法明確 100 字節全部正確傳遞還是丟失了一部分,比如只傳遞了 80 字節。因此按如下的公式確認Ack號:Ack =Seq號 + 傳遞的字節數 + 1 。

      • 與三次握手協議相同,最後加 1 是爲了告訴對方要傳遞的 Seq 號。

OK,讓我們重新來看下 TCP 的整個過程。如下圖所示:

TCP 數據傳輸丟失怎麼辦(T即CP重傳,通過定時器實現)

因爲各種原因,TCP 數據包可能存在丟失的情況,TCP 會進行數據重傳。如下圖所示:

  • 上圖表示通過 Seq 1301 數據包向主機 B 傳遞 100 字節的數據,但中間發生了錯誤,主機 B 未收到。經過一段時間後,主機 A 仍未收到對於 Seq 1301 的 ACK 確認,因此嘗試重傳數據。爲了完成數據包的重傳,TCP 套接字每次發送數據包時都會啓動定時器,如果在一定時間內沒有收到目標機器傳回的 ACK 包,那麼定時器超時,數據包會重傳。上圖演示的是數據包丟失的情況,也會有 ACK 包丟失的情況,一樣會重傳。

  • 重傳超時時間(RTO,Retransmission Time Out)

    這個值太大了會導致不必要的等待,太小會導致不必要的重傳,理論上最好是網絡 RTT 時間,但又受制於網絡距離與瞬態時延變化,所以實際上使用自適應的動態算法(例如 Jacobson 算法和 Karn 算法等)來確定超時時間。

    往返時間(RTT,Round-Trip Time)表示從發送端發送數據開始,到發送端收到來自接收端的 ACK 確認包(接收端收到數據後便立即確認),總共經歷的時延。

  • 重傳次數

    TCP 數據包重傳次數,根據系統設置的不同而有所區別。有些系統,一個數據包只會被重傳 3 次,如果重傳 3 次後還未收到該數據包的 ACK 確認,就不再嘗試重傳。但有些要求很高的業務系統,會不斷地重傳丟失的數據包,以盡最大可能保證業務數據的正常交互。

    最後需要說明的是,發送端只有在收到對方的 ACK 確認包後,纔會清空輸出緩衝區中的數據。

ps:TCP 數據傳輸的過程,和 MQ Broker 投遞消息給 Consumer 是一樣的,只有在 Consumer Ack 確認消息已經消費,該消息纔不會再被投遞給 Consumer 。

另外,也推薦閱讀 《網絡基本功(九):細說TCP重傳》

TCP 滑動窗口

將 TCP 與 UDP 這樣的簡單傳輸協議區分開來的是,它傳輸數據的質量。TCP 對於發送數據進行跟蹤,這種數據管理需要協議有以下兩大關鍵功能:

  • 可靠性:保證數據確實到達目的地。如果未到達,能夠發現並重傳。

  • 數據流控:管理數據的發送速率,以使接收設備不致於過載。

要完成這些任務,整個協議操作是圍繞滑動窗口 + 確認機制來進行的。因此,理解了滑動窗口,也就是理解了 TCP 。

       滑動窗口協議,是傳輸層進行流控的一種措施接收方通過通告發送方自己的窗口大小,從而控制發送方的發送速度,從而達到防止發送方發送速度過快而導致自己被淹沒的目的。

TCP 的滑動窗口解決了端到端的流量控制問題,允許接受方對傳輸進行限制,直到它擁有足夠的緩衝空間來容納更多的數據。

TCP將獨立的字節數據當作流來處理。一次發送一個字節並接收一次確認顯然是不可行的。即使重疊傳輸(即不等待確認就發送下一個數據),速度也還是會非常緩慢。

TCP消息確認機制如上圖所示,首先,每一條消息都有一個識別編號,每一條消息都能夠被獨立地確認,因此同一時刻可以發送多條信息。設備B定期發送給A一條發送限制參數,制約設備A一次能發送的消息最大數量。設備B可以對該參數進行調整,以控制設備A的數據流。

爲了提高速度,TCP並沒有按照字節單個發送而是將數據流劃分爲片段。片段內所有字節都是一起發送和接收的,因此也是一起確認的。確認機制沒有采用message ID字段,而是使用的片段內最後一個字節的sequence number。因此一次可以處理不同的字節數,這一數量即爲片段內的sequence number。

TCP數據流的概念劃分類別

假設A和B之間新建立了一條TCP連接。設備A需要傳送一長串數據流,但設備B無法一次全部接收,所以它限制設備A每次發送分段指定數量的字節數,直到分段中已發送的字節數得到確認。之後,設備A可以繼續發送更多字節。每一個設備都對發送,接收及確認數據進行追蹤。

如果我們在任一時間點對於這一過程做一個“快照”,那麼我們可以將TCP buffer中的數據分爲以下四類,並把它們看作一個時間軸:

1. 已發送已確認 數據流中最早的字節已經發送並得到確認。這些數據是站在發送設備的角度來看的。如下圖所示,31個字節已經發送並確認。

2. 已發送但尚未確認 已發送但尚未得到確認的字節。發送方在確認之前,不認爲這些數據已經被處理。下圖所示14字節爲第2類。

3. 未發送而接收方已Ready 設備尚未將數據發出,但接收方根據最近一次關於發送方一次要發送多少字節確認自己有足夠空間。發送方會立即嘗試發送。如圖,第3類有6字節。

4. 未發送而接收方Not Ready 由於接收方not ready,還不允許將這部分數據發出。

接收方採用類似的機制來區分已接收並已確認,尚未接受但準備好接收,以及尚未接收並尚未準備好接收的數據。實際上,收發雙方各自維護一套獨立的變量,來監控發送和接收的數據流落在哪一類。

滑動窗口的原理

TCP是一個可靠的傳輸協議,所以需要對數據進行確認。TCP協議裏窗口機制有2種:一種是固定的窗口大小;一種是滑動的窗口。這個窗口大小就是我們一次傳輸幾個數據,對所有數據幀按順序賦予編號,發送方在發送過程中始終保持着一個發送窗口,只有落在發送窗口內的幀才允許被髮送;同時接收方也維持着一個接收窗口,只有落在接收窗口內的幀才允許接收。這樣通過調整發送方窗口和接收方窗口的大小可以實現流量控制。

TCP滑動窗口技術通過動態改變窗口大小來調節兩臺主機間數據傳輸。每個TCP/IP主機支持全雙工數據傳輸,因此TCP有兩個滑動窗口:一個用於接收數據,另一個用於發送數據。TCP使用肯定確認技術,其確認號指的是下一個所期待的字節。

假定發送方設備以每一次三個數據包的方式發送數據,也就是說,窗口大小爲3。發送方發送序列號爲1、2、3的三個數據包,接收方設備成功接收數據包,用序列號4(窗口大小+1)確認。發送方設備收到確認,繼續以窗口大小3發送數據。當接收方設備要求降低或者增大網絡流量時,可以對窗口大小進行減小或者增加,本例降低窗口大小爲2,每一次發送兩個數據包。當接收方設備要求窗口大小爲0,表明接收方已經接收了全部數據,或者接收方應用程序沒有時間讀取數據,要求暫停發送。發送方接收到攜帶窗口號爲0的確認,停止這一方向的數據傳輸。

先看下面一張圖來分析一下固定窗口大小有什麼問題。

注意:這裏應該是ack而不是ACK,ACK是控制位中的一位,爲 1 表示確認號有效,爲 0 表示報文中不包含確認信息,忽略確認號字段。

這裏我們可以看到假設窗口的大小是1,也是就每次只能發送一個數據只有接受方對這個數據進行確認了以後才能發送第2個數據。我們可以看到發送方每發送一個數據,接受方就要給發送方一個ACK對這個數據進行確認。只有接受到了這個確認數據以後發送方纔能傳輸下個數據。 這樣我們考慮一下如果說窗口過小,那麼當傳輸比較大的數據的時候需要不停的對數據進行確認,這個時候就會造成很大的延遲。如果說窗口的大小定義的過大。我們假設發送方一次發送100個數據。但是接收方只能處理50個數據。這樣每次都會只對這50個數據進行確認。發送方下一次還是發送100個數據,但是接受方還是隻能處理50個數據。這樣就避免了不必要的數據來擁塞我們的鏈路。所以我們就引入了滑動窗口機制,窗口的大小並不是固定的而是根據我們之間的鏈路的帶寬的大小,這個時候鏈路是否擁護塞。接受方是否能處理這麼多數據了。

結合下圖看看滑動窗口是如何工作的

首先是第一次發送數據這個時候的窗口大小是根據鏈路帶寬的大小來決定的。我們假設這個時候窗口的大小是3。這個時候接受方收到數據以後會對數據進行確認告訴發送方我下次希望手到的是數據是多少。這裏我們看到接收方發送的ACK=3(這是發送方發送序列2的回答確認,下一次接收方期望接收到的是3序列信號)。這個時候發送方收到這個數據以後就知道我第一次發送的3個數據對方只收到了2個。就知道第3個數據對方沒有收到。下次在發送的時候就從第3個數據開始發。這個時候窗口大小就變成了2

這個時候發送方發送2個數據。

看到接收方發送的ACK是5就表示他下一次希望收到的數據是5,發送方就知道我剛纔發送的2個數據對方收了這個時候開始發送第5個數據。

這就是滑動窗口的工作機制,當鏈路變好了或者變差了這個窗口還會發生變化,並不是第一次協商好了以後就永遠不變了。

滑動窗口協議,是TCP使用的一種流量控制方法。該協議允許發送方在停止並等待確認前可以連續發送多個分組。由於發送方不必每發一個分組就停下來等待確認,因此該協議可以加速數據的傳輸。 只有在接收窗口向前滑動時(與此同時也發送了確認),發送窗口才有可能向前滑動。 收發兩端的窗口按照以上規律不斷地向前滑動,因此這種協議又稱爲滑動窗口協議。當發送窗口和接收窗口的大小都等於1時,就是停止等待協議。

參照下面:

TCP 擁堵

計算機網絡中的帶寬、交換結點中的緩存及處理機等都是網絡的資源。在某段時間,若對網絡中某一資源的需求超過了該資源所能提供的可用部分,網絡的性能就會變壞,這種情況就叫做擁塞

解決方案

通過擁塞控制來解決。擁堵控制,就是防止過多的數據注入網絡中,這樣可以使網絡中的路由器或鏈路不致過載。注意,擁塞控制和流量控制不同,前者是一個全局性的過程,而後者指點對點通信量的控制。

擁塞控制的方法主要有以下四種:

  • 1、慢開始。

  • 2、擁塞避免。

  • 3、快重傳。

  • 4、快恢復。

1)慢開始

不要一開始就發送大量的數據,先探測一下網絡的擁塞程度,也就是說由小到大逐漸增加擁塞窗口的大小。

2)擁塞避免

擁塞避免算法,讓擁塞窗口緩慢增長,即每經過一個往返時間 RTT 就把發送方的擁塞窗口 cwnd 加 1 ,而不是加倍,這樣擁塞窗口按線性規律緩慢增長。

3)快重傳

快重傳,要求接收方在收到一個失序的報文段後就立即發出重複確認(爲的是使發送方及早知道有報文段沒有到達對方),而不要等到自己發送數據時捎帶確認。

快重傳算法規定,發送方只要一連收到三個重複確認,就應當立即重傳對方尚未收到的報文段,而不必繼續等待設置的重傳計時器時間到期。

4)快恢復

快重傳配合使用的還有快恢復算法,當發送方連續收到三個重複確認時,就執行“乘法減小”算法,把 ssthresh 門限減半。

  • 但是接下去並不執行慢開始算法:因爲如果網絡出現擁塞的話就不會收到好幾個重複的確認,所以發送方現在認爲網絡可能沒有出現擁塞。

  • 所以此時不執行慢開始算法,而是將 cwnd 設置爲 ssthresh 的大小,然後執行擁塞避免算法。

二、UDP

UDP(User Data Protocol,用戶數據報協議),是與 TCP 相對應的協議。它是面向非連接的協議,它不與對方建立連接,而是直接就把數據包發送過去。

主要特點如下:

  • UDP 是無連接的。

  • UDP 使用盡最大努力交付,即不保證可靠交付,因此主機不需要維持複雜的鏈接狀態(這裏面有許多參數)。

  • UDP 是面向報文的。

  • UDP 沒有擁塞控制,因此網絡出現擁塞不會使源主機的發送速率降低。

    對實時應用很有用,如 直播,實時視頻會議等

  • UDP 支持一對一、一對多、多對一和多對多的交互通信。

  • UDP 的首部開銷小,只有 8 個字節,比 TCP 的 20 個字節的首部要短。

UDP在應用層協議中的應用

  • DNS :用於域名解析服務,將域名地址轉換爲 IP 地址。DNS 用的是 53 號端口。

  • SNMP :簡單網絡管理協議,使用 161 號端口,是用來管理網絡設備的。由於網絡設備很多,無連接的服務就體現出其優勢。

  • TFTP(Trivial File Transfer Protocol):簡單文件傳輸協議,該協議在熟知端口 69 上使用 UDP 服務。

TCP 與 UDP 的區別

TCP(Transmission Control Protocol)和 UDP(User Datagram Protocol) 協議屬於傳輸層協議,它們之間的區別包括:

  • TCP 是面向連接的;UDP 是無連接的。

  • TCP 是可靠的;UDP 是不可靠的。

  • TCP 只支持點對點通信;UDP 支持一對一、一對多、多對一、多對多的通信模式。

  • TCP 是面向字節流的;UDP 是面向報文的。

  • TCP 有擁塞控制機制;UDP 沒有擁塞控制,適合媒體通信。

  • TCP 首部開銷(20 個字節),比 UDP 的首部開銷(8 個字節)要大。

TCP數據流模式和UDP數據報模式

所謂的“流模式”,是指TCP 發送端發送幾次數據和接收端接收幾次數據是沒有必然聯繫的

  • 比如你通過 TCP 連接給另一端發送數據,你只調用了一次 write ,發送了 100 個字節,但是對方可以分 10 次收完,每次 10 個字節;你也可以調用 10 次 write ,每次 10 個字節,但是對方可以一次就收完。

  • 原因:這是因爲 TCP 是面向連接的,一個 Socket 中收到的數據都是由同一臺主機發出,且有序地到達,所以每次讀取多少數據都可以。

所謂的“數據報模式”,是指 UDP 發送端調用了幾次 write ,接收端必須用相同次數的 read 讀完

  • UDP 是基於報文的,在接收的時候,每次最多隻能讀取一個報文,報文和報文是不會合並的,如果緩衝區小於報文長度,則多出的部分會被丟棄。

  • 原因:這是因爲 UDP 是無連接的,只要知道接收端的 IP 和端口,任何主機都可以向接收端發送數據。這時候,如果一次能讀取超過一個報文的數據,則會亂套。

參照:TCP流模式和UDP數據報模式的區別

UDP 報文的格式

  • 16 位 * 4 = 64 位 = 8 字節。

三、DNS

  • 域名解析,www.xxx.com 轉換成 IP ,能夠使用戶更方便的訪問互聯網,而不用去記住能夠被機器直接讀取的 IP 數串。

  • DNS 協議運行在 UDP 協議之上,使用端口號 53 。

主機解析域名的順序

  1. 瀏覽器緩存

  2. 找本機的 hosts 文件

  3. 路由緩存

  4. 找 DNS 服務器(本地域名、頂級域名、根域名)

DNS 使用的協議

參見 《DNS使用的是 TCP 協議還是 UDP 協議》 文章。

既使用 TCP 又使用 UDP 。

  • 區域傳送時使用 TCP 協議。

    • 輔域名服務器會定時(一般是 3 小時)向主域名服務器進行查詢以便了解數據是否有變動。如有變動,則會執行一次區域傳送,進行數據同步。區域傳送將使用 TCP 而不是 UDP ,因爲數據同步傳送的數據量比一個請求和應答的數據量要多得多。

    • TCP 是一種可靠的連接,保證了數據的準確性。

  • 域名解析時使用 UDP 協議。

    • 客戶端向 DNS 服務器查詢域名,一般返回的內容都不超過 512 字節,用 UDP 傳輸即可。

      UDP 報文的最大長度爲 512 字節。

    • 不用經過 TCP 三次握手,這樣 DNS 服務器負載更低,響應更快。雖然從理論上說,客戶端也可以指定向 DNS 服務器查詢的時候使用 TCP ,但事實上,很多 DNS 服務器進行配置的時候,僅支持 UDP 查詢包。

參照:

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