日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

大话 TCP/IP

發布時間:2023/12/16 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 大话 TCP/IP 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

一切還要從那個經典問題出發:

當你在瀏覽器中輸入 www.google.com/ 并且按下回車之后發生了什么?

Whaaat!!! 都 9012 年了你還在問這個問題!

解析 URL,DNS 查詢,獲得服務器 IP 地址,向目標地址發送 HTTP 請求,服務器收到,響應,返回頁面,瀏覽器接收,渲染,bingo!

你露出滿意笑容,又是一個滿分回答。

停!還沒完呢。請問這位同學,你發送的請求是怎么到達目標服務器的,服務器的響應又是如何回來的?

你陷入沉默,說了一些 TCP 協議、OSI 模型、路由器之類的詞。

此時問題又來了:瀏覽器又是如何將請求發送出去的?

空氣中的沉默加深了幾分,仿佛要滴出水來······

這篇文章,我將以網絡通信常用的 TCP/IP 模型為主,解釋網絡通信涉及的各個階段,不管是常規的頁面訪問,還是我們業務中常見的 HTTP 請求,都包含在這樣的過程中,了解整體對前端開發者們很有益處。開始吧!

目錄

  • TCP/IP 參考模型是什么
  • 一次完整的網絡通信過程
  • 各個階段的深入理解
  • 一、TCP/IP參考模型是什么

    在進入具體的解釋之前,我們對 TCP/IP 協議的前世今身做一個簡單回顧。

    所謂無規矩不成方圓,網絡誕生之初,為了保證網絡通信的有序進行,相關組織開始著手制定各種通信協議,例如最早的網絡控制協議(NCP),到后來耳熟能詳的 OSI 七層協議等,整個因特網在這些協議的制約下迅速發展。事物總是發展變化的,技術自然更新換代。到上一世紀 80 年代,美國國防部的 ARPA 網(也就是阿帕網,互聯網的鼻祖)項目中,TCP、IP 協議最早被提出來得到應用,并且由于其優異性迅速成為互聯網通信的主流通用協議。

    這一協議最早得名是因為兩個最重要最先被提出的協議 TCP 和 IP,后來,互聯網通信的各類協議(HTTP、IP、DNS、TCP、ARP)整體都被納入這一協議體系中,被統稱為“TCP/IP 協議族”。

    也就是說,TCP/IP 協議族最早的確只有 TCP 和 IP 兩個協議,現在則是一系列與網絡通信有關的各類協議的集合。對應這一協議族,同時發展出了TCP/IP 參考模型,這一模型是一個抽象出來的分層模型,TCP/IP 協議族中的所有協議被歸類到這一模型的 4 個層次中,每一層相互獨立,下一層為上一層提供服務,各個層次間互相協作,完成了互聯網通信的主要工作。

    這四個層分別是:網絡訪問層(又叫數據鏈路層或者網絡接口層)網絡層傳輸層應用層,大家通常將這四個層次與更為詳細的OSI七層模型映射:

    在 TCP/IP 參考模型中,各項通信協議各有歸屬,例如我們在瀏覽器中常用的:HTTP(超文本傳輸協議)、DNS(域名系統)、FTP(文件傳輸協議)、SMTP(簡單郵件傳輸協議等)都是屬于應用層協議,而 TCP、UDP 則屬于傳輸層協議,IP 則屬于網絡層協議。更多的通信協議,大家可以搜索了解。我們這篇文章主要分析以 HTTP 為主的通信過程。

    (常見協議)

    二、一次完整的網絡通信過程

    為了對 HTTP 請求的通信過程有一個更好的理解,我將從 TCP/IP 四個層次出發,對應各個層次的通信實體,或者媒介(例如瀏覽器,路由器以及網線等),看各個協議是如何在這些通信實體中發生作用,將一個請求發送到服務器,服務器的響應又是如何趕回來的。

    整體來講,一次完整的通信,很像快遞郵遞包裹,物品被加上包裝,寫上地址信息和聯系方式,經過一個又一個的快遞中轉站,到達收貨人的位置,在網絡請求中,請求的數據就是需要快遞的物品,IP 地址和 MAC 地址就是通信的地址,網線和路由器、交換機和集線器等就是運輸道路和快遞中轉站,網絡協議則可以看做快遞員和快遞政策,而和快遞類似的是,網絡通信也會出現丟包(包裹損壞)等情況。所以說,一個簡單的 HTTP 請求,要完整地拿到請求信息,中間有若干操作系統組件、通信協議、通信實體參與,才能保證通信的順利進行。

    那么,這個快遞過程,具體是怎么進行的呢?

    其基本原則是,通過分層的順序,發送端由上往下發送,接收端則由下向上接收。為了保證數據順利發送到下一個層次,會在發送在其頭部加上一些必要的信息,這些信息是為了保證數據的完整和符合需求的約束信息。發送 HTTP 請求時,經常會設置 Request Header,例如 Content-Type:text/html 是向服務器說明,我需要的是 HTML 頁面,你返回其他東西是不行滴。

    這些頭部信息還可能包含協議信息,請求路徑、請求方法等,但這僅僅是發生在應用層,整個通信過程,經過四個層次,會被依次加上 HTTP 請求頭,TCP 頭部、IP 頭部以及以太網頭部。數據加上這些頭部信息之后,才會被發往下一層,數據經過重重包裝,從你的網卡出發,穿過若干路由器,網線,交換機,到達目標服務器所在的子網,服務器要做的則是相反的過程,它會根據前面加上的頭部信息,層層解析,最后到達服務器被處理(處理就是服務端程序代碼的責任),之后再將響應數據返回。整體過程如下圖:

    (圖片來自謝希仁版《計算機網絡》)

    數據在各個層次間依次傳遞,其傳遞的數據單位我們可以統一理解為數據包,數據包在不同的層次有不同的稱呼,我們熟悉的是,其從應用層出發時,將之稱為 HTTP 請求消息(message)或者報文,為其加上消息頭之后,發送至傳輸層,加上 TCP 頭部,叫它報文段(segment),到網絡層,加上 IP 頭部,成為 IP 數據,到了最后的網絡訪問層,其已經套上層層包裝,在這里在為其加上以太網首部的同時,還會加上一些尾部信息,搖身變為幀(framing),這個過程叫做封裝過程。不管怎么叫,數據在各個層次間,是以數據包的形式傳遞,當數據量大時,還會出現分包傳遞的情況。

    接下來我將這個過程進行擴展,看看在輸入 www.google.com/ 之后,TCP/IP 的各個層次間,前面提到的通信協議是如何參與其中的:

    三、各階段發生了什么

    1. DNS 查詢

    URL 只是為了人類更友好識別網絡程序而設置的互聯網資源的定位標識,瀏覽器首先會對 URL 進行解析,獲取到請求的協議(https),域名(google.com),路徑(/),由于沒有其他子域名,也就是查詢 google 的默認主頁。解析完畢后,DNS 出場。

    DNS,也就是域名查詢系統,負責 URL 對應的 IP 地址的查詢,每個操作系統會內置 Socket 協議庫,協議庫中有解析器(resolver)專門負責這個過程,又是一個漫長的過程(當然我們等的時間不會很長),這里不再具體展開,感興趣的同學可以看看我在文尾列出的參考資源 How DNS works,其用生動有趣的動畫形式展示了這一過程,十分有趣。

    經過 DNS 查詢,瀏覽器拿到了請求資源的 IP 地址。IP 地址,又叫網際協議地址,是分配給網絡上設備的數字標識,也就是說,只要聯網的設備,例如我們的電腦手機以及路由器等都是有 IP 地址的。其是我們的請求數據識別服務器在網絡中的位置的必須標識。

    2. Mac 地址查詢

    IP 地址在網絡層使用,但在實際的數據鏈路上傳遞數據時,在同一個鏈路中不同的計算機,其必須要使用另一個地址來識別—— Mac 地址,又叫做物理地址。

    說到這里,岔開一句,在網絡通信中,我們通常提到三個地址:IP 地址、Mac 地址以及端口號,三者分別代表的是:

    IP地址:網絡中互聯的主機和路由器的標識。 Mac 地址:每個網卡硬件的物理地址。 端口號:識別同一個主機上不同的應用程序,也可以理解為程序地址。

    所以,在一個網絡通信中,我們需要用到五大識別符:源IP地址、目標IP地址、協議、源端口號和目標端口號。

    言歸正傳,Mac 地址是每一個網卡被生產的時候就寫死在其中的,所以其是不變且唯一的,那么如何得到服務器的 Mac 地址呢,又一個協議閃亮登場——ARP。

    ARP,英文全稱叫做 Address Resolution Protocol,也就是地址解析協議,其作用是,根據IP地址獲取通信設備的物理地址,其工作原理類似于以前我們常見的廣播,它會將包發送給同一以太網的所有主機,若目標主機的 Mac 地址與對應的 IP 地址命中,則找到了目標,但是,若每次查詢都要給所有的主機發送 ARP 請求,網絡中則會出現很多 ARP 包,因此,每個主機都會有一個 ARP 緩存,里面存放著常用的 MAC 地址,主機會優先從緩存中查詢是否有需要的信息,如果有,就不再發送廣播。Mac 地址會在網絡層加入 IP 頭部發往網絡訪問層,其實你會發現,為了提高效率和性能,網絡通信中隨處可見緩存,HTTP 緩存、DNS 緩存以及 ARP 緩存等。值得了解的是,在IPv6中,有一個 NDP(鄰居發現協議)替代 ARP 來完成這個工作。

    3. 數據傳輸——套接字來幫忙

    我們前面提到操作系統中有一個協議庫,負責本機中網絡通信的很多功能,在 DNS 查詢的時候,協議棧中的解析器就參與其中,當應用層獲取到服務器的 IP 地址和 Mac 地址,已經擁有了數據傳遞的必要條件,接下來,瀏覽器會向操作系統的協議庫發出委托指令,調用其中 Socket 庫中的程序組件,建立套接字(socket),套接字的本質可以理解為一個數據通道的出入口,其執行的是一個“打開,讀/寫,關閉”的流程。

    在進行數據傳輸時,客戶端和服務器都會創建一個套接字,之后調用 socket 庫中的 connect 組件,該組件會依據描述符(套接字的匹配令符,與服務端的套接字的接頭暗號),服務器的 IP 地址和端口號,在瀏覽器和目標服務器之間建立一個傳輸通道(實際上并沒有真實的通道,中間隔著N多網關、路由器和防火墻,這樣說更好理解),而大名鼎鼎的 TCP 三次握手實際就是發生在這個階段,我們會在后面具體介紹 TCP 到底做了什么。

    通道建立之后,接下來就是數據的讀寫操作,我們的程序代碼無法直接控制套接字,它依然會委托 Socket 庫中的組件來完成數據的讀寫(write 和 read),數據傳輸完成后,服務器會主動執行斷開操作,調用 Socket 庫中的 close 組件斷開連接,瀏覽器發現之后,也會執行斷開操作,數據傳輸完成。

    可以看到,在應用程序代碼的背后,操作系統中內置的組件庫和互聯網協議互為網絡通信的左膀右臂,共同負責整個通信過程,缺一不可。

    4. 三次握手

    TCP 和 UDP 是傳輸層中的兩個主要協議,兩者的區別是:前者是面向連接的(實際就是套接字管道)、可靠的流協議,后者則并不可靠,它采取一種“盡最大努力”的傳輸策略,大家可以記住,瀏覽器、郵件等應用程序一般使用 TCP 傳遞數據,而像 DNS 查詢等較短的收發則使用 UDP。我們主要介紹 TCP。

    整體來講,之所以要在發送數據之前建立套接字,正是因為 TCP 是面向連接的傳輸協議,在傳輸協議面前,你發送的內容無關緊要,它們會將之看為一串具有一定長度的數據。

    為了保證數據傳輸的可靠,TCP 在套接字建立連接時,采用“三次握手”策略傳輸數據。

    下面是一張三次握手流程圖:

    圖中的 syn 是 Synchronize Sequence Numbers 的簡寫,也就是同步序列編號,擁有數據傳輸序列的標識。

    ack 指的是acknowledgement,表示確認。

    通俗來講,是這樣一個過程:

    第一次握手:客戶端嘗試連接服務器,向服務器發送syn包(同步序列編號),syn=j,其進入SYN_SEND 狀態等待服務器確認:我已準備好,隨時出發!

    第二次握手:服務器接收客戶端 syn 包并確認(ack=j+1),同時向客戶端發送一個 syn 包(syn=k),也即 syn + ack 包,此時服務器進入SYN_RECV 狀態:收到請求,隨時接收。

    第三次握手:客戶端收到服務器的 syn + ack 包,向服務器發送確認包 ack(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED 狀態,完成三次握手:OK,我知道了,那我們開始發送數據。

    你可能會覺得相當麻煩,確認一次就可以了嘛,收到了嗎?收到,傳輸,為什么需要三次握手呢?

    其實,為了保證數據傳輸的絕對可靠,三次確認是最少的次數,試想這樣一種情況:在第一次得到確認后,客戶端發送數據出去,但是這個數據由于中途網絡等問題,遲遲到不了服務端,服務端選擇關掉通道,但通道關閉后,剛剛的數據又跑過來了,這時候,服務端會將這個數據視為來自客戶端的新的傳輸請求,同意建立連接,而建立一個新的連接,但是,客戶端并沒有發送數據,所以,它會忽視服務端的確認,也不會回應給服務端,服務端就在傻傻滴等待,但這種等待是沒有結果的,這就造成了服務端資源的浪費。

    我在知乎上看到另外一種理解:之所以需要三次握手,本質的原因是,傳輸信道是不可靠的,你不知道網絡會在什么時候出什么樣的問題,所以,為了保證傳輸的確可靠,三次握手是理論上的最小值。

    TCP 傳輸數據時,并不是將所有數據一股腦全丟出去,而是會將數據存放在一個的發送緩沖區,并且會等待應用程序的下一段程序到達,之所以這樣干,是因為一收到數據立馬發送,很可能會造成信道的浪費與閑置,導致網絡效率太低,就像明明很寬的馬路,非要像過獨木橋一樣通過。

    而 TCP 如何決定數據什么時候會發送,其擁有一套計算機制,整體來說,是按網絡包的長度以及應用程序送包過來的時間,雖然你的數據很小,但你半天不發送,我也不會一直傻等著。

    還有一種情況是,當發送過來的數據包很大時,會在緩沖區對包進行拆分發送,拆分的時候,TCP 模塊會計算好每一塊數據的開頭和結尾的字節數,并將之寫在 TCP 頭部信息中,以待對方確認,根據這些起始序號,接收方可以判斷是否有數據遺漏的情況。

    每發送一個包,就需要等待 ack 包的確認,這也是一種資源浪費,所以為了利用等待 ack 的空閑時間,數據可以不用等待 ack 直接發送,但是,這會出現一種情況,一邊一味地發送,但超過了接收方的處理能力,就會出現網絡擁堵,得不償失。為了解決這個問題,TCP 采取了一種滑動窗口的發送策略,它的原理是這樣的:

    滑動窗口實際上是數據流量控制策略,我們可以將所有的數據想象為一個序列,而窗口則是數據可處理的數據大小,接收方會將窗口的大小寫入 ack 包的頭部信息中,告知發送方,發送方會據此動態調整發送的速率,由于傳輸的持續進行,這個窗口大小會動態變化,因此達到了流量的控制,其本質的目的是,不要發的太快,讓接收方處理不過來。

    (滑動窗口示意圖)

    接下來的路

    上面我們只提到發送和接收,但是在瀏覽器和服務器之間,可能隔著極多的網關、路由器、交換機等,數據是如何在龐大無比的因特網上找到服務器的呢?

    這就是網絡層協議的用武之地了。

    實際上,這一切在請求發送之前已經準備好了,我們使用 DNS 和 ARP 等方式,獲取到了目標服務器的 IP 地址和 Mac 地址,這兩個地址引導發送的數據包到達服務器,IP 地址用于在網絡中的所有主機中匹配通信的目標主機,IP 地址包含網絡標識主機標識,前者用于區別不同的網段,后者找到同一網段的不同主機,數據到達路由器時,路由器會根據網絡標識將數據轉發到相應的網段,到達相應的網段之后,又會根據主機號,到達真正的主機。

    說到這里,大家可能會有一個疑惑,既然 IP 地址都能找到目標服務器,為什么還需要 Mac 地址

    請容我解釋:

    在同一個網段內通信時,只用知道 Mac 地址,就可以精準找到目標,但是,互聯網上的網絡數量無比龐大,網絡被各大運營商分割為多個網段,每個網段又有多個子網,如果僅僅知道一個 Mac 地址,要在所有的網絡設備進行匹配,就是相當大的工程了,這時候,IP 地址的妙用體現出來了:它可以用來找路,這就類似于快遞中的省市地區等,而 Mac 地址可能是唯一的名字,你在全中國找一個小強的人那就太多了,但是你要具體到某一個村或小區,就很簡單了。

    另外一個原因是,交換機這個東西,只認 Mac 地址,就如同路由器根據 IP 地址決定網絡請求的轉發路線,交換機通過 Mac 地址來確定具體的網卡位置。

    路由器、交換機、網線、光纖等正是 TCP/IP 四層協議的最底層,網絡訪問層,也就是 OSI 模型中的數據鏈路層和物理層,在這一層,數據被加上以太網首部,封裝成幀,在各個路由器之間轉發傳送,經常來說,路由器之間的傳送又有常用的點對點協議,也就是PPP(Point-To-Point Protocol),這是一個網絡訪問層協議,PPP會在幀的前后加上幀界定符進行發送。最后,到達服務器所在子網,會將消息轉交網絡層向上傳遞。

    向上傳遞的過程如前所述,乃是解析頭部信息,最終到達服務器的相反過程,不再細述。

    這個過程我們可以在前面的整體過程圖清晰看到,請求數據到達服務器所在子網的路由器之后,又是一個由下而上的過程,這與客戶端發送數據基本相反,每經過一個層次,都會解析前面添加到請求數據上的多層頭部信息,交由上一層處理,在整個 TCP/IP 協議棧的幫助下,我們的請求數據終于到達了目標服務器,穿過服務器的網卡,服務器操作系統同樣有協議棧來負責找到服務端程序對應的端口,將數據交由服務端應用程序處理。

    服務器會根據我們的請求頭信息,處理返回結果,之后,請求響應信息重新出發,再次回到瀏覽器。

    瀏覽器收到請求后,經過解析、渲染過程,頁面呈現在我們面前。

    參考鏈接

  • How DNS works
  • 謝希仁《計算機網絡》
  • 戶根勤《網絡是怎樣連接的》
  • what-happens-when...
  • 通俗大白話來理解TCP協議的三次握手和四次分手
  • 轉載于:https://juejin.im/post/5d097d936fb9a07ee9587327

    總結

    以上是生活随笔為你收集整理的大话 TCP/IP的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。