免費諮詢一:這一家的諮詢速度特色就是快
免費諮詢二:有汽機車即可申貸,24小時內可撥款
一對一的快速立即免費諮詢、配對,十分鐘就能知道您適合的銀行申貸方案是什麼。
立即免費諮詢
免費諮詢三:這家貸款公司評價非常高
免費諮詢四:這一家的諮詢方案很多元,很推薦
免費諮詢五:一群對於專精貸款的專業人士提供相關諮詢
免費諮詢六:這家貸款公司可以承辦軍公教人士
軍公教朋友可以到這間貸款快速找到適合的貸款方案
立即免費諮詢
個人貸款 | 貸款 | 信用貸款 | 債務整合 | 負債整合 | 債務協商 | 個人信貸 | 小額借款 | 信貸 | 信貸利率 |
信貸代辦 | 創業貸款 | 銀行貸款 | 貸款投資 | 買車貸款 | 車貸 | 汽車貸款 | 債務協商 | 卡債處理 | 二胎房貸 |
信用不良信貸貸的下來嗎 該怎辦 | 信用貸款哪裡申請最快核貸 | 信用不良要如何申請信用貸款
個人信貸免費諮詢的網站 | 個人信貸條件,銀行個人信貸比較諮詢 | 小額信貸利率比較標準迷思
三面向分析最低信貸利率條件的迷惑陷阱 | 哪家銀行信貸利息最低 | 銀行個人信貸免費諮詢 | 小額信貸推薦幾家 | 個人信貸利率比較銀行條件如何談 |
RF4165456EDFECE15158DCE |
... ... 前言 TCP(Transmission Control Protocol,傳輸控制協議) 是計算機網絡的的重要組成部分,也是網絡編程的重要內容,還有我們平時接觸最多的 HTTP 也是基於 TCP 實現的。TCP 可以說是最重要的傳輸層協議,既然如此,作為開發人員,就有必要把 TCP 的核心概念和原理搞清楚。除此之外,諸如三次握手、四次揮手、滑動窗口和擁塞控制這些概念更是高頻面試題,這就更有理由深入學習一下 TCP 了,本文就為大家詳細梳理一下 TCP 的核心概念和原理。 一、TCP 簡介 第一部分先為大家介紹一下 TCP 的主要概念,並講解一下 TCP 的三個重要特性——1. 面向連接;2. 基於字節流;3. 可靠性。關於網絡分層的概念實在是老生常談了,下圖就是兩種經典的分層模型,可以看到 TCP 在網絡分層中的位置。 ... 網絡分層模型 本文重點對 TCP 進行介紹,從圖中可以看到 TCP 位於傳輸層,而且構建於網絡層的 IP 協議之上,對於 TCP 最常見的介紹就是 「TCP 是一種面向連接的、可靠的、基於字節流的傳輸層通信協議」,那這三個形容詞究竟是什麼意思呢?1.1 面向連接面向連接意味著兩個使用 TCP 的應用 (通常是一個客戶端和一個伺服器) 在彼此交換數據之前必須先建立一個 TCP 連接。這一過程與打電話很相似,先撥號響鈴,等對方應答後再說明是誰。詳細的三次握手、四次揮手過程將在第二部分——連接管理部分進行介紹。1.2 基於字節流TCP 連接雙方的數據交換格式是以字節 (byte,1byte = 8 bit)構成的有序但無結構的字節流。TCP 不在字節流中插入記錄標識符,這被稱為字節流服務(byte stream service)。如果一方的應用程式先傳 10 字節,又傳 20 字節,再傳 50 字節 ,連接的另一方將無法了解發方每次發送了多少字節。收方可以分 4 次接收這 80 個字節,每次接收 20 字節。一端將字節流放到 TCP 連接上,同樣的字節流將出現在 TCP 連接的另一端。另外,TCP 對字節流的內容不作任何解釋,TCP 無法知道傳輸的數據字節流是二進位數據,還是 ASCI I 字符。如果覺得上面這段話比較抽象的話,可以拿 TCP 的字節流和 UDP 的報文 (message) 進行比較(UDP:User Datagram Protocol,用戶數據報協議,和 TCP 同為傳輸層的協議,後面會提供兩者的全面對比)。TCP 的字節流類似於自來水,連接雙方都有緩衝區,可以類比成蓄水池,發送方的發送頻率和每次的發送量沒有固定要求,接收方也可以自由決定自己的接收頻率和每次的接收量,只要把所有的數據接收完畢即可。而 UDP 的報文則類似於瓶裝水 (比如農夫山泉),發送方發送一瓶,接收方就要相應地接收一瓶。下圖描述了 TCP 連接中數據的傳輸過程以及 TCP 在整個過程中所扮演的角色。 ... TCP 在網絡數據傳輸中的位置和角色 按照圖中的流程,比如我們在瀏覽B站,在 TCP 連接建立之後,客戶端的應用層協議可以向 TCP 發送無特殊格式的字節流,TCP 會將這些字節打包成報文段(segment),報文段大小視情況而定,這些報文段會被網絡層的 IP 封裝成 IP 數據報(IP Datagram),然後經過網絡傳輸給伺服器,而接下來伺服器的操作相當於客戶端的逆操作,先從 IP 數據報中拆分出 TCP 報文段,再把 TCP 報文段還原成字節流並發送給上層的應用層協議。伺服器向客戶端發送數據的流程也是一樣的,發送方和接收方的角色互換即可。 報文段簡介上面多次提到了報文段的概念,其結構非常重要,後面的連接過程和擁塞控制等內容也要用到相關概念,先在這裡介紹一下。 ... TCP 報文段結構 圖的上半部分顯示 TCP 報文段被封裝在 IP 數據報中,圖的下半部分則顯示了 TCP 報文段和 TCP 首部的結構,TCP 首部的固定數據有20字節,加上選項部分最大可達60字節,而有效數據部分則是被打包的應用層數據。下面介紹一下 TCP 首部的結構: 埠號 (Source Port and Destination Port):每個 TCP 報文段都包含源端和目的端的埠號,用於尋找發送端和接收端應用進程。這兩個值加上 IP 首部中的源端 IP 地址和目的端 IP 地址就可以確定一個唯一的 TCP 連接。 序號 (Sequence Number):這個欄位的主要作用是用於將失序的數據重新排列。TCP 會隱式地對字節流中的每個字節進行編號,而 TCP 報文段的序號被設置為其數據部分的第一個字節的編號。序號是 32 bit 的無符號數,取值範圍是0到 232 - 1。 確認序號 (Acknowledgment Number):接收方在接受到數據後,會回復確認報文,其中包含確認序號,作用就是告訴發送方自己接收到了哪些數據,下一次數據從哪裡開始發,因此,確認序號應當是上次已成功收到數據字節序號加 1。只有 ACK 標誌為 1 時確認序號欄位才有效。 首部長度 (Header Length):首部中的選項部分的長度是可變的,因此首部的長度也是可變的,所以需要這個欄位來明確表示首部的長度,這個欄位占 4 bit,4 位的二進位數最大可以表示 15,而首部長度是以 4 個字節為一個單位的,因此首部最大長度是 15 * 4 = 60 字節。 保留欄位 (Reserved):占 6 位,未來可能有具體用途,目前默認值為0. 控制位 (Control Bits):在三次握手和四次揮手中會經常看到 SYN、ACK 和 FIN 的身影,一共有 6 個標誌位,它們表示的意義如下: URG (Urgent Bit):值為 1 時,緊急指針生效 ACK (Acknowledgment Bit):值為 1 時,確認序號生效 PSH (Push Bit):接收方應儘快將這個報文段交給應用層 RST (Reset Bit):發送端遇到問題,想要重建連接 SYN (Synchronize Bit):同步序號,用於發起一個連接 FIN (Finish Bit):發送端要求關閉連接 窗口大小 (Window):TCP的流量控制由連接的每一端通過聲明的窗口大小來提供。窗口大小為字節數,起始於確認序號欄位指明的值,這個值是接收端正期望接收的字節。窗口大小是一個 16 bit 欄位,單位是字節, 因而窗口大小最大為 65535 字節。 檢驗和 (Checksum):功能類似於數字簽名,用於驗證數據完整性,也就是確保數據未被修改。檢驗和覆蓋了整個 TCP 報文段,包括 TCP 首部和 TCP 數據,發送端根據特定算法對整個報文段計算出一個檢驗和,接收端會進行計算並驗證。 緊急指針 (Urgent Pointer):當 URG 控制位值為 1 時,此欄位生效,緊急指針是一個正的偏移量,和序號欄位中的值相加表示緊急數據最後一個字節的序號。TCP 的緊急方式是發送端向另一端發送緊急數據的一種方式。 選項 (Options):這一部分是可選欄位,也就是非必須欄位,最常見的可選欄位是「最長報文大小 (MSS,Maximum Segment Size)」。 有效數據部分 (Data):這部分也不是必須的,比如在建立和關閉 TCP 連接的階段,雙方交換的報文段就只包含 TCP 首部。 1.3 可靠性我們都知道 TCP 是具有可靠性的通信協議,它主要通過以下方式確保可靠性,這裡先了解一下可靠性的原理,其中細節部分後文會講: 合理的數據大小:TCP 發送的數據並不是固定的大小,而是會根據實際情況調整報文段的大小。 檢驗和:發送端按照特定算法計算出 TCP 報文段的檢驗和並存儲在 TCP 首部中的對應欄位上,接收端在接收時會以同樣的方式計算校驗和,如果不一致,說明報文段出現錯誤,會將其丟棄。 序號與確認序號:對亂序的數據進行排序後發給應用層,並丟棄重複的數據。 超時重傳機制:當 TCP 發出一個報文段後,它會啟動一個定時器,等待目的端確認收到這個報文段。如果不能及時收到一個確認,將重發這個報文段,後面會細講這個機制。 連接管理:也就是三次握手和四次揮手,連接的可靠性是整體可靠性的前提,本文第二部分將會詳細介紹連接管理的內容。 流量控制:TCP 雙方都有固定大小的緩衝區,流量控制的原理是利用滑動窗口控制數據發送速度,避免緩衝區溢出導致數據丟失。 擁塞控制:TCP 利用慢啟動和擁塞避免等算法實現了擁塞控制。 上面為大家介紹了 TCP 最重要的三個特點,在本文第一部分的最後,再來看看 TCP 和 UDP 的對比吧。1.4 TCP 和 UDP 的區別 UDP TCP 是否連接 無連接 面向連接 是否可靠 不可靠,沒有確認機制、流量控制和擁塞控制 可靠,有確認機制、流量控制和擁塞控制 連接對象個數 支持一對一,一對多,多對一和多對多交互通信 只支持一對一通信 傳輸方式 面向報文 面向字節流 首部開銷 首部開銷小,固定8字節 首部開銷較大,最小20字節,最大60字節 適用場景 適用於實時應用(IP電話、視頻會議、直播等) 適用於要求可靠傳輸的應用,如文件傳輸等 二、TCP 的連接控制 2.1 建立連接2.1.1 三次握手這個問題簡直太經典了,如果你在面試中只被問到了一個關於 TCP 的問題,那大機率就是關於三次握手的問題。TCP 的重要特性之一就是面向連接,連接雙方在發送數據之前必須經歷握手的階段,那具體的過程是怎樣的呢?先來看圖,大家最好可以動手簡單畫畫這個圖,當然還有後文四次揮手的圖,幫助加深記憶。 ... 三次握手過程 如圖所示,雙方之間的三個藍色箭頭就表示了三次握手過程中所發生的數據交換: 第一次握手:客戶端向伺服器發送報文段1,其中的 SYN 標誌位 (前文已經介紹過各種標誌位的作用)的值為 1,表示這是一個用於請求發起連接的報文段,其中的序號欄位 (Sequence Number,圖中簡寫為seq)被設置為初始序號x (Initial Sequence Number,ISN),TCP 連接雙方均可隨機選擇初始序號。發送完報文段1之後,客戶端進入 SYN-SENT 狀態,等待伺服器的確認。 第二次握手:伺服器在收到客戶端的連接請求後,向客戶端發送報文段2作為應答,其中 ACK 標誌位設置為 1,表示對客戶端做出應答,其確認序號欄位 (Acknowledgment Number,圖中簡寫為小寫 ack) 生效,該欄位值為 x + 1,也就是從客戶端收到的報文段的序號加一,代表伺服器期望下次收到客戶端的數據的序號。此外,報文段2的 SYN 標誌位也設置為1,代表這同時也是一個用於發起連接的報文段,序號 seq 設置為伺服器初始序號y。發送完報文段2後,伺服器進入 SYN-RECEIVED 狀態。 第三次握手:客戶端在收到報文段2後,向伺服器發送報文段3,其 ACK 標誌位為1,代表對伺服器做出應答,確認序號欄位 ack 為 y + 1,序號欄位 seq 為 x + 1。此報文段發送完畢後,雙方都進入 ESTABLISHED 狀態,表示連接已建立。 常見面試題 1: TCP 建立連接為什麼要三次握手而不是兩次?答:網上大多數資料對這個問題的回答只有簡單的一句:防止已過期的連接請求報文突然又傳送到伺服器,因而產生錯誤,這既不夠全面也不夠具體。下面給出比較詳細而全面的回答: 防止已過期的連接請求報文突然又傳送到伺服器,因而產生錯誤在雙方兩次握手即可建立連接的情況下,假設客戶端發送 A 報文段請求建立連接,由於網絡原因造成 A 暫時無法到達伺服器,伺服器接收不到請求報文段就不會返回確認報文段,客戶端在長時間得不到應答的情況下重新發送請求報文段 B,這次 B 順利到達伺服器,伺服器隨即返回確認報文並進入 ESTABLISHED 狀態,客戶端在收到 確認報文後也進入 ESTABLISHED 狀態,雙方建立連接並傳輸數據,之後正常斷開連接。此時姍姍來遲的 A 報文段才到達伺服器,伺服器隨即返回確認報文並進入 ESTABLISHED 狀態,但是已經進入 CLOSED 狀態的客戶端無法再接受確認報文段,更無法進入 ESTABLISHED 狀態,這將導致伺服器長時間單方面等待,造成資源浪費。 三次握手才能讓雙方均確認自己和對方的發送和接收能力都正常第一次握手:客戶端只是發送處請求報文段,什麼都無法確認,而伺服器可以確認自己的接收能力和對方的發送能力正常;第二次握手:客戶端可以確認自己發送能力和接收能力正常,對方發送能力和接收能力正常;第三次握手:伺服器可以確認自己發送能力和接收能力正常,對方發送能力和接收能力正常;可見三次握手才能讓雙方都確認自己和對方的發送和接收能力全部正常,這樣就可以愉快地進行通信了。 告知對方自己的初始序號值,並確認收到對方的初始序號值TCP 實現了可靠的數據傳輸,原因之一就是 TCP 報文段中維護了序號欄位和確認序號欄位,也就是圖中的 seq 和 ack,通過這兩個欄位雙方都可以知道在自己發出的數據中,哪些是已經被對方確認接收的。這兩個欄位的值會在初始序號值得基礎遞增,如果是兩次握手,只有發起方的初始序號可以得到確認,而另一方的初始序號則得不到確認。 常見面試題2: TCP 建立連接為什麼要三次握手而不是四次?答:相比上個問題而言,這個問題就簡單多了。因為三次握手已經可以確認雙方的發送接收能力正常,雙方都知道彼此已經準備好,而且也可以完成對雙方初始序號值得確認,也就無需再第四次握手了。常見面試題3: 有一種網絡攻擊是利用了 TCP 建立連接機制的漏洞,你了解嗎?這個問題怎麼解決?答:在三次握手過程中,伺服器在收到了客戶端的 SYN 報文段後,會分配並初始化連接變量和緩存,並向客戶端發送 SYN + ACK 報文段,這相當於是打開了一個「半開連接 (half-open connection)」,會消耗伺服器資源。如果客戶端正常返回了 ACK 報文段,那麼雙方可以正常建立連接,否則,伺服器在等待一分鐘後會終止這個「半開連接」並回收資源。這樣的機制為 SYN洪泛攻擊 (SYN flood attack)提供了機會,這是一種經典的 DoS攻擊 (Denial of Service,拒絕服務攻擊),所謂的拒絕服務攻擊就是通過進行攻擊,使受害主機或網絡不能提供良好的服務,從而間接達到攻擊的目的。在 SYN 洪泛攻擊中,攻擊者發送大量的 SYN 報文段到伺服器請求建立連接,但是卻不進行第三次握手,這會導致伺服器打開大量的半開連接,消耗大量的資源,最終無法進行正常的服務。解決方法:SYN Cookies,現在大多數主流作業系統都有這種防禦系統。SYN Cookies 是對 TCP 伺服器端的三次握手做一些修改,專門用來防範 SYN 洪泛攻擊的一種手段。它的原理是,在伺服器接收到 SYN 報文段並返回 SYN + ACK 報文段時,不再打開一個半開連接,也不分配資源,而是根據這個 SYN 報文段的重要信息 (包括源和目的 IP 地址,埠號可一個秘密數),利用特定散列函數計算出一個 cookie 值。這個 cookie 作為將要返回的SYN + ACK 報文段的初始序列號(ISN)。當客戶端返回一個 ACK 報文段時,伺服器根據首部欄位信息計算 cookie,與返回的確認序號(初始序列號 + 1)進行對比,如果相同,則是一個正常連接,然後分配資源並建立連接,否則拒絕建立連接。 2.2.2 同時打開 這是 TCP 建立連接的特殊情況,有時會出現兩臺機器同時執行主動打開的情況,不過機率非常小,這種情況大家僅作了解即可。在這種情況下就無所謂發送方和接收方了,雙放都可以稱為客戶端和伺服器,同時打開的過程如下: ... 同時打開的過程 如圖所示,雙方在同一時刻發送 SYN 報文段,並進入 SYN-SENT 狀態,在收到 SYN 後,狀態變為 SYN-RECEIVED,同時它們都再發送一個 SYN + ACK 的報文段,狀態都變為 ESTABLISHED,連接成功建立。在此過程中雙方一共交換了4個報文段,比三次握手多一個。2.2 關閉連接2.2.1 四次揮手建立一個連接需要三次握手,而終止一個連接要經過 4次握手。這由 TCP 的半關閉( half-close) 造成的。既然一個 TCP 連接是全雙工 (即數據在兩個方向上能同時傳遞), 因此每個方向必須單獨地進行關閉。這原則就是當一方完成它的數據發送任務後就能發送一個 FIN 來終止這個方向連接。當一端收到一個 FIN,它必須通知應用層另一端已經終止了數據傳送。理論上客戶端和伺服器都可以發起主動關閉,但是更多的情況下是客戶端主動發起。 ... 四次揮手過程 四次揮手詳細過程如下: 客戶端發送關閉連接的報文段,FIN 標誌位1,請求關閉連接,並停止發送數據。序號欄位 seq = x (等於之前發送的所有數據的最後一個字節的序號加一),然後客戶端會進入 FIN-WAIT-1 狀態,等待來自伺服器的確認報文。 伺服器收到 FIN 報文後,發回確認報文,ACK = 1, ack = x + 1,並帶上自己的序號 seq = y,然後伺服器就進入 CLOSE-WAIT 狀態。伺服器還會通知上層的應用程式對方已經釋放連接,此時 TCP 處於半關閉狀態,也就是說客戶端已經沒有數據要發送了,但是伺服器還可以發送數據,客戶端也還能夠接收。 客戶端收到伺服器的 ACK 報文段後隨即進入 FIN-WAIT-2 狀態,此時還能收到來自伺服器的數據,直到收到 FIN 報文段。 伺服器發送完所有數據後,會向客戶端發送 FIN 報文段,各欄位值如圖所示,隨後伺服器進入 LAST-ACK 狀態,等待來自客戶端的確認報文段。 客戶端收到來自伺服器的 FIN 報文段後,向伺服器發送 ACK 報文,隨後進入 TIME-WAIT 狀態,等待 2MSL(2 * Maximum Segment Lifetime,兩倍的報文段最大存活時間) ,這是任何報文段在被丟棄前能在網絡中存在的最長時間,常用值有30秒、1分鐘和2分鐘。如無特殊情況,客戶端會進入 CLOSED 狀態。 伺服器在接收到客戶端的 ACK 報文後會隨即進入 CLOSED 狀態,由於沒有等待時間,一般而言,伺服器比客戶端更早進入 CLOSED 狀態。 常見面試題1: 為什麼 TCP 關閉連接為什麼要四次而不是三次?答:伺服器在收到客戶端的 FIN 報文段後,可能還有一些數據要傳輸,所以不能馬上關閉連接,但是會做出應答,返回 ACK 報文段,接下來可能會繼續發送數據,在數據發送完後,伺服器會向客戶單發送 FIN 報文,表示數據已經發送完畢,請求關閉連接,然後客戶端再做出應答,因此一共需要四次揮手。常見面試題2: 客戶端為什麼需要在 TIME-WAIT 狀態等待 2MSL 時間才能進入 CLOSED 狀態?答:按照常理,在網絡正常的情況下,四個報文段發送完後,雙方就可以關閉連接進入 CLOSED 狀態了,但是網絡並不總是可靠的,如果客戶端發送的 ACK 報文段丟失,伺服器在接收不到 ACK 的情況下會一直重發 FIN 報文段,這顯然不是我們想要的。因此客戶端為了確保伺服器收到了 ACK,會設置一個定時器,並在 TIME-WAIT 狀態等待 2MSL 的時間,如果在此期間又收到了來自伺服器的 FIN 報文段,那麼客戶端會重新設置計時器並再次等待 2MSL 的時間,如果在這段時間內沒有收到來自伺服器的 FIN 報文,那就說明伺服器已經成功收到了 ACK 報文,此時客戶端就可以進入 CLOSED 狀態了。 2.2.2 同時關閉 之前在介紹 TCP 建立連接的時候會有一種特殊情況,那就是同時打開,與之對應地, TCP 關閉時也會有一種特殊情況,那就是同時關閉,這種情況僅作了解即可,流程圖如下: ... 同時關閉過程 這種情況下,雙方應用層同時發出關閉命令,這將導致雙方各發送一個 FIN,兩端均從 ESTABLISHED 變為 FIN_WAIT_1,兩個 FIN 經過網絡傳送後分別到達另一端。收到 FIN 後,狀態由 FIN_WAIT_1 變遷到 CLOSING,並發送最後的 ACK,當收到最後的 ACK 時,為確保對方也收到 ACK,狀態變化為 TIME_WAIT,並等待 2MSL 時間,如果一切正常,隨後會進入 CLOSED 狀態。 三、TCP 的流量控制與滑動窗口 3.1 什麼是流量控制?TCP 連接雙方的主機都為該連接設置了發送緩存和接收緩存,這些緩存起到了蓄水池的作用,我們肯定不能把上層應用程式發來的數據一股腦兒發送到網絡中,而是利用發送緩存將其緩存起來,然後再按一定的速率通過網絡發送給對方,而接收緩存的作用是把對方傳來的數據先緩存起來,等到己方應用程式有空的時候再來取走數據。示意圖如下: ... TCP 緩存示意圖 在此過程中,如果接收方應用程式讀取數據的速度小於發送方的數據發送速度,將導致接收方的接收緩存溢出,造成數據丟失,這顯然不是我們想看到的。因此 TCP 為應用程式提供了流量控制服務 (flow-control service),以消除發送方使接收方的接收緩存溢出的可能性。簡單來說流量控制的目的就是協調發送方的數據發送速度,使其與接收方的數據處理速度相匹配,避免數據丟失,那麼如何實現流量控制呢?3.2 早期的流量控制模式——停止-等待模式 (stop-wait) 顧名思義就是發送方在發送一個數據包後就停止發送,等待對方響應 ACK,然後才能繼續發送數據。這種模式的具體實現為 Positive Acknowledgment With Retransmission (PAR),意為帶重傳的肯定確認協議,其實現方式如下圖所示: ... PAR 示意圖 這種實現很簡單,發送方在發送數據包 (圖中的msg)時會設置一個計時器,然後等待接收方的 ACK,接收方在收到數據後會返回 ACK 作為應答,發送方在收到 ACK 後會發送下一個數據包。如果由於網絡原因造成數據包或者 ACK 丟失時,計時器會超時,然後發送方會重新發送未被確認的數據包。可以看到,這種模式雖然可以確保數據傳輸的可靠性,但是有個致命的缺點,那就是效率太低?如果是你,你會怎麼對這個方案進行優化呢?既然每次發送只一個數據包效率太低,那就多發送幾個,然後給這些數據包編上號,接收端必須對每一個包進行確認,這樣設備 A 一次多發送幾個片段,而不必等候 ACK,同時接收端也要告知它能夠收多少,這樣發送端發起來也有個限制,當然還需要保證順序性,不要亂序,對於亂序的狀況,我們可以允許等待一定情況下的亂序,比如說先緩存提前到的數據,然後去等待需要的數據,如果一定時間沒來就丟掉亂序的數據,來保證順序性,這樣的話,數據傳輸效率就可以大大提高。不過 TCP 也沒有採用這種方案,而是在此基礎上實現更加複雜的滑動窗口。3.3 滑動窗口 我們可以把發送方的發送緩存中的字節分為以下四類,每個編號對應一個字節: ... 發送緩存中的字節分類 第一類:已發送且已確認,這些數據已經發送成功並已經被確認的數據,比如圖中的前31個bytes,這些數據其實的位置是在窗口之外了,下一步將被移出發送緩存。窗口內順序最低的字節被確認之後,窗口左邊界會向右移動,稱為窗口合攏。 第二類:已發送但未收到確認,這部分數據已經被發送出去,但是還沒有收到接收端的 ACK,認為並沒有完成發送,這部分數據屬於窗口內的數據。 第三類:未發送但是接收方已經準備好接收,這部分是儘快發送的數據,這部分數據已經被加載到緩存中,也在發送窗口中,正在等待發送,其實這個窗口是完全有接收方告知的,接收方告知當前可以接受這些數據,所以發送方需要儘快的發送。 第四類:未發送且接收方未準備好接收,這些數據屬於未發送,同時接收端也不允許發送的,因為這些數據已經超出了發送端所接收的範圍。 3.3.1 發送窗口和接收窗口 ... 發送窗口 發送窗口:圖中的黑色框就是發送方的發送窗口,其大小由兩個因素決定:1、接收方的提供的窗口大小 (TCP 報文段首部中的 window 欄位),發送方在三次握手階段首次得到這個值,之後的通信過程中接收方會根據自己的可用緩存對這個值進行動態調整;2、發送方會根據網絡情況維護一個擁塞窗口變量 (後文介紹)。發送窗口的大小取這兩個值的最小值。對於發送方來說,發送窗口分為兩部分,分別是已經發送的部分(已經發送了,但是沒有收到ACK)和可用窗口,接收端允許發送但是沒有發送的那部分稱為可用窗口。接收窗口:對於接收端也是有一個接收窗口的,類似發送端,接收端的數據有3個分類,因為接收端並不需要等待ACK所以它沒有類似的接收並確認了的分類,情況如下 Received and ACK Not Send to Process:這部分數據屬於接收了數據但是還沒有被上層的應用程式接收; Received Not ACK: 已經接收,但是還沒有回覆 ACK; Not Received:有空位,還沒有被接收的數據。 3.3.2 滑動窗口是如何滑動的? ... 滑動窗口的滑動過程 累積確認概念:TCP 並不是每一個報文段都會回復一個 ACK ,可能會對兩個報文段發送一個ACK,也可能會對多個報文段發送 1 個 ACK,這稱為累積確認。比如說發送方有 1/2/3 3 個報文段,先發送了2,3 兩個報文段,但是接收方期望收到1報文段,這個時候 2/3 報文段就只能放在緩存中等待報文1的空洞被填上,如果報文段1一直不來,報文2/3也將被丟棄,如果報文1來了,那麼會發送一個 ACK 對第3個報文段進行確認,就代表對這三個報文段全部進行了確認。下面舉例說明一下窗口滑動的過程: 在握手過程中,接收方通告的窗口大小為20字節,所以發送方將發送窗口大小設置為20字節。 從圖中的"上一個發送窗口的位置"(灰色虛線框)說起, 32-51號字節恰好處於發送窗口中,恰好20個字節,假設 TCP 將其分為 4 個報文段進行發送,每個報文段 5 個字節數據,分別記為 seg1 32-36, seg2 37-41, seg3 42-46, seg4 47-51。 TCP 將有序發送 seg1、seg2、seg3和seg4四個報文段,如果這四個報文段都順利到達接收方 (圖中並不是這樣),接收方將發回一個累積確認的 ACK 報文段,其中 ack = 52,代表希望收到下一個報文段的起始字節編號,報文段中也會繼續通告窗口大小,如果還是20字節,那麼發送方的窗口將整體向右移動20字節,如果通告的窗口值變小,比如變成15,那麼發送窗口左邊界移動20字節,右邊界移動15字節。 如果在發送過程中 seg2 報文段丟失,而其他三個報文段正常到達接收方,那麼接收方會現接受這三個報文段,然後返回 ACK 報文段,ack = 37,表示希望收到的下一個報文段的起始字節號為37,也就是seg2報文段。如果通告窗口值未發生變化,發送方在收到 ACK 後會將窗口整體右移5個字節,也就變成了圖中的位置。 由於 seg2 還未收到 ACK,當重傳計時器超時後,發送方會重新發送 seg2,此時52-56號字節又落到了發送窗口中,TCP 將其封裝成 報文段進行發送,如果接收方全部順利收到,會返回一個累積確認的 ACK,ack = 57,表示希望收到的喜愛個報文段的起始字節號為57。 接下來就是重複上述過程,直到 TCP 字節流的所有數據發送完畢。在這個過程中,接收方會根據自己接收緩存的剩餘空間動態調整窗口值,對發送方進行流量控制。 ... 滑動窗口動畫效果 四、TCP 的擁塞控制 4.1 什麼是擁塞控制?當數據從一個大的管道 (比如一個快速區域網)向一個較小的管道 (比如較慢的廣域網)發送的時候就會發生擁塞,還有一種情況就是當多個輸入流到達一個路由器,而路由器的輸出流小於這些輸入流的總和時,也會發生擁塞。舉個例子就好理解了,第一種情況就好像源源不斷的車流從八車道進入四車道,如果不進行控制,必然造成道路擁堵;第二種情況類似於很多車輛匯入十字路口,如果進的速度大於出的速度,再不加以控制,必然也會造成擁堵。於是 TCP 提供了響應的機制來應對這種情況,也就是 TCP 的擁塞控制。4.2 如何實現擁塞控制?TCP 一共使用了四種算法來實現擁塞控制:1、慢開始 (slow-start);2、擁塞避免 (congestion avoidance);3、快速重傳 (fast retransmit);4、快速恢復 (fast recovery)。這裡先介紹一下擁塞窗口 (congestion window,簡寫為 cwnd)的概念:擁塞窗口是由發送方根據網絡狀況維護的一個變量,用於控制自己的數據發送速率。前文提到了發送方的發送窗口受兩個變量約束,一是接收方通告的窗口大小值,二就是發送方自身的擁塞窗口,實際的發送窗口大小取二者最小值。4.2.1 慢開始(慢啟動) 在早期的 TCP Tahoe 版本中,只用到了慢開始和擁塞避免算法,如圖所示: ... 慢開始和擁塞避免 如圖所示,在剛開始,TCP 採用慢開始算法。慢開始不是指擁塞窗口的增長速度慢(增長速度是指數增長,非常快),而是指 TCP 開始發送設置 cwnd=1。思路就是不要一開始就發送大量的數據,先探測一下網絡的擁塞程度,也就是說由小到大 逐漸增加擁塞窗口的大小。這裡用報文段的個數的擁塞窗口大小舉例說明慢啟動算法,實時擁塞窗口大小是以字節為單位的。為了防止 cwnd 增長過大引起網絡擁塞,設置一個慢開始門限(slow start threshold,簡寫為 ssthresh) ,當cnwd < ssthresh,使用慢開始算法 當 cnwd = ssthresh,既可使用慢開始算法,也可以使用擁塞避免算法 當 cnwd > ssthresh,使用擁塞避免算法4.2.2 擁塞避免當擁塞窗口大小達到初始 ssthresh 值時,轉而採用擁塞避免算法。擁塞避免並非完全能夠避免擁塞,是說在擁塞避免階段將擁塞窗口控制為按線性規律增長,使網絡比較不容易出現擁塞,思路:讓擁塞窗口 cwnd 緩慢地增大,即每經過一個往返時間 RTT 就把發送方的擁塞窗口加一。無論是在慢開始階段還是在擁塞避免階段,只要發送方判斷網絡出現擁塞(其根據就是沒有收到確認,雖然沒有收到確認可能是其他原因的分組丟失,但是因為無法判定,所以都當做擁塞來處理),就把慢開始門限設置為出現擁塞時的發送窗口大小的一半。然後把擁塞窗口設置為 1,執行慢開始算法。4.2.3 快速重傳 ... TCP Reno 應用了四種算法 有時候的發送方未收到某個報文段的確認也並一定就說明一定是出現了網絡擁塞,也可能是其他原因,所以直接執行慢開始算法會影響整體效率,後來的 TCP Reno 版本解決了這一問題,那就是採用快速重傳和快速恢復算法。快速重傳要求接收方在收到一個失序的報文段後就立即發出重複確認(為的是使發送方及早知道有報文段沒有到達對方),而不要等到自己發送數據時捎帶確認。快重傳算法規定,發送方只要一連收到三個重複確認就應當立即重傳對方尚未收到的報文段,而不必繼續等待設置的重傳計時器時間到期。由於不需要等待設置的重傳計時器到期,能儘早重傳未被確認的報文段,能提高整個網絡的吞吐量。4.2.4 快速恢復當發送方連續收到三個重複確認時,就執行「乘法減小」算法,把 ssthresh 門限減半。但是接下去並不執行慢開始算法。考慮到如果網絡出現擁塞的話就不會收到好幾個重複的確認,所以發送方現在認為網絡可能沒有出現擁塞。所以此時不執行慢開始算法,而是將 cwnd 設置為 ssthresh 的大小, 然後執行擁塞避免算法。 五、TCP 粘包與拆包 5.1 TCP 粘包和拆包的原因我們知道 TCP 是以字節流的方式傳輸數據,傳輸的最小單位為一個報文段(segment)。TCP 首部 中有個選項 (Options)的欄位,常見的選項為 MSS (Maximum Segment Size最大消息長度),它是收發雙方協商通信時每一個報文段所能承載的最大有效數據的長度。數據鏈路層每次傳輸的數據有個最大限制MTU (Maximum Transmission Unit),一般是1500比特,超過這個量要分成多個報文段,MSS 則是這個最大限制減去 TCP 的首部,光是要傳輸的數據的大小,一般為1460比特。換算成字節,也就是180多字節。MSS = MTU - HeaderTCP 為提高性能,發送端會將需要發送的數據發送到發送緩存,等待緩存滿了之後,再將緩存中的數據發送到接收方。同理,接收方也有接收緩存這樣的機制,來接收數據。上面這些是發生 TCP 粘包和拆包的前提,下面是具體的原因: 要發送的數據大於TCP發送緩衝區剩餘空間大小,將會發生拆包。 待發送數據大於MSS(最大報文長度),TCP在傳輸前將進行拆包。 應用程式寫入數據小於剩餘緩存大小,網卡將應用多次寫入的數據先緩存起來,然後一起發送到網絡上,這將會發生粘包。 接收數據端的應用層沒有及時讀取接收緩存中的數據,將發生粘包。 5.2 TCP 粘包和拆包的解決方案 設置定長消息,服務端每次讀取既定長度的內容作為一條完整消息。 設置消息邊界,數據結尾尾增加特殊字符分割。 使用帶消息頭的協議,消息頭存儲消息開始標識及消息長度信息,接收方獲取消息頭的時候解析出消息長度,然後向後讀取該長度的內容。 六、結語 本文為大家梳理了 TCP 的核心概念和原理,也分享了一些高頻面試題,希望對你有幫助。儘管文章字數超過了一萬字,但是 TCP 的很多細節還遠遠沒有介紹到,如果想進一步了解,可以參考一下下面參考資料中提到的幾本書。 《TCP/IP詳解卷一:協議》 《計算機網絡自頂向下方法》 《TCP/IP Guide》 TCP-IP詳解:滑動窗口(Sliding Window) ...
詳細資料
- ISBN:9780230035195
- 叢書系列:
- 規格:87頁 / 13 x 19.8 cm / 普通級
- 本書分類:> > >
文章來源取自於:
壹讀 https://read01.com/BJQ6JQ7.html
博客來 https://www.books.com.tw/exep/assp.php/888words/products/0010403429
如有侵權,請來信告知,我們會立刻下架。
DMCA:dmca(at)kubonews.com
聯絡我們:contact(at)kubonews.com
花蓮信用聯徵分數ptt台北銀行小額貸款花蓮銀行借錢企業貸款利率比較
屏東信貸條件評分 苗栗信用卡債務協商 個人信貸、車貸、二胎好過嗎?雲林銀行借款 軍公教債務整合協商 信貸繳不出來!我可以辦 信貸整合 降低利率嗎?基隆買房自備款要多少 台南信用卡信用評分 個人信貸條件有哪些?5個基本門檻報你知!南投信用貸款推薦融資公司 新北信用卡債務協商 代書貸款、房屋貸款、個人信貸利息比銀行高到底有多高?
留言列表