免费爱碰视频在线观看,九九精品国产屋,欧美亚洲尤物久久精品,1024在线观看视频亚洲

      《網(wǎng)絡(luò)是怎么連接的》讀書筆記 – Tcp/IP連接

      《網(wǎng)絡(luò)是怎么連接的》讀書筆記 - Tcp/IP連接

      TCP和IP協(xié)議承載了整個互聯(lián)網(wǎng)的生命線,這一章算是本書核心部分,掌握這兩個協(xié)議也是學(xué)好網(wǎng)絡(luò)編程的基礎(chǔ)。

      Socket連接

      套接字鏈接在表面上看就是建立連接,交換數(shù)據(jù),斷開連接,雖然實際上細(xì)節(jié)肯定沒有那么簡單,但是大體上的思路基本不變。

      協(xié)議棧建立連接

      這里記住一個前提:向操作系統(tǒng)內(nèi)部的協(xié)議棧發(fā)出委托時,需要按照指定的順序來調(diào)用 Socket 庫中的程序組件。

      建立Socket的協(xié)議大部分情況都是Tcp/ip協(xié)議,Socket收發(fā)數(shù)據(jù)類似在兩個主機之間建立一個無形的管道,Socket建立的關(guān)鍵是要按照指定順序調(diào)用Socket程序組件,大致的構(gòu)建順序如下:

    1. 創(chuàng)建Socket(Socket類似管道兩邊的出入口)
    2. 綁定客戶端的套接字到服務(wù)端(類似接管道)
    3. 交換數(shù)據(jù)。
    4. 斷開Socket連接,解除綁定。
    5. 轉(zhuǎn)化為具體的流程圖如下:

      創(chuàng)建Socket

      過程大致為應(yīng)用程序會把控制流程會轉(zhuǎn)移到 socket 內(nèi)部并執(zhí)行創(chuàng)建套接字的操作,完成之后控制流程又會被移交回應(yīng)用程序。

      創(chuàng)建完套接字之后,協(xié)議棧需要返回標(biāo)識符號也就是描述符用于標(biāo)識是哪一個套接字在進行傳數(shù)據(jù),因為我們可能打開很多套接字連接訪問不同的網(wǎng)站,具體的效果是我們?yōu)g覽器會打開很多個頁面,這時候每一個頁面都可能需要創(chuàng)建套接字,此時就需要識別和區(qū)分這些套接字依賴描述符。

      綁定客戶端的套接字到服務(wù)端

      連接操作核心是調(diào)用Socket的connect連接方法,此方法需要指定描述符、 服務(wù)器 IP 地址和端口號這 3 個參數(shù)。

      connect看上去挺復(fù)雜,其實本質(zhì)上就是完成連接動作而已,連接成功會把IP地址和端口號記錄到套接字上面。

      描述符在創(chuàng)建Socket的時候已經(jīng)拿到了,IP地址則是在DNS解析的步驟完成,拿到IP之后會放入到應(yīng)用程序的某個位置替換保存,而端口號則是需要應(yīng)用程序事先提供。

      端口可以簡單看作應(yīng)用程序的入口,DNS解析的IP只能知道主機在哪但是本身發(fā)往哪個應(yīng)用程序是不清楚的,我們可以想象DNS解析類似地圖上告訴我們高速的收費站坐標(biāo),但是他并不知道對應(yīng)數(shù)據(jù)送往那個閘口)。

      這里可以理解為端口就是收費站過站口,計算機會要求程序?qū)Υ龖?yīng)用程序預(yù)設(shè)明確的端口參與網(wǎng)絡(luò)交互。

      傳遞消息

      接下來的操作是調(diào)用read和write函數(shù)完成消息傳遞動作,這一步就是底層的流讀寫操作。

      斷開連接

      這一步需要簡單理解為需要一方主動發(fā)起斷開申請瀏覽器調(diào)用read收發(fā)數(shù)據(jù)同時會收到關(guān)閉請求,此時客戶端確認(rèn)請求之后將會停止請求并且開始釋放Socket連接。

      為什么不能用描述符標(biāo)識應(yīng)用程序的入口?

      描述符是和委托創(chuàng)建套接字的 應(yīng)用程序進行交互時使用的,并不是用來告訴網(wǎng)絡(luò)連接的另一方。

      客戶端也無法知道服務(wù)器上的描述符,客戶端也無法通過服務(wù)器端的描述符去確定位于服務(wù)器上的某 一個套接字?!?/p>

      Socket連接中大致介紹了協(xié)議棧是如何通過網(wǎng)卡完成和目標(biāo)服務(wù)器的連接、斷開、收發(fā)數(shù)據(jù)的過程下面按照順序講述各個步驟的細(xì)節(jié)。

      下面我們根據(jù)上面所講的各個步驟按順序進行詳細(xì)介紹。

      創(chuàng)建套接字

      首先來看一下創(chuàng)建套接字的情況,下面是協(xié)議棧的內(nèi)容。

      委托分發(fā)被拆分為好幾個部分,最上面可以看作瀏覽器,協(xié)議棧中主要有兩張協(xié)議 TCP和UDP, TCP主要是用于和服務(wù)器交互收發(fā)數(shù)據(jù)的,UDP則用于較短的控制數(shù)據(jù)。

      IP協(xié)議主要控制網(wǎng)絡(luò)收發(fā)操作,主要工作是把一個個拆分的網(wǎng)絡(luò)包發(fā)給通信的目標(biāo)對象,IP協(xié)議包括 ICMP和 ARP協(xié)議,前者告知傳輸過程的錯誤和控制信息,后者傳遞以太網(wǎng)MAC地址。

      MAC 地址:符合 IEEE 規(guī)格的局域網(wǎng)設(shè)備都使用同一格式的地址,這種地址被稱為 MAC 地址

      驅(qū)動部分是為了讓操作系統(tǒng)能正常使用硬件進行網(wǎng)絡(luò)收發(fā)的一個“適配器”,而所有的電信號最終要通過網(wǎng)卡完成。

      套接字和協(xié)議棧

      協(xié)議棧實際上是根據(jù)套接字傳遞的信息來決定做什么操作的,比如發(fā)數(shù)據(jù)要看IP和端口號。

      以Windows的套接字為例,直接在CMD中使用 netstat操作即可:

      復(fù)制代碼 隱藏代碼C:UsersXander>netstat -ano 協(xié)議 本地地址 外部地址 狀態(tài) PID TCP 0.0.0.0:49666 0.0.0.0:0 LISTENING 604 TCP 0.0.0.0:49667 0.0.0.0:0 LISTENING 1892 TCP 0.0.0.0:49668 0.0.0.0:0 LISTENING 4508 TCP 0.0.0.0:57621 0.0.0.0:0 LISTENING 22748 TCP 127.0.0.1:1001 0.0.0.0:0 LISTENING 4 TCP 127.0.0.1:1043 127.0.0.1:1061 ESTABLISHED 8452 TCP 127.0.0.1:1043 127.0.0.1:1063 ESTABLISHED 8452 UDP 192.168.159.1:1900 *:* 3060 UDP 192.168.159.1:5353 *:* 5248 UDP 192.168.159.1:58085 *:* 3060

      netstat 命令 的 ano 三個參數(shù)主要用于擴展IP地址端口以及PID的顯示,以及一些隱式的可能存在的通信也會被記錄。

      LISTENING:表示等待對方連接ESTABLISHED :表示完成連接并且進行數(shù)據(jù)通信操作

      套接字和協(xié)議棧和應(yīng)用程序的交互流程如下:

    6. 協(xié)議棧在操作套接字之前,需要事先開辟一塊空間來存放用于操作套接字的必要信息。
    7. 協(xié)議棧需要向應(yīng)用程序返回描述符表示當(dāng)前連接的是哪一個“管道”。
    8. 之后應(yīng)用程序需要和協(xié)議棧交互就必須要攜帶描述符,不過這樣也節(jié)省了協(xié)議棧了解應(yīng)用程序要和哪一個套接字交互。
    9. 連接服務(wù)器

      連接的目的是為了讓兩臺不在同一個地方的主機能夠相互認(rèn)識對方,這時候不可避免地需要互相提供自己的信息,這樣才能正確的建立連接然后使用套接字傳輸數(shù)據(jù)。

      連接的含義

      人和人之間的溝通有時候可以不使用一個語言,只要雙方都聽懂就行,但是對于計算機是行不通的。

      所以連接操作的控制信息要根據(jù)通信規(guī)則確定,協(xié)議棧在通信之前需要依靠一塊空間來存放必要數(shù)據(jù),這塊內(nèi)存空間稱為緩沖區(qū)。

      連接需要雙方各自告知自己的信息,所以連接最開始的時候是沒有任何數(shù)據(jù)交互的,由于是TCP是全雙工的協(xié)議客戶端和服務(wù)器都需要建立套接字,不過雙方不知道和誰連接,所以需要在客戶端和服務(wù)端各自開辟一塊空間來存放對方的IP和端口等必要的傳輸信息。

      為了讓雙方既可以正常通信,又可以根據(jù)自己的系統(tǒng)設(shè)計協(xié)議棧和套接字的控制信息處理方式,網(wǎng)絡(luò)通信設(shè)計采用了 控制信息的方式讓不同的計算機和系統(tǒng)能相互認(rèn)識。

      所謂的控制信息可以認(rèn)為是一種 通用語言,只要是符合這個控制信息規(guī)范的頭部信息就可以被其他的計算機認(rèn)識。

      控制信息分為兩類:

    10. 客戶端和服務(wù)器的交換的控制信息,主要用于整個通信過程,這些內(nèi)容在TCP協(xié)議進行規(guī)定。生活的例子理解是我們和別人通話之前,兩邊都得知道對方的電話號碼和基本身份。
    11. 保存在套接字中用來控制協(xié)議棧操作的信息,這些信息主要用來傳輸數(shù)據(jù),通常需要包括控制信息和數(shù)據(jù)塊,套接字需要通過控制信息了解到發(fā)來的是什么類型的數(shù)據(jù),然后協(xié)議棧才能配合處理數(shù)據(jù)。
    12. 由于在一開始傳輸?shù)臅r候是沒有具體數(shù)據(jù)的,通常是一個空的報文頭,所以這個控制信息也被叫做 協(xié)議頭部, 比如下面提到的TCP頭部,IP頭部。

      第一類:TCP 頭部格式

      第二類:套接字中的信息

      連接的實際操作

      連接的實際操作主要是調(diào)用CONNECT函數(shù),協(xié)議首先會傳遞給TCP模塊,通過TCP模塊交換獲取控制信息的頭部,以此了解具體要連接的套接字信息,然后把頭部的SYN比特設(shè)置為1,表示可以連接。

      TCP 模塊處創(chuàng)建表示連接控制信息的頭部,接著便把信息傳遞給IP模塊進行委托發(fā)送。

      三次握手

      交換頭部信息之后,接著便是常見的TCP三次握手的過程:

      • 第一步:客戶端主動打開TCB端口,服務(wù)器被動打開TCB端口。發(fā)起方攜帶一個SYN標(biāo)志,并且攜帶一個ISN序號Seq=x,但是需要注意的是第一步的過程這個ISN序號是隱藏傳遞的(因為沒有傳遞數(shù)據(jù)),因為如果請求不存在數(shù)據(jù)的交換則不會被顯示??蛻舳税l(fā)送SYN命令之后進入設(shè)置SYN=1,并且設(shè)置SYN-SENT(同步-已發(fā)送狀態(tài))。
      • 第二步:服務(wù)器收到客戶端TCP報文之后,也將SYN=1,并且回送一個新的ISN序號ack=x+1,并且將ACK=1表示自己收到了,然后在返回參數(shù)回送自己新的序列號表示自己的確認(rèn)請求Seq=y,將狀態(tài)設(shè)置為SYN-RCVD(同步收到)狀態(tài),(表示希望收到的序號為xxxx1522),最后也是指定MSS。
      • 第三步:客戶端收到服務(wù)器的確認(rèn)報文之后,還需要向服務(wù)端返回確認(rèn)報文,確認(rèn)報文的ACK=1,并且回傳服務(wù)器傳遞的ISN序號+1(ack = y+1),以及自己的ISN序號+1(Seq = x+1),此時TCP連接進入已連接狀態(tài),ACK是可以攜帶數(shù)據(jù)的,但是如果不攜帶數(shù)據(jù)則不消耗序列號。
      • 最后一步:當(dāng)服務(wù)器收到客戶端的確認(rèn),也進入已連接狀態(tài)。

      經(jīng)過三次握手連接建立,直到斷開連接之前都可以傳遞數(shù)據(jù)。

      收發(fā)數(shù)據(jù)

      收發(fā)數(shù)據(jù)有兩個重點:

      • 第一點是收發(fā)數(shù)據(jù)并不關(guān)心數(shù)據(jù)的格式,而是根據(jù)頭部信息來辨別是什么類型的數(shù)據(jù),對于協(xié)議棧來說接收的的內(nèi)容都是二進制的數(shù)據(jù)。
      • 第二點是利用緩沖區(qū)減少頻繁的數(shù)據(jù)傳輸提高傳輸效率。

      緩沖區(qū)的大小如何控制?

      • 每個數(shù)據(jù)包的數(shù)據(jù)長度,協(xié)議棧會根據(jù)一個叫作 MTU的參數(shù)來進行判斷,但是MTU指的是總長度,除開頭部信息之后獲得真實的數(shù)據(jù)長度MSS。
      • 時間,這個時間指的是固定的時間內(nèi)容不管緩沖區(qū)有有沒有達(dá)到MSS長度必須發(fā)送數(shù)據(jù)的時間,目的是防止等待時間過長造成請求延遲。

      名詞解釋:

      MTU:一個網(wǎng)絡(luò)包的最大長度,以太網(wǎng)中一般為 1500 字節(jié)。MSS:除去頭部之后,一個網(wǎng)絡(luò)包所能容納的 TCP 數(shù)據(jù)的最大長度。

      但這兩個因素實際上并不能完全決定收發(fā)數(shù)據(jù)的效率平衡,TCP協(xié)議沒有規(guī)定協(xié)議棧如何平衡,具體需要看操作系統(tǒng)如何決定。

      實際上協(xié)議棧收發(fā)數(shù)據(jù)是有所保留的,并不是強制按照協(xié)議的規(guī)定處理,而是給了應(yīng)用程序一些可控選項,比如瀏覽器這種要求實時性的應(yīng)用程序通常不使用緩沖區(qū)。Http請求拆分

      通常情況http的請求響應(yīng)內(nèi)容可以通過一個網(wǎng)絡(luò)包完成,但是針對POST請求等大表單的數(shù)據(jù)提交則通常會觸發(fā)TCP拆包操作。

      拆包是根據(jù)MSS的參數(shù)確定的,發(fā)送緩沖區(qū)會根據(jù)這個參數(shù)把一個超過一次請求長度的數(shù)據(jù)拆分為多個包,但是因為實際上同屬一份數(shù)據(jù),拆分之后所有的數(shù)據(jù)包都需要添加相同的頭部。

      注意:TCP是面向字節(jié)流的協(xié)議,就是沒有界限的一串?dāng)?shù)據(jù),本沒有“包”的概念,“粘包”和“拆包”一說是為了有助于形象地理解這兩種現(xiàn)象。

      TCP粘包

      TCP除了拆包動作之外還包含粘包的操作,所謂粘包是指TCP協(xié)議中發(fā)送方發(fā)送的若干包數(shù)據(jù)到接收方接收時粘成一個包,從接收緩沖區(qū)角度來看后一個數(shù)據(jù)的頭緊接著前一包數(shù)據(jù)的尾部。

      解決粘包、拆包問題策略?

      粘包和拆包需要解決容易造成半包讀寫的根本問題,解決辦法也有很多種,主要的策略基本很多網(wǎng)上資料都有講到,這里直接搬運結(jié)論了:

      • 請求消息定長,如果緩沖區(qū)不滿,則通過補0的方式達(dá)到長度,防止粘包和拆包。
      • 在包尾增加回車換行符進行分割,例如FTP協(xié)議;
      • 將消息分為頭部和消息體,頭部中保存整個消息的長度,只有讀取到足夠長度的消息之后才算是讀到了一個完整的消息;
      • 通過自定義協(xié)議進行粘包和拆包的處理。(幾乎不用)

      ACK號確認(rèn)網(wǎng)絡(luò)包收發(fā)

      ACK號碼除了在三次握手的過程中確認(rèn)對方是否有收到請求之外,還能作為判斷接收的數(shù)據(jù)包是否完整的依據(jù),在進行數(shù)據(jù)傳輸?shù)臅r候,接收方會將到目前為止接收到的數(shù)據(jù)長度加起來,計算出一共已經(jīng)收到了多少個字節(jié),然后將這個數(shù)值寫入 TCP頭部的 ACK 號中發(fā)送給發(fā)送方,以表示自己到底受到了多少數(shù)據(jù),如果中間存在缺少數(shù)據(jù)則服務(wù)端重新傳輸即可。

      當(dāng)然僅靠ACK號不能完全作為參考依據(jù),并且只使用ACK號是只考慮 單向傳輸?shù)那闆r,但是TCP是全雙工協(xié)議,無法確定數(shù)據(jù)接收方來自哪一方。

      解決這個問題也很簡單,實際在進行雙向數(shù)據(jù)傳輸?shù)臅r候雙方各自會額外計算一個序號,序號其實就是一組隨機數(shù),在接收方收到數(shù)據(jù)之后每次都需要把序號+1回傳給發(fā)送方表示自己接收到哪一個序號之前的所有數(shù)據(jù)。

      通過ACK+序號的方式確保數(shù)據(jù)正確傳輸,這樣可以使得其他網(wǎng)絡(luò)通信組件不需要額外的失敗補償機制,如果發(fā)現(xiàn)丟包或者數(shù)據(jù)不完整的情況,直接根據(jù)序號進行重傳重發(fā)的操作即可。

      影響數(shù)據(jù)傳輸?shù)囊蛩?/p>

      主要影響因素是返回ACK號的等待時間。

      如果ACK號遲遲沒有響應(yīng)給對方服務(wù)器,勢必會影響整個網(wǎng)絡(luò)傳輸?shù)男?,如果下一個數(shù)據(jù)已經(jīng)準(zhǔn)備好上一個返回包卻沒有發(fā)回去,很容易造成網(wǎng)絡(luò)的堵塞,對方遲遲拿不到正確結(jié)果。

      網(wǎng)絡(luò)環(huán)境的復(fù)雜多變,這個等待時間不可能是固定的,所以TCP使用了動態(tài)時間的方法進行調(diào)整,具體的調(diào)整方法就是使用滑動窗口。

      滑動窗口

      滑動窗口:指的是在不等待ACK返回結(jié)果的情況下直接雙方互相不間斷的發(fā)送數(shù)據(jù)。

      雙方需要通過各自的緩沖區(qū)順序返回ACK信息,但是如果無限制的發(fā)送數(shù)據(jù)會導(dǎo)致數(shù)據(jù)無法處理出現(xiàn)丟包,所以滑動窗口的關(guān)鍵是接收方需要告訴發(fā)送方自己最多能接收多少數(shù)據(jù)。

      滑動窗口的細(xì)節(jié)通過一張圖更好理解:

      關(guān)于接收方的接收量,最大能承受處理多少數(shù)據(jù)是通過緩沖區(qū)大小確定的。另外需要注意下面的圖只有單向的部分,實際上對于雙向來說都是類似的處理。

      影響數(shù)據(jù)傳輸?shù)拇我蛩兀悍祷?ACK號和更新窗口的時機。

      關(guān)于這一點直接記住一個結(jié)論,接收方在發(fā)送 ACK 號和窗口更新時,并不會馬上把包發(fā)送出去,而是會等待一段時間,等到其他的通知合并到一起處理,因為ACK號體現(xiàn)的是已經(jīng)收到的包的數(shù)據(jù)量,使用這樣延遲發(fā)送的方式也可以防止過多的更新數(shù)據(jù)包出現(xiàn)。

      最終協(xié)議棧收發(fā)數(shù)據(jù)的細(xì)節(jié)如下:

    13. 協(xié)議棧會根據(jù)收到的數(shù)據(jù)塊和TCP或者IP頭部解析內(nèi)容,如果確認(rèn)收到數(shù)據(jù)則返回ACK + 序號。
    14. 協(xié)議棧會把數(shù)據(jù)塊放到緩沖區(qū)進行存儲,利用滑動窗口的特性按照順序處理數(shù)據(jù)交給應(yīng)用程序處理。
    15. 協(xié)議棧會將接收到的數(shù)據(jù)復(fù)制到應(yīng)用程序指定的內(nèi)存地址中,然后將控制流程交回應(yīng)用程序
    16. 斷開連接

      斷開連接的部分包含斷開連接和刪除套接字的操作,斷開連接也就是經(jīng)典的四次揮手的操作,而刪除套接字則需要注意在協(xié)議棧中并沒有規(guī)定關(guān)閉的時間,但是通常情況下過幾分鐘之后會刪除套接字。

      四次揮手端口tcp連接

      • 第一步(客戶端):TCP發(fā)送釋放連接的報文,停止發(fā)送數(shù)據(jù),釋放報文首部,把FIN=1,同時發(fā)送序列號,根據(jù)上一次傳送的序列號+1傳送Seq = t + 1(由于下圖是在連接之后立馬進行四次揮手,所以序列號沒有變),此時客戶端進行終止等待1的狀態(tài)。注意FIN不攜帶數(shù)據(jù)也需要消耗序列號。
      • 第二步(服務(wù)端):服務(wù)器回送確認(rèn)報文,發(fā)出確認(rèn)報文,ACK=1,并且把回傳序列號+1回傳(ack = t + 1),然后再帶上自己的序列號Seq = y,此時服務(wù)端進入CLOSE-WAIT狀態(tài)(關(guān)閉等待狀態(tài)),TCP服務(wù)器此時需要停止上層應(yīng)用客戶端向服務(wù)端請求釋放,處于 半關(guān)閉 階段,此時服務(wù)端依然可以向客戶端發(fā)數(shù)據(jù)并且客戶端需要接收并處理,關(guān)閉等待狀態(tài)意味著整個狀態(tài)還需要持續(xù)一段時間。
      • 第三步(客戶端):客戶端接收到服務(wù)端確認(rèn)請求,此時客戶端進入到FIN-WAIT-2終止等待2的階段,等待服務(wù)器的釋放報文。(還有一部分服務(wù)器沒有發(fā)送完的數(shù)據(jù)需要處理)
      • 第四步(服務(wù)端):服務(wù)器把最后的數(shù)據(jù)處理完畢,向客戶端發(fā)送釋放報文,F(xiàn)IN=1,ack=t + 1,由于需要把剩下的數(shù)據(jù)發(fā)送完成,假設(shè)處理完成之后需要帶上自己的序列號Seq=w,服務(wù)器進入最后確認(rèn)狀態(tài),等待客戶端確認(rèn)。
      • 第五步(客戶端):客戶端收到報文之后,發(fā)出確認(rèn) ACK=1,ack=w+1,自己的序列號為Seq = t + 1,此時客戶端進入到了TIME-WAIT(時間等待狀態(tài)),此時客戶端還是沒有釋放,必須經(jīng)過**2 * MSL(最長報文壽命)**之后,客戶端撤掉TCB之后才進入CLOSED狀態(tài)。
      • 第六步(服務(wù)端):服務(wù)器收到客戶端的請求立馬進入CLOSE狀態(tài),同時撤銷TCB,結(jié)束此次TCP的連接。(服務(wù)端結(jié)束TCP連接要比客戶端早一些)

      套接字和協(xié)議棧和對方服務(wù)器的交互流程細(xì)節(jié)還是比較多的,這里可以發(fā)現(xiàn)實際上三次握手和四次揮手實際上只是網(wǎng)絡(luò)連接當(dāng)中很小的一部分,最后是從連接服務(wù)到數(shù)據(jù)收發(fā)到斷開連接的一張簡單總結(jié)圖,建議當(dāng)作一個大概的流程參考:

      IP和以太網(wǎng)的收發(fā)操作

      上面的部分比較貼近TCP協(xié)議的相關(guān)操作,TCP完成連接收發(fā)的同時其實都需要IP模塊的配合,在了解這兩個模塊如何配合工作之前需要了解完整的網(wǎng)絡(luò)包是如何組成的。

      包的組成

      對于任何一個網(wǎng)絡(luò)包,都有最外層的抽象概念,那就是頭部和數(shù)據(jù) 兩個部分

      上面的部分有一個這樣的圖,里面套接字中的TCP數(shù)據(jù),這里需要注意在TCP控制信息的前面就是以太網(wǎng)和IP的控制信息,對于只傳輸控制信息的網(wǎng)絡(luò)包雖然沒有數(shù)據(jù)的部分,但是可以把協(xié)議的頭部信息作為數(shù)據(jù)部分。

      通過下面的圖也可以發(fā)現(xiàn),所有的網(wǎng)絡(luò)包必須要委托以太網(wǎng)和IP控制信息才能完成傳輸。

      把存放數(shù)據(jù)的網(wǎng)絡(luò)包進行拆分,可以看到下面的TCP/IP 包結(jié)構(gòu):

      我們可以簡單把頭部和數(shù)據(jù)看做是平時的快遞,頭部是面單,指示從哪里到哪里,然后這個“快遞”會通過網(wǎng)絡(luò)轉(zhuǎn)發(fā)設(shè)備的查表操作判斷傳輸?shù)侥莻€方向。

      轉(zhuǎn)發(fā)設(shè)備是什么?這里建議看看第一章的關(guān)于認(rèn)識網(wǎng)絡(luò)傳輸?shù)幕靖拍?,這里簡單提一下:

      • 路由器根據(jù)目標(biāo)地址判斷下一個路由器的位置
      • 集線器在子網(wǎng)中將網(wǎng)絡(luò)包傳輸?shù)较乱粋€路由

      但是實際上集線器和路由器各自有不同分工,集線器負(fù)責(zé)管理以太網(wǎng)規(guī)則傳輸包設(shè)備,路由器管理IP轉(zhuǎn)發(fā)規(guī)則,所以上面兩個步驟也可以做下面的理解:

      • IP協(xié)議根據(jù)層級規(guī)則判斷下一個IP轉(zhuǎn)發(fā)設(shè)備。
      • 子網(wǎng)的以太網(wǎng)協(xié)議轉(zhuǎn)發(fā)給下一個轉(zhuǎn)發(fā)設(shè)備。

      實際上頭部部分應(yīng)該分為 MAC 頭部 和 IP頭部。為什么要把頭部拆分為兩個協(xié)議?實際上是為了讓協(xié)議之間可以實現(xiàn)替換,比如MAC可以替換為局域網(wǎng)、ADSL、FTTH。同時因為互聯(lián)網(wǎng)這樣龐大的網(wǎng)絡(luò)架構(gòu),需要更加細(xì)化的分工。

      小結(jié)

      實際上網(wǎng)絡(luò)包的封裝應(yīng)該范圍三個部分:

      第一部分是TCP模塊組織頭部信息和數(shù)據(jù)包(當(dāng)然也可能沒有數(shù)據(jù)只有控制信息)。

      第二部分是把整個TCP模塊塞到IP模塊的后面,然后經(jīng)過網(wǎng)卡發(fā)送出去。

      第三部分是在IP模塊前面加上Mac信息。

      關(guān)鍵:無論要收發(fā)的包是控制包還是數(shù)據(jù)包,IP 對各種類型的包的收發(fā)操作都是相同的。

      名詞解釋ADSL:可以理解為以前寬帶使用撥號連接互聯(lián)網(wǎng)上網(wǎng)的方式。

      非對稱數(shù)字用戶線路(英語:Asymmetric Digital Subscriber Line)又稱非對稱數(shù)字用戶環(huán)路(Asymmetric Digital Subscriber Loop),簡稱ADSL。ADSL是一個依靠銅質(zhì)電話線的數(shù)據(jù)傳輸技術(shù)比傳統(tǒng)的調(diào)制器更快。

      FTTH:其實就是現(xiàn)在的光纖通信。

      光纖到戶(英語:Fiber To The Home,縮寫:FTTH)是一種光纖通信的傳輸方法。是直接把光纖接到用戶的家中(用戶所需的地方)。

      這種光纖通信方式及策略與FTTN、FTTC、HFC(Hybrid Fiber Coaxial)等也不同,它們都是需要依賴傳統(tǒng)的金屬電線,包括雙絞線及同軸電纜等,作“最后一哩”的信息傳輸。

      IP 協(xié)議頭部

      IP類似快遞上的單號,所以實際上IP模塊是無法決定自己選擇正確的地址了,哪怕應(yīng)用程序通過TCP告訴IP發(fā)的地址式是一個錯誤地址,IP也無法自行修正只能照做。

      從這樣的特點可以看出IP頭部又有點類似快遞員,和網(wǎng)上買東西商家發(fā)錯地址或者我們填錯地址一樣,不能把責(zé)任賴在快遞員上。

      IP協(xié)議頭部的組成類似下面的結(jié)構(gòu),注意IP地址的長度固定需要32Bit的空間占用。

      這里需要注意“發(fā)送方的IP”地址不是指計算機的IP,而是指網(wǎng)卡對應(yīng)的IP,因為IP不是分配和計算機而是網(wǎng)卡的,當(dāng)一個計算機有多個網(wǎng)卡就會存在多個IP。

      那么應(yīng)該如何判斷包發(fā)送給哪一個網(wǎng)卡?這里涉及到IP協(xié)議規(guī)則,無論是路由器的轉(zhuǎn)發(fā)還是協(xié)議棧的處理都需要按照IP協(xié)議轉(zhuǎn)給下一個用戶。

      查詢分配給哪一個網(wǎng)卡在不同操作系統(tǒng)中的查詢方式不同,查詢發(fā)送端需要查詢是哪個網(wǎng)卡把包發(fā)給了路由器,這個動作只需要簡單的根據(jù)路由器IP地址和網(wǎng)卡的IP進行比對。

      在windows中可以通過命令route print查看路由信息。

      獲取IP和網(wǎng)卡之后,還需要知道包所屬的協(xié)議,委托內(nèi)容是固定的,比如TCP模塊就是06,UDP就是17,大部分請求都是HTTP,使用TCP的方式傳輸。

      以太網(wǎng)Mac頭部

      TCP/IP模塊只能在傳輸層上互相了解,但是往下的鏈路層以太網(wǎng)用同樣的規(guī)則是行不通的,所以頭部加上TCP/IP的頭部之后,還需要在頭部加上Mac頭部,Mac頭部包含了發(fā)送方和接收方的Mac信息,這里可以簡單理解為Mac和IP的作用類似,不過Mac頭部是48Bit,而IP頭部是32Bit。

      需要注意以太類型就是Mac包裝的后面的真實數(shù)據(jù)的類型, 如果是IP就是IP協(xié)議。另外需要注意在發(fā)送Mac包給接收方之前,由于不知道對方的Mac地址,所以還需要一步查詢操作。

      注意IP 模塊根據(jù)路由表 Gateway 欄的內(nèi)容判斷應(yīng)該把包發(fā)送給誰。

      下面是Mac頭部的組成:

      查詢Mac地址

      查詢對方的Mac地址需要用到ARP( Address Resolution Protocol,地址解析協(xié)議),ARP通過廣播的方法查找到目標(biāo)地址,所謂廣播就是字面意思把消息發(fā)給所有的其他互聯(lián)網(wǎng)用戶,等待對方應(yīng)答。

      為了防止每次查詢都要帶ARP的數(shù)據(jù),所以有一塊ARP的緩存專門緩存這個地址,但是需要注意這個緩存和IP模塊的IP地址一樣,過一段時間會被ARP緩存淘汰掉,但是如果IP剛剛變化可能會導(dǎo)致ARP緩存未及時更新導(dǎo)致網(wǎng)絡(luò)異常。

      實際整個工作都是由IP模塊完成的,雖然Mac地址是以太網(wǎng)數(shù)據(jù)傳輸?shù)谋匾獌?nèi)容,但是實際上讓IP模塊負(fù)責(zé)這些工作是有利的。

      為什么需要以太網(wǎng)?

      # 有了 IP 地址,為什么還要用 MAC 地址?

      以太網(wǎng)基本知識

      首先來看看以太網(wǎng)的基本發(fā)展,雖然設(shè)計結(jié)構(gòu)越來越精細(xì),但是本質(zhì)上干的活卻沒有發(fā)生變化。

      以太網(wǎng)早期原型本質(zhì)上可以看作是一根網(wǎng)線以及一個用于收發(fā)的設(shè)備,網(wǎng)絡(luò)信號發(fā)送之后通過廣播最終到達(dá)所有設(shè)備,在開頭的收發(fā)信息讓其他人可以知道信息最終要發(fā)給誰,在Mac頭部就包含了“收貨地址”,而具體發(fā)送了什么類型的可以通過上面的“以太類型”進行判斷。

      以太網(wǎng)在后續(xù)的發(fā)展中將主干網(wǎng)線替 換成了一個中繼式集線器,收發(fā)器變成雙絞線,雖然形式變了,但是本質(zhì)的工作沒有變。

      以太網(wǎng)到了現(xiàn)代最終由交換式集線器完成所有的操作,并且網(wǎng)絡(luò)請求只有請求方和接收方可以互通,集成度增加以及網(wǎng)絡(luò)傳輸安全性能增加。

      但是以太網(wǎng)無論怎么發(fā)展性質(zhì)始終沒有任何變動:

      MAC 地址代表的目的地,用發(fā)送方 MAC 地址識別發(fā)送方,用以太類型識別包的內(nèi)容。

      IP模塊轉(zhuǎn)光(或電)信號

      網(wǎng)絡(luò)信號發(fā)送依賴網(wǎng)卡,但是網(wǎng)卡并不是插上電就可以使用的,還需要依賴初始化以及驅(qū)動程序才能完成操作,驅(qū)動程序和初始化操作在其他很多電腦硬件中比較常見,但是以太網(wǎng)有比較獨特的驅(qū)動操作,那就是控制以太網(wǎng)收發(fā)操作的MAC當(dāng)中收發(fā)MAC地址。

      另外網(wǎng)卡還有一個特性是網(wǎng)卡的 ROM 中保存著全世界唯一的 MAC 地址,這是在生產(chǎn)網(wǎng)卡的時候就已經(jīng)決定。

      所以可以看到最終完成IP數(shù)據(jù)轉(zhuǎn)化的關(guān)鍵是驅(qū)動程序,網(wǎng)卡中保存的 MAC 地址會依賴網(wǎng)卡驅(qū)動程序讀取并分配給 MAC模塊。

      網(wǎng)絡(luò)包的控制信息

      MAC模塊工作在網(wǎng)卡調(diào)用MAC包發(fā)送請求命令之后,MAC模塊的工作是劃分網(wǎng)絡(luò)包的“邊界”。

      為了劃分邊界,MAC模塊會加上三個控制信息:

    17. 報頭:是一串像 10101010…這樣 1 和 0 交替出現(xiàn)的比特序列,長度為** 56 比特**,它的作用是確定包的讀取時機。
    18. 起始幀分界符(SFD):確定幀的起始位置,主要是輔助電信號切分報文頭部和真實的網(wǎng)絡(luò)包邊界,并且判斷出每個比特的界限。
    19. FCS:檢查包傳輸過程中因噪聲導(dǎo)致的波形紊亂、數(shù)據(jù)錯誤,它是一串 32 比特的序列,是通過一個公式對包中從頭到尾 的所有內(nèi)容進行計算而得出來的
    20. 響應(yīng)內(nèi)容傳輸從IP給TCP

      當(dāng)服務(wù)器接收到網(wǎng)絡(luò)包之后,首先協(xié)議棧會判斷以太網(wǎng)頭部的以太類型,發(fā)現(xiàn)是0800為TCP/IP協(xié)議,接下來是IP模塊工作,首先是檢查IP頭部是否正確,IP地址是否正確。

      如果接收方是window客戶端,因為不會對包進行轉(zhuǎn)發(fā),如果發(fā)現(xiàn)包不是發(fā)給自己的,會調(diào)用ICMP消息回傳給請求發(fā)送方,IMCP的消息格式如下:

      另外接收到的網(wǎng)絡(luò)請求可能會因為數(shù)據(jù)包過大出現(xiàn)IP分片,分片的包會在 IP 頭部的標(biāo)志字段中進行標(biāo)記,IP模塊會把分片過的包暫存內(nèi)部內(nèi)存空間,等相同ID的包全部接收到緩沖區(qū)之后再拼接。

      怎么保證拼接的順序正確呢?可以查看前文IP 頭部還有一個分片偏移量(fragment offset)字段,它 表示當(dāng)前分片在整個包中所處的位置。

      IP模塊完成數(shù)據(jù)分片重組之后,數(shù)據(jù)包交給TCP模塊操作,TCP還會再次檢查一遍請求方和接收方的IP信息,以及獲取端口號找到對應(yīng)的套接字,找到套接字之后根據(jù)應(yīng)用程序的類型進行不同的操作,這個過程可能是建立連接,也可能是完成應(yīng)用程序數(shù)據(jù)的讀寫操作。

      這里可能會覺得IP檢查不是IP模塊的操作么,TCP去看IP模塊的信息是不是“越權(quán)”了?實際上這是一種性能開銷都考慮而違反“迪米特法則(Law of Demeter)”的一種特例。因為TCP模塊需要頻繁使用IP模塊的信息,如果老是需要數(shù)據(jù)之間的交互傳輸非常影響性能。

      UDP協(xié)議收發(fā)操作

      TCP/IP為了保證數(shù)據(jù)準(zhǔn)確收發(fā)需要使用一系列復(fù)雜的模塊和過程配合保證數(shù)據(jù)的完整傳輸,但是有時候有些應(yīng)用程序為了保證高效會舍棄使用TCP這種復(fù)雜的機制。

      UDP協(xié)議的要點是盡可能將所有的數(shù)據(jù)通過一個包解決,UDP 沒有 TCP 的接收確認(rèn)、窗口等機制,因此在收發(fā)數(shù)據(jù)之前也不 需要交換控制信息。UDP的實現(xiàn)非常簡單只需要應(yīng)用程序加入頭部,直接交給IP模塊完成即可,接收方也只需要檢查IP頭部的發(fā)送方和接收方的IP地址信息,然后再從UDP找到端口號,最后再找到套接字信息把數(shù)據(jù)給應(yīng)用程序。

      因為UDP不保證傳輸?shù)姆€(wěn)定性所以無論包是否接收到都無關(guān)緊要,只要對方?jīng)]有回應(yīng)直接把包進行重發(fā)即可。這種不需要保證傳輸穩(wěn)定性的場景還是有不少的,比如聊天數(shù)據(jù)、音頻和視頻信息,即使丟失一點點也沒有關(guān)系,最多是卡頓一下而已。

      關(guān)鍵:UDP 可發(fā)送的數(shù)據(jù)最大長度為 IP 包的最大長度減去 IP 頭部和 UDP 頭部 的長度。一般來說 IP 頭部為 20 字節(jié),UDP 頭部為 8 字節(jié),因此 UDP 的最大數(shù)據(jù)長度為 65507 字節(jié)。

      下面是UDP的頭部信息:

      小結(jié)

      在第二章我們了解Socket鏈接的步驟和大致細(xì)節(jié),另外介紹了整個互聯(lián)網(wǎng)比較重要的兩個協(xié)議TCP協(xié)議和IP協(xié)議,在兩個協(xié)議中需要重點掌握頭部設(shè)計,IP模塊完成TCP模塊的數(shù)據(jù),TCP數(shù)據(jù)封裝應(yīng)用程序數(shù)據(jù),之后還需要配合Mac以太網(wǎng)模塊完成網(wǎng)絡(luò)包的最后封裝,等一切準(zhǔn)備工作完成之后,由網(wǎng)卡以及驅(qū)動程序把整個包發(fā)送出去,所以其實可以看到?jīng)Q定你能不能上網(wǎng)等實際上是網(wǎng)卡和驅(qū)動(這不是廢話),但是這些內(nèi)容屬于不同層級的內(nèi)容,需要一一消化。

      介紹了TCP之后,在在第二章最后部分簡單提到了UDP協(xié)議,UDP是一種簡單暴力的協(xié)議,設(shè)計的目的是讓所有的數(shù)據(jù)盡可能通過一個包完成,所以他不需要鏈接也不需要保證數(shù)據(jù)安全傳輸,數(shù)據(jù)丟了直接傳輸即可,UDP的應(yīng)用也是十分廣泛的,比如游戲,視頻,音樂等等數(shù)據(jù)的傳輸,很多時候丟一點根本無關(guān)緊要,因為即使找回來這些數(shù)據(jù)也沒有意義。

      TCP/IP連接也只是互聯(lián)網(wǎng)數(shù)據(jù)傳輸?shù)囊恍〔糠郑谴_實最為核心的部分,雖然往下還有以太網(wǎng)和網(wǎng)卡以及網(wǎng)絡(luò)通信如何上網(wǎng)等細(xì)節(jié),但是只有深刻了解TCP/IP協(xié)議才能了解整個互聯(lián)網(wǎng)是如何交互和數(shù)據(jù)傳輸?shù)摹?/p>

      鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
      (0)
      用戶投稿
      上一篇 2022年6月22日 21:08
      下一篇 2022年6月22日 21:09

      相關(guān)推薦

      聯(lián)系我們

      聯(lián)系郵箱:admin#wlmqw.com
      工作時間:周一至周五,10:30-18:30,節(jié)假日休息