全網最全最通俗的TCP總結!面試?一文就搞定!!!

運輸層是面向通信部分的最高層,同時也是用戶應用功能中的最底層,主要是向下封裝通信部分、對接應用層完成分用複用這兩個主要功能,運輸層是通常開發中接觸到的最底層。在 TCP/IP 協議棧中有兩種重要的運輸層協議 UDPTCP,同時 TCP 也是應用層 HTTP 協議的基礎。

本篇以面試問題爲導向,用通俗易懂的語言進行總結回答。

溫故而知新,可以爲師矣。

本篇文字較多:先收藏,不迷路哦!有幫助的話,別忘了點贊+關注!

上一篇:《面試必考問題一文搞定:HTTP和HTTPS?TLS的工作流程?》

插個題外話,推薦一本書《圖解HTTP》,作爲一名菜鳥覺得這本書非常有趣,哪怕是作爲睡前讀物也是可以的。不得不吐槽一下學校用的謝希仁第七版的計網教材,真的又臭又硬。(當然了之後的深入學習還是要沉下心來去細啃一下)

熱身一下:說說 TCP 和 UDP 的區別?

TCP(傳輸控制協議):面向連接以字節流的方式進行傳輸,提供可靠服務,適用於文件傳輸、郵件傳輸、聊天消息等需要可靠傳輸的常見,首部 20~60 字節。通信雙方需要經過三次握手後才能建立 TCP 連接進行通信,通信完成後還需要四次揮手斷開連接。並且 TCP 不支持多播和廣播服務。

UDP(用戶數據報協議):無連接以數據報文段的方式進行傳輸,提供非可靠傳輸服務,但是傳輸速度比 TCP 協議快,佔用資源比 TCP 協議少,適用於要求通信速度的場景如域名轉換、視頻流、直播流等等,首部 8 字節。僅僅提供了校驗和來保證報文的完整性,如果校驗失敗,直接丟棄,不做任何處理。

關於 TCP 連接的建立和關閉有了解過麼?

TCP 協議爲了保證通信服務的可靠性,採用三次握手的策略來建立可靠的通信信道,數據傳輸完成後通過四次揮手的策略來關閉連接。

爲什麼需要三次握手才能建立連接?

三次握手的過程大致如下圖:
在這裏插入圖片描述

出自《圖解HTTP》 PS:下文用客戶端和服務端來表述上圖中的發送端和接收端。

  1. 第一次握手:發送端(客戶端)發送帶有 SYN 標誌的數據包給接收端(服務端),接收端接收到這個數據包之後,服務端知道了客戶端發送功能正常,同時也知道了服務端接收功能正常
  2. 第二次握手:服務端發送帶有 SYN/ACK 標誌的數據包給客戶端,客戶端接收到這個數據包之後,客戶端就知道了客戶端發送、接受功能都正常服務端發送、接受功能都正常
  3. 第三次握手:客戶端發送帶有 ACK 標誌的數據包給服務端,服務端接收到這個數據包後,服務端知道了客戶端發送、接受功能都正常服務端發送、接受功能都正常

至此,三次握手完成,此時的客戶端和服務端都確認了:雙方的收發功能全部正常

缺少任何一步,都不能使雙方成功相互確認收發功能。

爲什麼不是兩次握手呢?爲什麼客戶端還要最終確認一次呢?

爲了防止已經失效的連接請求報文突然又傳送到了服務器,從而產生錯誤連接。如果是兩次握手,舉例如下:

客戶端發送了第一個 SYN 標誌的連接請求,但是在網絡中阻塞滯留了,客戶端一直到超時都沒有等到來自服務端的確認請求,於是重發了一個 SYN 標誌的連接請求,這次順利完成兩次握手建立了連接、傳輸數據、關閉連接。一切風平浪靜了。。。這時!第一個連接請求姍姍來遲,到達了服務器,經過兩次握手建立了一個並不需要的連接,浪費了資源還可能導致不必要的錯誤。

如果是三次握手策略,當第一個被阻塞滯留報文傳送到服務端,雖然服務端對這條無效報文回覆了對應的 SYN-ACK 確認報文,但是客戶端不會再次發出 ACK 報文,從而讓服務器知道客戶端並不需要建立這個連接。

服務端爲什麼要回傳 SYN-ACK 應答標誌?而不是 ACK 標誌?

SYN 是客戶端發出的一個握手信號,服務端接收後回傳是爲了告訴客戶端,我要應答的握手信息確實就是你所發送的。

說說四次揮手的過程?

打字好累,我相信看字也不輕鬆,換換腦子,來畫個圖吧!
在這裏插入圖片描述

  1. 第一次揮手:客戶端進入 FIN-WAIT-1 階段,客戶端就不再向服務端傳輸數據了,但是依然可以接受服務端的數據。

  2. 第二次揮手:服務端收到客戶端發來的 FIN 標誌的關閉連接報文,通知上層應用後向客戶端發送 ACK 標誌的確認報文,進入 CLOSE-WAIT 階段。

    客戶端收到這個確認報文後,進入 FIN-WAIT-2 階段,繼續接收服務端傳輸的數據,並等待服務端發送 FIN 標誌的關閉連接報文。

  3. 第三次揮手:服務端傳輸完最後的數據,向客戶端發送 FIN 標誌的關閉連接報文,並進入 LAST-ACK 階段,等待客戶端最後的確認。

  4. 第四次握手:客戶端收到服務端的關閉連接報文後,發出最後的 ACK 標誌的確認報文,並進入 TIME-WAIT 階段,這個階段會在等待 2MSL(報文最大生存時間) 後釋放客戶端 TCB(傳輸控制塊) 進入 CLOSED 狀態,真正完成關閉連接。

    而服務端收到客戶端發來的 ACK 標誌的確認報文後,立刻釋放服務端 TCB 進入 CLOSED 狀態,完成連接關閉。

服務器完全關閉 TCP 連接的時間要比客戶端早一些。

客戶端完成確認完成後爲什麼不能立刻釋放資源關閉連接?還要等待 2MSL?

等待 2MSL(報文最大生存時間) 是爲了確保客戶端發送的 ACK 標誌的確認報文能夠正確到達服務端,如果這個確認報文因爲各種問題導致沒有到達服務端,服務器會在定時器到期後,重新發送 FIN+ACK 標誌的連接關閉報文,而客戶端在這個等待的 2MSL 的時間段內可以收到這個服務端重傳的報文,從而重新發送 ACK 確認報文,並且重啓 2MSL 時間的計時器。

爲什麼三次握手就可以建立連接,而關閉連接卻需要四次揮手呢?

建立連接的時候,服務端監聽到建立連接的 SYN 報文後,將 ACK 和 SYN 一起發送給客戶端,就可以讓客戶端知道服務端收到了自己的請求,並且已經做好了建立連接的準備。

關閉連接的時候,服務端收到客戶端發來的 FIN 報文後,知道客戶端不再發送消息了,於是服務端可以立刻迴應一個 ACK 報文,但是服務端此時可能還需要繼續發送完最後的數據,只有當服務端發送完最後的數據,才能夠向客戶端發出自己的 FIN 報文。正是因爲關閉連接時 ACK 和 FIN 標誌的報文需要分開發送,所以導致關閉連接時需要多發送一次報文。

如果建立連接之後,客戶端出現故障了怎麼處理的?

爲了防止服務器一直等待從而白白浪費資源,TCP 設置了一個保活計時器,服務端每次收到客戶端請求之後就會重置保活計時器,如果計時器到期仍沒有收到來自客戶端的數據,服務器會主動地每隔 75 秒發送一個探測報文,如果連續發送 10 個探測報文客戶端仍然沒有動靜,服務器就會釋放資源關閉連接。

除了剛纔說的握手揮手,還有其他保證TCP可靠傳輸的機制麼?

接下來部分文字摘自謝希仁的《計算機網絡》第七版

tSPuFJ.png

檢驗和

TCP 報文首部的檢驗和字段,目的用來校驗首部和數據兩部分在傳輸過程中的正確性,如果接收端收到報文後通過檢驗和計算發現出了差錯,TCP 協議會將這個出錯的報文段直接丟棄,並且不會進行相應的確認。

ARQ協議

自動重傳請求(ARQ)是 OSI 七層模型中數據鏈路層傳輸層的一個錯誤糾正協議,有確認超時兩個主要機制,可以在不可靠的傳輸網絡上實現可靠的通信。如果發送方發送消息一段時間後沒有收到對應的確認幀,發送方會重新發送這條消息。

停止等待ARQ協議

發送方每發完一個分組就停止發送(暫時保留已發送分組的副本),等待接收方的 ACK 確認幀。如果等待計時器超時後,還沒收到 ACK 確認,說明消息沒有成功發送,需要重新發送,直至收到對應的確認幀再發送下一個分組。

分組和分組的確認都必須進行編號,這樣才能明確哪一個發送出去的分組收到了確認,而且可以檢測到重複的分組,重複的分組需要丟棄,但還是需要發送確認。

這麼做的優點是協議簡單,缺點是信道利用率低、等待時間長。

連續ARQ協議

發送方維持一個發送窗口,所有在發送窗口內的分組都可以連續發送出去,不需要停止等待接收方的確認幀。接收方採用累計確認,對按序到達的最後一個分組發送確認,表明到這個分組爲止的所有分組都已經正確收到了。

這麼做的優點是信道利用率高、容易實現,即使分組丟失也不必立刻重傳。

缺點是不能向發送方反映出接收方已經確認收到的所有分組信息。例如:發送方發送了 5 個分組,中間的第 3 個分組丟失了,這時接收方只能對前兩個分組發出確認收到,發送方無法知道後面三個分組的情況,只好把後面的三個分組都重傳一次,這個過程叫做 Go-Back-N(回退 N),表示需要回退回來,重傳已經發送過的 N 個分組。

所以當通信線路質量不好時,連續 ARQ 協議會帶來負面影響。

流量控制

TCP 使用可變滑動窗口實現流量控制,就是讓發送方的發送速率不要太快,要讓接收方來得及接受。接收方發送的確認報文中的窗口字段用來控制發送方窗口的大小,從而影響發送方的發送速率。當窗口字段設置爲 0 時,發送方不能發送數據。

流量控制往往是點到點通信量的控制,是一個端到端的問題。

擁塞控制

擁塞控制就是爲了防止過多的數據注入到網絡中,這樣就可以是網絡中的路由器或鏈路不至於過載。擁塞控制是一個全局性的過程,涉及到所有的主機,所有的路由器,以及與降低網絡傳輸性能有關的所有因素。

擁塞控制依然是利用發送方維持的一個擁塞窗口(cwnd) 的狀態變量。擁塞控制窗口的大小取決於網絡的擁塞程度,並且動態變化。發送方的發送窗口取爲擁塞窗口和接收方的接受窗口中較小的一個。

在網絡層也可以使路由器採用合適的分組丟棄策略,例如 AQM(主動隊列管理) 等,以減少網絡擁塞的發生。

TCP 擁塞控制主要涉及四種算法:慢開始、擁塞避免、快重傳、快恢復。

慢開始

當最開始發送數據時,因爲不知道網絡的情況,所以不能立即注入大量的數據到網絡中,不然可能會引起網絡擁塞。較好的方法是先探測一下,由小到大逐漸增加發送窗口的大小,cwnd 的初始值是 1 ,沒經過一個傳播輪次,cwnd 就翻倍。

擁塞避免

擁塞避免聽名字就很"謹慎",當窗口大小達到一定的門限值/閾值 (ssthresh) 後,就讓擁塞窗口 cwnd 緩慢增大,每經過一個往返時間 RTT 就把發送方的 cwnd 增加 1 。

快重傳、快恢復

主要作用就是快速恢復丟失的數據包。沒有 FRR(快速重傳和恢復) ,如果數據包丟失了,TCP 會使用定時器來要求傳輸暫停;有了 FRR ,如果接收方收到一個不按順序的數據段,他會立刻給發送方發送一個重複確認,如果發送方連續收到三個重複確認,它會認爲重複確認指出的數據段丟失了,並立即重傳這些丟失的數據段,並且不會因爲重傳而要求傳輸暫停。

每當發生三次重複確認,就認爲當前爲本網絡設置的擁塞避免門限值太大了,於是 ssthresh 就重新設定爲當前窗口的一半,同時當前窗口大小也減半後,繼續執行擁塞避免算法。

如果網絡中發生發送方沒有及時接收到 ACK 確認,也就是超時的情況,則認爲在本網絡中當前發送窗口過大了,於是 ssthresh 重新設定爲當前窗口的一半,同時當前窗口大小降爲 1 ,並執行慢開始算法。

在這裏插入圖片描述

圖片出自謝希仁的《計算機網絡》第七版

當有單獨的數據包丟失時 FRR 能最有效地工作,如果短時間有很多數據包丟失 FRR 並不是很有效。(原因見上文連續 ARQ 協議)

附加題:瀏覽器輸入一個URL之後顯示主頁的過程?

PS:這是一個經典面試題,甚至在學校的計網考試中最後一道簡答題也是這個。。。
在這裏插入圖片描述

出自《圖解HTTP》

  1. 先從本地緩存中查找 URL 對應的 IP 地址,如果本地緩存沒有,會使用 DNS 協議,先從當地的根域名服務器查找對應的 IP 地址,如果沒有則去對應的頂級 DNS 服務器查找,如果還沒有則會去權威 DNS 服務器查找。

    一般具體的查詢順序是( 瀏覽器緩存,系統緩存,路由器緩存,IPS服務器緩存,根域名服務器緩存,頂級域名服務器緩存,權威域名服務器緩存 )

  2. 三次握手建立 TCP 連接。(如果需要使用 HTTPS 協議,還需要進行 TLS 四次握手協商加密套件和會話祕鑰用來實現之後的加密通信)

  3. 客戶端通過已經建立的 TCP 連接,向服務器指定端口(HTTP 80/HTTPS 443)發送 HTTP 請求。

  4. 服務器接受處理客戶端發來的 HTTP 請求,並返回 HTTP 響應報文。

  5. 客戶端根據服務端響應來的各種數據,邊解析邊渲染構建 DOM 樹、構建渲染樹等等。。。並將其繪製到屏幕上。

  6. 關閉之前建立的連接。


最後再卑微的囉嗦一句:碼字不易,如果有幫助到你請點贊關注+收藏哦!

本人菜鳥,有錯誤請告知,感激不盡!

更多題解源碼和學習筆記:githubCSDNM1ng

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