網絡是如何鏈接的?網絡發展簡介(四)

從瀏覽器地址欄輸入後敲下回車,直到瀏覽器呈現信息,這個過程到底發生了什麼?前端

這一過程涉及寬帶接入、瀏覽器、前端技術,DNS,TCP/IP,操做系統,網卡,驅動程序,傳輸設備,交換機、路由器,服務器等等網絡、通訊、web相關的幾乎全部技術
本文只是宏觀上簡單的瞭解,加深本身對網絡鏈接的理解,不是大而全的技術論文
只是一個過程瞭解,閱讀須要對網絡、web有所瞭解
 
在前文中,我有上面兩幅圖, 網絡的通訊相似快遞的運輸
計算機網絡傳輸的核心是TCP/IP協議,分爲四層結構
應用層產生須要傳輸的真正數據。
傳輸層、網際層、網絡接口層由操做系統以及網卡驅動程序和物理網卡實現,負責將數據從計算機中發送出去,通過路由器(網際層)等網絡設置到達最終的目的地。
本文以發送HTTP請求以及返回響應的過程簡單介紹網絡的通訊

瀏覽器發起請求

解析URL

打開瀏覽器以後,能夠在地址欄輸入網址(或者點擊某個超連接)本質是同樣的,網址就是URL
URL是Uniform Resource Locator的縮寫,譯爲「統一資源定位符」,一般由三部分組成,協議,ip地址(或者域名)以及資源的具體目錄(第三個也能夠省略)
https是協議 ,www.cnblogs.com是域名,noteless是資源具體路徑
輸入網址,按下回車後,瀏覽器的目的就是請求這一「URL」的資源,並將解析呈現出來。
瀏覽器首先要解析URL,進一步肯定通訊協議
應用層不止一種協議,有http、ftp、file、https 等,每種協議天然有不一樣的約定方式
因此須要先肯定協議,協議是什麼?協議就是相互之間的一個約定,好比我給你一塊錢,你給我一瓶礦泉水,這就是約定,約定好了你們就按照協議進行執行。
解析URL以後,瀏覽器解析出URL給出的信息

HTTP請求

咱們輸入的網址是https協議,簡單起見以HTTP來了解
HTTP 協議定義了客戶端和服務器之間交互的消息內容和步驟,你們按照固定的步驟和格式進行通訊
根據URL能夠定位請求資源的位置,可是對於這個資源可能還有多種處理方法,好比是請求資源仍是要刪除指定資源?
因此HTTP請求也規定了方法,用於指定請求的類型
HTTP主要請求方法爲 GET  POST
 
如上圖所示,HTTP主要有兩類報文,一個是從客戶端向服務器發送請求,一個是服務器到客戶端的應答
下面就是請求和響應的格式
請求和響應都由三部分組成,首行、頭部以及實體
請求報文 中分別叫作, 請求行,請求頭,請求體
響應報文 分別叫作: 狀態行(響應行),響應頭,響應體
每一部分又都由多個字段約定了更加詳細具體的通訊規則
在瀏覽器中能夠查看到這些信息,好比chrome中查看https://www.cnblogs.com/noteless/ 的請求和響應信息
在查看工具中看的信息,爲了更加直觀,工具對原始數據進行了必定處理,因此不是上面的HTTP格式,不要奇怪
 
總之
瀏覽器將須要請求的信息,按照HTTP協議約定的格式,封裝成爲HTTP請求報文

DNS解析

HTTP請求是應用層協議,自己不具有將消息發送到網絡的功能
想要進一步進行通訊,還須要調用操做系統提供的socket接口,與服務器創建鏈接進行通訊
socket是操做系統對TCP/IP的封裝,提供應用編程接口,想要依賴socket進行通信,須要ip地址和端口號
此時,咱們僅僅知道服務器的名稱,也就是域名www.cnblogs.com
須要獲取到服務器的真實IP地址,纔可以真正的進行通訊
解析的過程:
操做系統會 先檢查本身本地的hosts文件 ,若是hosts裏沒有這個域名的映射,則查找本地DNS解析器緩存
若是hosts與本地DNS解析器緩存都沒有相應的網址映射關係,首先會找TCP/IP參數中設置的 首選DNS服務器 ,叫作本地DNS服務器
本地DNS解析器是操做系統中的DNS客戶端程序,負責DNS的解析管理
因此,以上的步驟就是
hosts文件有沒有?
操做系統的客戶端--本地DNS解析器緩存  有沒有?
尚未?去配置的DNS服務器中進行查找!
 
若是要查詢的域名,不禁本地DNS服務器區域解析
但該服務器已緩存了此網址映射關係,則調用這個IP地址映射,完成域名解析,此解析不具備權威性
 
若是本地DNS服務器本地區域文件與緩存解析都失效,則根據本地DNS服務器的設置(是否設置轉發)進行查詢
若是未用轉發模式,那麼迭代查詢
本地DNS就把請求發至 「根DNS服務器」,「根DNS服務器」收到請求後會判斷這個域名(.com)是誰來受權管理,並會返回一個負責該頂級域名服務器的一個IP。
本地DNS服務器收到IP信息後,將會聯繫負責.com域的這臺服務器。
這臺負責.com域的服務器收到請求後,若是本身沒法解析,它就會找一個管理.com域的下一級DNS服務器地址(cnblogs.com)給本地DNS服務器。
當本地DNS服務器收到這個地址後,就會找cnblogs.com域服務器,重複上面的動做,進行查詢,直至找到www.cnblogs.com主機。
 
若是用的是轉發模式,那麼遞歸查詢
此DNS服務器就會把請求轉發至上一級DNS服務器,由上一級服務器進行解析
上一級服務器若是不能解析,或找根DNS或把轉請求轉至上上級,以此循環。
 
無論本地DNS服務器是否使用轉發,最後都是把結果返回給本地DNS服務器,而後由此DNS服務器再返回給客戶機。
 
本地DNS服務器解析的過程,就是前面提到的DNS的查詢
主機到本地域名服務器的查詢是遞歸查詢
本地域名服務器的查詢過程,能夠是遞歸查詢,也能夠是迭代查詢
 
DNS解析以後就得到了請求域名的IP地址,對於HTTP請求,若是沒有設置那麼默認是80端口
若是設置的話,那麼就是使用指定的端口
端口號會設置在URL中,瀏覽器客戶端解析URL就能夠得到,不須要專門的解析
因此此時,擁有了Ip地址和端口號

socket鏈接

socket是操做系統提供的TCP/IP的薄層封裝,大大簡化了TCP/IP的使用
藉助於socket通訊的過程大體分爲下面四個過程
  1. 建立套接字
  2. 鏈接階段
  3. 通訊階段
  4. 斷開階段
web服務器會先建立套接字,而後進行監聽,等待客戶端進行鏈接
下圖是一個簡化版,簡化版,簡化版,socket鏈接請求的過程
 
socket是對TCP/IP協議的封裝,因此本質仍是TCP/IP,接下來的TCP/IP中會繼續介紹

TCP處理

tcp報文格式、字段

若是應用層的數據過大,會將數據進行分塊,每一個塊都會添加TCP頭部信息
以下圖所示
 
 
TCP協議與HTTP協議同樣,協議就是一種約定好的格式
TCP的頭部的全部字段信息,體現了TCP協議全部的功能,TCP協議模塊的實現就是對這些字段的解析使用處理
 
源端口和目的端口
各佔2個字節,分別寫入源端口號和目的端口號。
序號
序號佔4字節
序號範圍是[0, 232 - 1 ],共232(即4 294 967 296)個序號。序號增長到232-1後,下一個序號就又回到0。
也就是說,序號使用mod 232運算。
TCP是面向字節流的。在一個TCP鏈接中傳送的字節流中的每個字節都按順序編號。
確認號 
確認號 佔4字節
是指望收到對方下一個報文段的第一個數據字節的序號
若確認號=N,則代表:到序號N-1爲止的全部數據都已正確收到
確認ACK
僅當ACK=1時確認號字段纔有效。當ACK=0時,確認號無效
TCP規定,在鏈接創建後全部傳送的報文段都必須把ACK置1
 
同步SYN
在鏈接創建時用來同步序號
當SYN=1而ACK=0時,代表這是一個鏈接請求報文段。
對方若贊成創建鏈接,則應在響應的報文段中使SYN=1和ACK = 1
所以,SYN置爲1就表示這是一個鏈接請求或鏈接接受報文。
終止FIN
用來釋放一個鏈接
當FIN = I時,代表此報文段的發送方的數據己發送完畢,並要求釋放運輸鏈接

TCP三次握手

TCP運輸鏈接有三個階段:鏈接創建、數據傳送、鏈接釋放
TCP鏈接過程一般叫作 握手 ,握手須要客戶端和服務器端交換三個報文,以下圖所示
之因此須要三次握手是由於TCP是可靠傳輸,三次可以恰好可靠又很少餘
TCP三次握手與Socket的鏈接過程是相關聯對應的,Socket就是對於TCP/IP的封裝麼
客戶端有CLOSED、SYN-SEND、ESTABLISHED三種狀態
客戶端有CLOSED、LISTEN、SYN-RCVD、ESTABLISHED四種狀態
服務器會首先建立鏈接,而且進入監聽等待階段,等待客戶端的請求
當須要發送請求時,瀏覽器客戶端主動打開鏈接,而後服務器被動打開鏈接
 

鏈接過程

客戶端在須要時,向服務器發起請求鏈接報文,發出後狀態從CLOSED轉換爲SYN-SEND  同步-已發送狀態
服務器一直處於LISTEN狀態,接收到請求後,對客戶端的請求進行迴應,轉換爲SYN-RCVD,同步-已收到狀態
客戶端收到服務器的迴應後,狀態轉換爲ESTABLISHED,而且再次向服務器發送確認
服務器收到客戶端的確認以後,服務器也轉換爲ESTABLISHED狀態,完成了鏈接
發出消息或者收到消息後狀態纔會進行切換
客戶端與服務器的握手是一個往復確認的過程
客戶端:發出確認請求,SYN=1,seq=x,你聽獲得麼,我想創建鏈接(SYN=1),個人序號是x(seq=x)
服務器:對請求進行確認,也就是迴應,我聽到了(ACK=1,ack=x+1),你聽獲得麼(SYN=1),個人序號是y(seq=y)
客戶端:對服務器的迴應進行確認,我聽到了(ACK=1,ack=y+1),個人序號是x+1
 
IP數據報通過運輸層須要分段發送,因此在TCP的處理過程當中,有序號的概念
好比客戶端說我要從666號開始,發送100個數據,服務器說,我是從888號開始迴應的
上面的seq=x  和 seq=y   seq=x+1(上一個seq=x,下一個天然就是seq=x+1了)都是各自的序號
 
握手的過程就是SYN seq   ACK ack的來回確認 
SYN  ACK是頭部的字段,能夠理解爲標誌位,協議中有對他們的值有具體的規定
ack就是確認號,確認號是指望收到的對方的下一個報文段的第一個數據字節的序號,也就是收到的序號+1
不然隨便一個,怎麼對得上號

爲何要三次握手?

若是不是三次握手,只有兩次
若是客戶端發出請求鏈接時,報文延時了,因而客戶端從新發送了一次鏈接請求消息
後來收到了確認,創建了鏈接,而後完成了數據傳輸,關閉了鏈接
此時,服務器收到了那個遲到的請求消息,此時他應該是個廢物了
可是若是隻有兩次握手,服務器收到請求就響應創建了鏈接了
可是若是是三次,客戶端不會再次確認,服務器也就隨後知道了這消息有問題,不會創建鏈接

TCP四次揮手

鏈接創建之後就能夠進行數據通訊傳輸了
通訊結束後,須要斷開鏈接,斷開鏈接須要四次交互,常被稱爲 四次揮手
最初狀態均爲ESTABLISHED ,客戶端與服務器相互進行數據傳送
下圖假設客戶端無數據發送,請求斷開鏈接

斷開過程

客戶端無數據發送時,請求關閉鏈接,我好了,我想斷開鏈接了(FIN=1)個人序號是u(u就是以前傳送過的全部數據的最後一個字節的序號+1)
此時客戶端轉變爲FIN-WAIT-1狀態
服務器收到客戶端的消息後,告訴客戶端「好的,我知道了」(ACK=1,ack=u+1),這條消息的序號是v(seq=v ,這是服務器發送消息的序號)
此時服務器的狀態就轉換爲了CLOSE-WAIT狀態
 
此時,客戶端通往服務器的路就斷開了,客戶端不能向服務器發送數據
可是服務器仍舊能夠向客戶端發送數據,如今是「半關閉」的狀態
 
當客戶端收到來自服務器的確認以後,進入FIN-WAIT-2狀態,等待服務器那邊說斷開鏈接,等待中。。。。。
 
當服務器全部的數據也都徹底發送完成了以後,服務器纔開始主動告知客戶端斷開鏈接(FIN=1,seq=w)
這中間服務器可能又繼續發送了一些數據,多是v+1 也可能發送了更多,因此設置爲w
而且再次發送確認信息(ACK=1,ack=u+1,由於客戶端已經不能發送數據了,服務器指望收到的序號永遠都是最後一個序號+1,也就是u+1)
這時,服務器就進入了LAST-ACK狀態,最後確認狀態
 
客戶端收到了服務器的斷開鏈接請求後,也須要給出確認響應(ACK=1,ack=w+1,seq=u+1),而後進入TIME-WAIT狀態
等待兩個MSL後,進入關閉狀態
MSL 是Maximum Segment Lifetime英文的縮寫「報文最大生存時間」,他是任何報文在網絡上存在的最長時間,超過這個時間報文將被丟棄。
 
服務器最終收到來自客戶端的確認信息後,關閉,進入CLOSED狀態
 
四次揮手也是一個互相確認的過程,你說不玩了,別人答應了,還要等別人都搞好了再告訴你能夠走了,你才能走
客戶端:我不想玩了
服務器:好的我知道了
服務器:你能夠走了
客戶端:好的我走了
 
就如同在網吧上網,你點擊下機以後,再去網管那邊結帳
結帳清楚了以後才完全結束,而不是你說走就走了,難道你辦會員卡了麼
 
這個過程很好理解, 客戶端發出請求後,並不意味着服務器都已經完成響應
因此當客戶端請求斷開時,並不能當即斷開,還須要等待服務器那邊處理穩當,再來通知你的確是能夠斷開了
消息發出來誰知作別人收沒收到,因此還須要一個確認
 

爲何還須要等待2MSL?

爲了保證客戶端發送的最後一個確認,可以達到服務器
這個ACK可能丟失,就會致使服務器在LAST-ACK狀態,沒辦法正常結束,那麼服務器收不到就會超時重傳能夠斷開的消息
那麼A就可以在這個2MSL中收到這個重傳的消息,而且從新計時2MSL
 
並且,客戶端持續2MSL時間後斷開,就能夠保證這個鏈接的全部報文都會死亡,能夠看下MSL的含義,也就是2MSL以後,斷開這個鏈接以後,確定不會還存在這個鏈接的舊的報文了
上面說的過程雖說得是TCP的交流,可是儘管同層之間看似同層交換,可是能不用底層的協議嘛,TCP的數據也還都是要通過IP層,鏈路層、網卡、路由,同樣不缺

IP層處理

TCP 模塊在執行鏈接、收發、斷開等各階段操做時,都須要委託 IP 模塊將數據封裝成包發送給通訊對象。

關於TCP和IP的分段

咱們以前講過TCP會進行分段,IP也會進行分段,看起來有點奇怪
有兩個概念:
MTU (Maximum Transmission Unit,MTU), 最大傳輸單元 ,以太網和802.3對數據幀的長度都有一個限制,其最大值分別是1500和1492個字節
MSS (Maxitum Segment Size) 最大分段大小 ,TCP數據包每次可以傳輸的最大數據分段,每每MSS爲1460
因此說TCP分段的緣由是MSS,IP分片的緣由是MTU
對於TCP來講,MSS<MTU,因此說, 對於TCP報文,IP不須要再繼續對他進行分段了
可是IP是爲運輸層服務的,不只僅是爲了TCP,還有UDP,UDP則極可能會致使IP分段
首部由兩部分組成,分爲固定部分和可變部分(就是固定參數和可選參數的概念)
這些數據都是由操做系統組裝生成的,好比目的地址就是來源於應用程序的層層傳遞
 

ip地址與硬件地址

ip地址是網際層以及以上使用的,是一種邏輯地址,不存在物理實體,由於IP地址是用軟件實現的 ,沒有一臺機器被寫死某個IP
數據通過IP處理封裝後,數據報會交給數據鏈路層,會被封裝成MAC幀
MAC幀在傳送時,使用的是物理地址,源地址和目的地址都是硬件地址,這兩個地址被寫入MAC幀的頭部
鏈接在通訊線路上的網絡設備(主機或者路由器)在收到MAC幀以後,根據MAC幀首部的硬件地址決定收下或者丟棄。
總之,IP地址保存在IP數據報的首部,MAC地址保存在MAC數據報的首部
網際層以及網際層以上使用IP地址,數據鏈路層以及如下使用硬件地址
硬件地址就是網卡的地址,任何一塊網卡,都有一個惟一的物理地址,這就是MAC地址,因此叫作硬件地址,由於是被寫死固化在網卡中的
一個網卡就有一個MAC地址,若是計算機中安裝多個網卡,那麼就會有多個MAC地址
 
既然有了IP爲何還要使用MAC?或者說有了MAC爲何還須要IP呢?
IP層關注的是網際層的傳輸,可是具體的數據傳輸必然沒法脫離具體的物理線路以及組網環境
IP地址是根據網絡的拓撲結構分配的,因此根據IP能夠實現高效的路由選擇
物理地址跟網絡拓撲結構沒有任何關係,顯然不適合用來路由選擇,並且,若是物理地址跟網絡拓撲創建了關聯
那麼,對於設備的更換,或者網卡的更換,將會增長難度
並且,實際的物理組網環境多變複雜,因此纔會分爲網際層和網絡接口層,因此纔會同時使用IP地址和MAC地址
IP地址能夠實現高效的路由選擇,MAC地址實現相鄰鏈路間的數據傳送
應用層經過藉助於操做系統的DNS解析能夠得到接收方的IP地址,操做系統也知道本機的IP地址
那麼如何肯定目的MAC?
答案是 經過路由表這是操做系統實現的功能,其實也仍是藉助於各類協議來生成的,說白了就是計算規則,先找到下一個中轉設備的IP地址
而後再借助於ARP協議 ,查詢MAC地址
 
在windows下能夠經過命令 route print查看

路由表是怎麼來的?

有幾種常見的路由選擇協議,路由選擇協議的核心就是路由選擇算法
互聯網採用分層次的路由選擇協議
由於互聯網的規模自己很是大,不可能讓全部的路由都知道全部的網絡怎麼到達,這是不現實的
另外自己不少單位,並不但願外界瞭解本身內部的路由選擇協議以及網絡佈局細節
因此互聯網被劃分爲了多個 自治系統(autonomous system AS)
其實仍是分片管理,區域自治的思想
在目前的互聯網中,一個ISP就是一個自治系統,這樣互聯網的路由選擇協議就分爲兩大類
一個是AS內部,一個是AS與AS之間
內部網關協議IGP   Interior Gateway Protocol,AS內部使用的路由選擇協議,目前主要是RIP和OSPF
外部網關協議EGP  External Gateway Protocol,兩個AS之間相互聯繫時使用的協議,目前是BGP-4(版本4)
自治系統之間的又叫作 域間路由選擇 ,自治系統內部的路由選擇叫作 域內路由選擇
路由選擇協議是一個自學習的過程,經過相互之間的信息互換最終造成了路由表
想要了解具體的學習過程能夠查看路由選擇協議的相關資料
路由表怎麼使用?
 
網絡目標(destination)  目的地網段
網絡掩碼(mask)子網掩碼
網關(gateway)下一跳路由器入口的ip
若是是本地計算機直接鏈接到的網絡,網關一般是本地計算機對應的網絡接口,可是此時接口必須和網關一致;
若是是遠程網絡或默認路由,網關一般是本地計算機所鏈接到的網絡上的某個服務器或路由器
接口(interface)  接口定義了針對特定的網絡目的地址,本地計算機用於發送數據包的網絡接口
躍點數(metric)  可理解爲跳數表示該條路由記錄的質量通常狀況下,若是有多條到達相同目的地的路由記錄路由器會採用metric值小的那條路由
 
簡單說就是在「網絡目標「裏面查找匹配,匹配到了就使用」接口「 發往」網關「。
網絡目標0.0.0.0  表示默認路由,也叫作缺省路由,若是路由表匹配不到則經過這一條記錄執行
127.0.0.0  表示環回地址,系統將接收發送給該網段的全部數據包
 
總之,經過這個路由表
咱們就可以獲得想要發送到目的地IP,下一跳的IP地址是什麼,以及網絡接口的IP地址,也就是發送方的IP地址

下一跳的IP地址有什麼用?

有了下一跳IP地址,咱們就能夠查找他的物理地址,這樣就能夠得到下一個設備的MAC地址了
如何根據IP地址查詢MAC地址呢?
答案是經過ARP協議
ARP 地址解析協議Address Resolution Protocol
網絡層使用的是IP地址,但在實際網絡的鏈路上傳送數據幀時,最終仍是必須使用該網絡的硬件地址。
但IP地址和下面的網絡的硬件地址之間因爲格式不一樣而不存在簡單的映射關係 (例如,IP地址有32位,而局域網的硬件地址是48位),也就是說沒辦法單純的像個文件同樣一一對應,或者寫死的那種
此外,在一個網絡上可能常常會有新的主機加入進來,或撤走一些主機
更換網絡適配器也會使主機的硬件地址改變
地址解析協議ARP解決這個問題的方法是:
在主機ARP高速緩存中存放一個從IP地址到硬件地址的映射表,而且這個映射表還常常動態更新(新增或超時刪除)。
每一臺主機都設有一個ARP高速緩存(ARP cache),裏面有本局域網上的各主機和路由器的IP地址到硬件地址的映射表
假設須要查找主機B,IP地址爲X,B可能新來的,也可能主機纔開始運行,緩存爲空,總之,沒有差找不到IP地址爲X的主機B的信息
首先 ,ARP在局域網上 廣播發送ARP請求分組
大體內容是:「個人IP地址是XXX,個人MAC地址是YYY,我想找IP地址爲ZZZ的主機收到請回答
而後 局域網內全部運行ARP的主機都會收到這個請求
最後 主機B的IP地址就是請求中要查詢的主機,因此會應答,其餘人則不理睬這個請求,由於不是找他們的
ARP請求是廣播,這個響應就是普通的單播了
此時一旦收到了響應就獲得主機B IP地址爲X的物理地址了
 
因爲是IP協議使用了ARP協議,所以一般就把ARP協議劃歸網際層
但ARP協議的用途是爲了從網絡層使用的IP地址,解析出在數據鏈路層使用的硬件地址。因此有的書又說是鏈路層
此時通過路由表和ARP協議咱們得到了目的MAC地址
 
IP 生成的網絡包只是存放在內存中的一串數字信息,沒有辦法直接發送給對方
接下來就是數據鏈路層的相關職責,數據鏈路層屬於計算機網絡的低層
數據鏈路層使用的信道主要有如下兩種類型:
點對點信道 這種信道使用一對一的點對點通訊方式。使用的協議有ppp點對點協議
廣播信道 這種信道使用一對多的廣播通訊方式,所以過程比較複雜
廣播信道上鍊接的主機不少,所以必須使用專用的共享信道協議來協調這些主機的數據發送。
廣播信道能夠進行一對多的通訊,局域網使用的就是廣播信道
以太網(Ethernet)是一種計算機局域網技術規範,以太網是目前應用最廣泛的局域網技術,他可不是某種具體的網絡
 
因此接下來就是藉助鏈路層處理封裝成幀進行傳輸了
 

鏈路層處理

計算機與外界局域網的鏈接是經過通訊適配器(adapter)進行的,也就是網卡
網卡上裝有RAM和ROM
適配器和局域網之間的通訊是經過電纜或者雙絞線串行傳輸方式通訊
適配器和操做系統之間的通訊是經過主板上的IO總線並行傳輸的
網卡的正確運行還須要操做系統安裝 網卡驅動程序
他們掌管着應當從存儲器的什麼位置上把多長的數據塊發送到局域網
或者應當在存儲器的什麼位置上把局域網傳送過來的數據塊存儲下來
還要可以實現以太網協議
 
適配器在接收和發送各類幀時,不使用計算機的CPU,這時計算機中的CPU能夠處理其餘任務。
當適配器 收到有差錯的幀時,就把這個幀直接丟棄 而沒必要通知計算機。
當適配器 收到正確的幀時,它就使用中斷來通知該計算機 ,並交付協議棧中的網絡層。
當計算機要發送IP數據報時,就由協議棧把IP數據報向下交給適配器,組裝成幀後發送到局域網。
網卡驅動程序部分就是實現鏈路層的相關協議的實體
 
數據鏈路層協議有許多種,但有三個基本問題則是共同的。
這三個基本問題是: 封裝成幀、透明傳輸和差錯檢測
封裝成幀
封裝成幀((framing)就是在一段數據的先後分別添加首部和尾部,這樣就構成了一個幀。
接收端在收到物理層上交的比特流後,就能根據首部和尾部的標記,從收到的比特流中識別幀的開始和結束。
透明傳輸
「透明」 它表示:某一個實際存在的事物看起來卻好像不存在同樣
「在數據鏈路層透明傳送數據」表示不管什麼樣的比特組合的數據,都可以按照原樣沒有差錯地經過這個數據鏈路層
所以,對所傳送的數據來講,這些數據就「看不見」數據鏈路層有什麼妨礙數據傳輸的東西。或者說,數據鏈路層對這些數據來講是透明的。
使用專門的控制字符,若是出現控制字符則插入轉義字符,這種方法被稱爲 字節填充
差錯檢測
現實的通訊鏈路都不會是理想的,這就是說,比特在傳輸過程當中可能會產生差錯
1可能會變成0,而0也可能變成1。這就叫作比特差錯。比特差錯是傳輸差錯中的一種  
目前在數據鏈路層普遍使用了循環冗餘檢驗CRC (Cyclic Redundancy Check)的檢錯技術。
 
經常使用的以太網MAC幀格式有兩種標準,一種是DIX Ethernet V2標準(即以太網V2標準),另外一種是IEEE的802.3標準。
 
 
 
就這樣,通過驅動程序和網卡,數據就被從TCP層再到IP層再到鏈路層再到物理層完成了數據從計算機端口的輸出
 
注意,以上TCP、IP、鏈路層的處理,都是由操做系統以及網卡驅動程序按照TCP/IP的協議以及以太網等相關技術實現的
上面各個模塊功能的劃分描述只是大體的通常性的
操做系統到底實現到協議的哪一部分以及網卡驅動到底實現到哪一部分的細節,徹底由實現決定

數據轉發接收

數據從應用層,通過操做系統和網卡驅動程序對協議棧的實現,在通過網卡轉換爲廣電信號從網口發送出去
接下來就是藉助於網絡設備進行數據傳送
設備主要是交換機、路由器。不過如今路由器都集成了這幾個的功能
可是本質是同樣的,能夠理解爲網絡設備傳輸須要某些功能,而這幾種功能經過交換機、路由器實現了
隨着技術發展,設備的功能集成度很高,家用路由器都集成了這些功能
也有三層交換機,實現了轉發和路由的功能
因此,根本是咱們要理解交換機、路由器這幾個設備的功能點,從而瞭解數據處理過程,究竟是個什麼設備咱們能夠不用關心
先了解下發展,最初的設備是 集線器
集線器的英文稱爲「Hub」。「Hub」是「中心」的意思, 集線器的主要功能是對接收到的信號進行再生整形放大,以擴大網絡的傳輸距離
集線器屬於物理層設備 ,與網卡、網線等傳輸介質同樣,屬於局域網中的基礎設備, 集線器(hub)屬於純硬件網絡底層設備
因爲集線器會把收到的任何數字信號,通過再生或放大,收到1就轉發1,收到0就轉發0
從集線器的全部端口提交,這會形成信號之間碰撞的機會很大
並且 集線器不進行碰撞檢測,若兩個接口同時有信號輸入(即發生碰撞),那麼全部的接口都將收不到正確的幀
並且 信號也可能被竊聽 ,而且這表明全部連到集線器的設備,都是屬於同一個碰撞域名以及廣播域名,所以大部份集線器已被交換機取代。
組建局域網能夠用集線器,也能夠用交換機。經過集線器鏈接的一組工做站同屬一個衝突域,也同屬一個廣播域
 
爲了可以具備更高性能的擴展以太網,出現了 網橋 網橋對收到的幀根據其MAC幀的目的地址進行轉發和過濾。
網橋收到一個幀時,並非向全部的接口轉發此幀
而是根據此幀的目的MAC地址,查找網橋中的地址表,而後肯定將該幀轉發到哪個接口,或者是把它丟棄(即過濾)
 
再後來又出現了 交換機 (二層交換機),核心與網橋差很少,可是改進了不少,反正 交換機是網橋的進化版本就是了
交換機也被稱爲 多接口的網橋
以太網的交換機的每一個接口都直接與一臺主機或者另外一個以太網交換機鏈接,而且是 全雙工模式
全雙工就比如雙向兩車道(兩個方向能夠同時進行),若是其中一條道堵上了,被堵方向的車輛就須要借道,雙方交替,某一瞬間只能有一輛車經過,這就是半雙工。
並且,以太網還具備並行性,即同時聯通多接口,使多對主機同時進行通訊(網橋只能一次分析和轉發一個幀)相互通訊的主機都是獨佔傳輸媒體,無碰撞的進行數據傳輸。
交換機根據MAC地址轉發是藉助於內部的交換表,是經過自學習算法自動的創建起來的
交換機使用專用的交換芯片,用硬件轉發,其轉發效率比用軟件轉發的網橋快不少

交換表是如何學習的?

假設最開始是空的,當A發送數據給B時,從1進入,交換機將A,1 記錄在表中
此時交換機不知道要送到哪裏,因此廣播(轉發到除了入口以外的全部端口),C,D會丟棄,B會接收到
B要發送給A時,從3進入,交換機將B,3記錄在表中,查表獲得A的端口1,因此從1轉發出去
只要通過這樣的步驟,只要C,D也發送數據,那麼就最終會將全部主機的地址與端口進行匹配,就獲得了完整的交換表
 
表中的 數據都是有時效性的 ,過時的條目會被自動刪除,因此能夠很方便的更換主機,哪怕主機更換網卡
 
不過這個自學習的過程,某種條件下會產生問題,可能會成環
假如,最開始A經過1 向B發送一幀,交換機1#廣播,假設3收到後發送到交換機2#的1號口,而後再到2號口,造成了環裝,浪費了資源
爲了解決這種問題,有一個協議 生成樹協議STP Spanning Tree Protocol,主要就是爲了 不改變網絡拓撲結構的狀況下,切段環形
 
若是交換機收到的目的地址就是源端口地址,會簡單的丟棄包
由於A發出後,通過集線器會發送給B,若是交換機再將這個包返回,達到集線器以後,會再次的發送給A和B,這是有問題的
此外,若是接收方MAC地址是一個廣播地址 A,那麼交換機會將包發送到除源端口以外的全部端口。
 
網橋和交換機用於分割衝突域
衝突域簡單理解就是鏈接在一塊的節點的集合,集線器鏈接的全部節點,就是一個衝突域,由於他不作任何區分,全部的數據都廣播發到全部節點
網橋和交換機工做在鏈路層,會根據MAC地址進行轉發,因此能夠分割衝突域 ,減小了沒必要要的廣播數據,讓網絡通道舒服了一些
 
路由器是一種具備多個輸入端口和多個輸出端口的專用計算機,其任務是轉發分組
從路由器某個輸入端口收到的分組,按照分組要去的目的地(即目的網絡),把該分組從路由器的某個合適的輸出端口轉發給下一跳路由器
下一跳路由器也按照這種方法處理分組,直到該分組到達終點爲止。路由器的轉發分組正是網絡層的主要工做

路由器的結構

路由器包括 轉發模塊 端口模塊 兩部分
路由器的行爲和交換機是相似的,只不過路由器工做在網絡層,處理的是IP
路由器的端口的硬件將包接收進來
接下來,轉發模塊會根據接收到的包的 IP 頭部中記錄的接收方 IP 地址,在路由表中進行查詢,以此判斷轉發目標。
而後,轉發模塊將包轉移到轉發目標對應的端口,端口再按照硬件的規則將包發送出去
路由器的端口具備MAC 地址,因此他能夠做爲以太網的接收方和發送方,端口還具備 IP 地址
首先路由器端口會接收發給本身的以太網包,而後查詢轉發目標,再由相應的端口做爲發送方將以太網包發送出去
這一點和交換機是不一樣的,交換機只是將進來的包轉發出去而已,它本身並不會成爲發送方或者接收方
須要記住:路由器的各個端口都具備 MAC地址和 IP 地址
交換機在地址表中只匹配徹底一致的記錄,而路由器則會忽略主機號部分,只匹配網絡號部分
這涉及到子網劃分,總之路由器只看網絡號,不關注具體的門牌號,負責到小區,這也是路由表中爲什麼有子網掩碼的信息,由於路由器須要知道網絡號的位數
路由器中的路由表和上面計算機操做系統中的路由表是一個概念 ,邏輯思路也是同樣的
只不過具體實現確定不一樣(操做系統的代碼跟路由器的代碼怎麼可能同樣)
 
對路由表進行維護的方法有幾種,大致上可分爲如下兩類。
  1. 由人手動維護路由記錄
  2. 根據路由協議機制,經過路由器之間的信息交換由路由器自行維護路由表的記錄
其中 2 中提到的路由協議有不少種,例如RIP、OSPC、BGP 等都屬於路由協議
 
路由表記錄維護的方式和交換機也有所不一樣
交換機中對 MAC 地址表的維護是包轉發操做中的一個步驟
而路由器中對路由表的維護是與包轉發操做相互獨立的,也就是說,在轉發包的過程當中不須要對路由表的內容進行維護。
前面講到的交換機會在轉發時記錄端口與mac,路由器進行分租轉發過程當中不會作相似的事情

路由器處理過程

再次梳理下路由器的處理過程:
首先信號到達網線接口部分,而後經過網卡將信號轉換爲數字信息
而後經過包末尾的 FCS 進行 錯誤校驗 ,若是沒問題則 檢查 MAC 頭部 中的接收方 MAC 地址
確認是否發給本身的包,若是是就放到接收緩衝區中,不然就丟棄這個包。 
路由器的端口都具備MAC地址,只接收與自身地址匹配的包,遇到不匹配的包則直接丟棄。
計算機網卡對數據的接收也是這樣子的,網卡和驅動程序負責了這部份內容
 
而後,完成包接收操做以後,路由器就會丟棄包開頭的 MAC 頭部。
由於MAC 頭部的做用就是將包送達路由器,完成這一段鏈路上數據的傳送,若是這個下一站是路由器,那麼其中的接收方 MAC 地址就是路由器端口的 MAC 地址。
所以,當包到達路由器以後,MAC 頭部的任務就完成了,因而 MAC頭部就會被丟棄。
 
接下來路由器會根據 IP 頭部中的內容進行包的轉發操做
轉發操做分爲幾個階段,首先是查詢路由表判斷轉發目標
路由器根據路由表進行匹配的時候, 路由器首先尋找網絡號比特數最長的一條記錄
由於網絡號比特數越長,說明主機號比特數越短,也就意味着該子網內可分配的主機數量越少,即子網中可能存在的主機數量越少
這一 規則的目的是儘可能縮小範圍 ,因此根據這條記錄判斷的轉發目標就會更加準確
 
若是路由器發送出現問題,路由器會丟棄這個包,並經過ICMP 消息告知發送方主機。
這裏的處理方式和交換機不一樣, 緣由在於網絡規模的大小。
交換機鏈接的網絡最多也就是幾千臺設備的規模,遇到不知道應該轉發到哪裏的包
交換機能夠將包發送到全部的端口上,雖然這個方法很簡單粗暴,但不會引起什麼大問題。
但是,路由器工做的網絡環境就是互聯網,它的規模是遠遠大於以太網的,因此不能將包發送到整個網絡上,那就會產生大量的網絡包,形成網絡擁塞。
所以,路由器遇到不知道該轉發到哪裏的包,就會直接丟棄。
ICMP
爲了更有效地轉發IP數據報和提升交付成功的機會,在網際層使用了 網際控制報文協議ICMP (Internet Control Message Protocol)
ICMP容許主機或路由器報告差錯狀況和提供有關異常狀況的報告。
ICMP是互聯網的標準協議。
但ICMP不是高層協議(看起來好像是高層協議,由於ICMP報文是裝在IP數據報中,做爲其中的數據部分),而是IP層的協議。
ICMP報文做爲IP層數據報的數據,加上數據報的首部,組成IP數據報發送出去。

下一步的前置處理

路由器的轉發與計算機操做系統中IP實現模塊的工做核心點是同樣的,他們都是負責交付IP數據報
路由器從路由表中查詢到轉發目標以後,數據包會轉發給指定的端口
在此以前還須要作一系列的處理
TTL
第一個工做是更新 IP 頭部中的 TTL(Time to Live,生存時間)字段
TTL 字段表示包的有效期,包每通過一個路由器的轉發,這個值就會減 1,當這個值變成 0 時,就表示超過了有效期,這個包就會被丟棄,防止死循環永遠發送。
分片
路由器的端口並不僅有以太網一種,也能夠支持其餘局域網或專線通訊技術。
不一樣的線路和局域網類型各自能傳輸的最大包長度也不一樣,所以輸出端口的最大包長度可能會小於輸入端口。
即使兩個端口的最大包長度相同,也可能會由於添加了一些頭部數據而致使包的實際長度發生變化,ADSL、FTTH 等寬帶接入技術中使用的 PPPoEB 協議就屬於這種狀況。
不管哪一種狀況,一旦轉發的包長度超過了輸出端口能傳輸的最大長度,就沒法直接發送這個包了。
遇到這種狀況,可使用 IP 協議中定義的分片功能對包進行拆分,縮短每一個包的長度。
查詢物理地址
與計算機操做系統的處理相似,知道了目標地址,能夠根據ARP協議查詢目的MAC
路由器的端口也具備網卡,具備MAC以及IP,因此就是網卡負責鏈路層幀的封裝以及光電信號的轉換,而後發送
就是這樣一段一段,就像快遞同樣,就到達了最終的目的地
 
IP(路由器)負責將包發送給通訊對象這一總體過程,而其中將包傳輸到下一個路由器的過程則是由以太網(交換機)來負責的。
整個傳輸過程當中,目的IP並不會發生變化
雖然咱們經過路由表查找下一跳的IP地址,可是是爲了查詢下一個設備的物理地址,進而藉助於以太網進行發送
下一跳的IP地址並不存在與傳輸線路上,傳輸線路上一直都是目的IP,而以太網的源MAC和目的MAC倒是一直在變化的
因此說,IP負責包發送給通訊對象這一總體過程,以太網交換機負責將包傳輸到下一個路由器。
爲何要分IP層和鏈路層?
網絡並不是只有以太網一種,還有無線局域網,以及接入互聯網的通訊線路,它們和 IP 之間的關係又是什麼樣的呢?
其實只要將以太網替換成無線局域網、互聯網線路等通訊規格就能夠了。
也就是說,若是和下一個路由器之間是經過無線局域網鏈接的,那麼就委託無線局域網將包傳輸過去;
若是是經過互聯網線路鏈接的,那麼就委託它將包傳輸過去。
除了這裏列舉的例子以外,世界上還有不少其餘類型的通訊技術,它們之間的關係也是同樣的,都是委託所使用的通訊技術將包傳輸過去。
IP 自己不負責包的傳輸,而是委託各類通訊技術將包傳輸到下一個路由器,這樣的設計是有重要意義的,便可以根據須要靈活運用各類通訊技術,這也是 IP 的最大特色。正是有了這一特色,咱們纔可以構建出互聯網這一規模巨大的網絡
因此這一點再次的看出來,爲何網絡的通訊模型採用分層次的結構設計,經過層次的設計,IP層就專職負責總體交付就行了
每一層都可以獨立發展,運用最合適的技術。

數據的接收

從網卡到操做系統     

計算機數據的一部分接收過程與路由器邏輯是如出一轍的
經過網線的光/電信號,達到計算機的網口, 轉換爲數字信號
會經過包的 幀校驗序列(FCS) 來校驗錯誤,若是是錯誤的也會丟棄
當 FCS 一致,即確認數據沒有錯誤時,接下來須要 檢查 MAC 頭部 中的接收方 MAC 地址,若是是發給本身的,就緩存下來,通知操做系統進行處理
路由器此時的處理是丟掉MAC頭部,而後解析IP數據報信息,而後會查找轉發表開始準備轉發了
而咱們的計算機操做系統做爲最終目的地,固然再也不須要轉發,會根據收到的MAC數據進行處理
 
網卡每收到一個MAC幀就先用硬件檢查MAC幀中的目的地址。
若是是發往本站的幀則收下,而後再進行其餘的處理。不然就將此幀丟棄,再也不進行其餘的處理 。這樣作就不浪費主機的處理機和內存資源。
這裏「發往本站的幀」包括如下三種幀:
    (1)單播(unicast)幀(一對一),即收到的幀的MAC地址與本站的硬件地址相同。
    (2)廣播(broadcast)幀(一對全體),即發送給本局域網上全部站點的幀(全1地址)。
    (3)多播(multicast)幀(一對多),即發送給本局域網上一部分站點的幀。
    全部的適配器都至少應當可以識別前兩種幀,即可以識別單播和廣播地址。有的適配器可用編程方法識別多播地址。
當操做系統啓動時,它就把適配器初始化,使適配器可以識別某些多播地址。顯然,只有目的地址才能使用廣播地址和多播地址。
 
網卡須要經過中斷將網絡包到達的事件通知給 CPU以後,接下來,CPU 就會暫停當前的工做,並切換到網卡的任務。
而後,網卡驅動會開始運行,從網卡緩衝區中將接收到的包讀取出來,根據 MAC頭部的以太類型字段判斷協議的種類,並調用負責處理該協議的軟件。
這裏,以太類型的值應該是表示 IP 協議,所以會調用 TCP/IP 協議棧,並將包轉交給它。
 
簡言之
網卡接收到數據以後,產生中斷,彙報操做系統,操做系統過來讀取數據,根據類型交給指定的協議棧實現部分
至此,數據已經從另外一端達到了目的地計算機了

IP模塊接收

當網絡包轉交到協議棧時,IP 模塊會首先開始工做, 檢查 IP 頭部
IP模塊首先會檢查 IP 頭部的格式是否符合規範,而後檢查接收方 IP 地址,看包是否是發給本身的
確認包是發給本身的以後, 接下來須要 檢查包有沒有被分片 
檢查 IP頭部的內容就能夠知道是否分片,若是是分片的包,則將包暫時存放在內存中,等全部分片所有到達以後將分片組裝起來還原成原始包;
若是沒有分片,則直接保留接收時的樣子,不須要進行重組。
到這裏,咱們就完成了包的接收。
 
IP是對運輸層負責的,運輸層也就是TCP或者UDP
因此接下來須要 檢查 IP 頭部的協議號字段,並將包轉交給相應的模塊
例如,若是協議號爲06(十六進制),則將包轉交給 TCP 模塊;若是是 11(十六進制),則轉交給 UDP 模塊。
 
簡言之
協議棧的IP模塊會檢查IP頭部,(1)    判斷是否是發給本身的;(2)    判斷網絡包是否通過分片;(3)    將包轉交給TCP模塊或UDP模塊。

TCP模塊接收-鏈接

  TCP 頭部中的控制位 SYN 爲 1 時,表示這是一個發起鏈接的包
這時,TCP 模塊會執行接受鏈接的操做
不過在此以前,須要先 檢查包的接收方端口號 ,並確認在該端口上有沒有與接收方端口號相同且正在處於等待鏈接狀態的套接字。
若是指定端口號沒有等待鏈接的套接字,則向客戶端返回錯誤通知的包。
 
若是存在等待鏈接的套接字,則爲這個套接字複製一個新的副本 ,並將發送方 IP 地址、端口號、序號初始值、窗口大小等必要的參數寫入這個套接字中
同時分配用於發送緩衝區和接收緩衝區的內存空間。
而後生成表明接收確認的 ACK 號 ,用於從服務器向客戶端發送數據的序號初始值,表示接收緩衝區剩餘容量的窗口大小,並用這些信息生成 TCP 頭部,委託IP 模塊發送給客戶端 。
這不就是上面說過的TCP的三次握手嘛,這是其中的第二步,收到「TCP 頭部中的控制位 SYN 爲 1 時」是第一步
這個包到達客戶端以後,客戶端會返回表示接收確認的 ACK 號,當這個ACK 號返回服務器後,鏈接操做就完成了

TCP模塊接收-傳輸

而後就是數據的傳送階段了
數據包重複着上面的過程,TCP 模塊會檢查收到的包對應哪個鏈接
在服務器端,可能有多個已鏈接的套接字對應同一個端口號,所以僅根據接收方端口號沒法找到特定的套接字。
這時咱們須要根據 IP 頭部中的發送方 IP 地址和接收方 IP 地址,以及 TCP 頭部中的接收方端口號和發送方端口號共 4 種信息,找到上述4 種信息所有匹配的套接字。
簡言之,發送方 IP 地址和接收方 IP,發送方端口和接收方端口惟一肯定一條鏈接 (另外其實包含協議,應該是五個肯定一條鏈接)
找到 4 種信息所有匹配的套接字以後,TCP 模塊會對比該套接字中保存的數據收發狀態和收到的包的 TCP 頭部中的信息是否匹配,以肯定數據收發操做是否正常。
具體來講,就是根據保存的上一個序號和數據長度計算下一個序號
並檢查與收到的包的 TCP 頭部中的序號是否一致 。若是二者一致,就說明包正常到達了服務器,沒有丟失。
這時,TCP模塊會從包中提出數據,並存放到接收緩衝區中,與上次收到的數據塊鏈接起來。這樣一來,數據就被還原成分包以前的狀態了。
 
當收到的數據進入接收緩衝區後,TCP 模塊就會生成確認應答的 TCP頭部,並根據接收包的序號和數據長度計算出 ACK 號,而後委託 IP 模塊發送給客戶端。
這將又是一條漫長的旅途同發送數據相似,不過咱們根本感受不到。

web應用程序接收

收到的數據塊進入接收緩衝區,意味着數據包接收的操做告一段落了。
接下來,應用程序會調用 Socket 庫的 read來獲取收到的數據,這時數據會被轉交給應用程序。若是應用程序不來獲取數據,則數據會被一直保存在緩衝區中
但通常來講,應用程序會在數據到達以前調用 read 阻塞式的等待數據到達,在這種狀況下,TCP 模塊在完成接收操做的同時,就會執行將數據轉交給應用程序的操做。
 
接收到請求後,會根據URI轉換爲實際的文件,這些事情web服務器會進行處理
若是 URI 指定的文件內容爲 HTML 文檔或圖片,那麼只要直接將文件內容做爲響應消息返回客戶端就能夠了。
但 URI 指定的文件內容不只限於 HTML 文檔,也有多是一個程序。
在這個狀況下,服務器不會直接返回文件內容,而是會運行這個程序,而後將程序輸出的數據返回給客戶端
而響應的內容就是HttP協議中對於響應的約束。

總結

以下圖所示,數據就是這樣一層層的不斷進行數據封裝傳遞。
應用層協議的軟件,根據目的地的IP地址(若是是域名須要先進行DNS解析)以及端口號,再加上其餘的信息按照HTTP協議組裝成HTTP請求數據
而後藉助於操做系統提供的Socket接口,調用TCP模塊對數據進行處理,添加頭部,分片等
TCP想要發送數據前,還須要創建鏈接,也就是Socket的鏈接過程,這個創建鏈接的過程的數據發送流程與數據傳送階段的流程相同
他們都是TCP組裝好數據而後交由IP模塊進行處理
IP模塊根據目的地IP地址,藉助於操做系統的路由表選擇下一跳路由,而路由表又是根據各類路由選擇協議自學習而來的
獲得了下一跳的路由,再根據ARP協議就能夠查詢獲得下一站的物理地址
應用程序藉助於操做系統創建Socket鏈接,會分配端口,也就是源端口
此時就有了源IP地址,目的IP地址,源端口,目的端口,源MAC,目的MAC
而後操做系統與網卡驅動配合將數據封裝成以太網幀,而且藉助於網卡將數據轉換爲光電信號發送出去
 
路由器的端口有網卡和MAC,因此能夠做爲接收方,網卡將光電信號轉換爲數據,而後進行數據校驗,MAC檢驗,確認是發給本身的
而後就根據路由表進行轉發,這個路由表跟操做系統的路由表同樣的邏輯原理
這一步又跟操做系統IP模塊的處理差很少,找到了下一跳IP而後ARP協議查找MAC,而後更改源MAC和目的MAC
完成數據在鏈路層的傳遞
 
最終經過一段一段的鏈路到達目的地主機,主機的網卡相似路由器,也是光電信號轉換接收,而後檢驗,MAC檢驗,而後通知操做系統
操做系統解析MAC數據報,而後IP模塊接收,而後TCP/UDP,而後最終到達WEB應用程序。
這就是大體,大體的網絡通訊過程。
 
參考:計算機網絡(謝希仁)、網絡是怎樣鏈接的(戶根勤,周自恆(譯者))
相關文章
相關標籤/搜索