《網絡是怎樣鏈接的》閱讀

文章首發於我的bloghtml

歡迎指正補充,可聯繫lionsom_lin@qq.comgit

原文地址:《網絡是怎樣鏈接的》閱讀整理程序員

目錄

  • 前序
  • 1、生成HTTP請求消息
  • 2、向DNS服務器查詢Web服務器的IP地址
  • 3、瀏覽器委託協議棧發送消息
  • 4、IP與以太網的包收發操做
  • 5、集線器、交換機、路由器
  • 6、探索接入網和網絡運營商(沒有深刻了解)
  • 7、服務器端的局域網中有什麼玄機
  • 8、請求到達Web服務器,響應返回瀏覽器


macOS Sierra: 網絡實用工具幫助



前序

爲何會讀這本書?做爲一名普通的iOS開發者,在iOS開發過程當中通常使用三方庫AFNetworking來進行網絡請求,不多使用到系統的網絡請求接口NSURLSession,頂多頂多使用過socket套接字進行網絡請求,這裏是我用socket與FastDFS文件服務器進行交互的一個demo。因此咱們做爲上層開發者通常只會使用規定好的接口,根本不會在乎網絡請求底層是如何實現或者說是如何傳遞數據的,基於這種狀況,我也就很好奇網絡請求底層是如何如何的。bash

做者:[日]戶根勤

因而我也就在亞馬遜上挑選了這本《網絡是怎樣鏈接的》書籍來進行閱讀,但願能從中獲得些許啓發,藉此文章來記錄一些我對網絡的理解。

總體結構

總體結構

快速溫習

總綱1

總綱2

1、生成HTTP請求消息

1.一、瀏覽器輸入URL

http://www.baidu.com

1.二、首先根據HTTP的規則,解析URL

1.三、URL省略文件名的幾種狀況

a)、http://www.baidu.com/dir/

/dir/後面省略了訪問的文件名,服務器已經默認設置在省略文件名狀況下要訪問的默認文件名,通常都會訪問/dir/index.html或者/dir/default.html

b)、http://www.baidu.com/dir

通常處理方案:若是web服務器上存在dir文件,則將dir看成文件名來處理;若是web服務器上存在名爲dir的目錄,則將dir看成目錄來處理。

c)、http://www.baidu.com/

這個URL表示:它訪問一個名叫/的目錄。因爲省略了文件名,因此根據上一種狀況,它訪問的文件也就是/index.html或者/default.html。 註釋:/目錄表示的是目錄層級中最頂級的『根目錄』。

d)、http://www.baidu.com

沒有路徑時,表示訪問根目錄下事先設置的默認文件夾,也就是/index.html或者/default.html

1.四、HTTP的基本思路

HTTP協議:它定義了客戶端與服務器之間交互信息的內容和步驟

HTTP請求消息包含『對什麼』和『進行怎樣的操做』兩個部分。 其中至關於『對什麼』的部分稱爲URI。通常來講URI的內容是一個存放網頁的文件名或者是一個CGI程序的文件名,例如"/dir/file.html"、"/dir/program.cgi"等。 其中『進行怎樣的操做』的部分稱爲方法。方法表示須要讓web服務器完成怎樣的工做,其中典型的例子包括讀取URI表示的數據、將客戶端輸入的數據傳遞給CGI程序等。

URI:Uniform Resource Identifier,統一資源標識符

CGI程序:對web服務器程序調用其餘程序的規則所作的定義就是CGI,安裝這個規則來工做的程序就是CGI程序。

HTTP的主要方法

方法 含義
GET 獲取URI指定的信息,若是URI指定的文件,則返回文件的內容;若是URI指定的是CGI程序,則返回該程序的輸出數據
POST 從客戶端向服務器發送數據。通常用於發送表單中填寫的數據等狀況下。

1.五、生成HTTP請求消息

HTTP消息在格式上是有嚴格規定的,所以瀏覽器會按照規定的格式來生成請求消息。

1.六、發送請求後收到響應消息

響應狀態碼

1.七、請求網頁中包含圖片

1條請求消息中只能寫一個URI,若是須要獲取多個文件,必須對每一個文件單獨發送1條請求

2、向DNS服務器查詢Web服務器的IP地址

瀏覽器可以解析網址並生成HTTP消息,但它自己不具有將消息發送到網絡的功能,所以這一功能須要委託操做系統來實現。在委託操做系統發送消息時,必須提供通信對象的IP地址,而不是域名,所以在HTTP消息以後,咱們須要根據域名查詢IP地址。

2.一、TCP/IP網絡

互聯網和公司內部的局域網都是基於TCP/IP的思路來設計的,TCP/IP的結構就是由一些小的子網,經過路由器鏈接起來組成一個大的網絡,這裏的子網能夠理解爲用集線器鏈接起來的幾臺計算機,咱們將它當作一個單位,稱爲子網,將子網經過路由器鏈接起來,就造成一個網絡。

2.二、IP地址

在網絡中,全部的設備都會被分配一個地址,這個地址就至關於顯示中某一條路上的"XX號XX室",其中"號"對應的號碼是分配給整個子網的,而"室"對應的號碼是分配給子網中的計算機的,這就是網絡中的地址。"號"稱爲網絡號,"室"稱爲主機號,整個地址稱爲IP地址IP地址 = 網絡號 + 主機號

預熱:數據傳遞過程

經過IP地址咱們能夠判斷出訪問對象服務器的位置,從而將消息發送到服務器。消息傳送的具體過程在後面的章節有詳細講解,不過如今咱們先簡單瞭解一下。發送者發出的消息首先通過子網中的集線器,轉發到距離發送者最近的路由器上(上圖①)。接下來,路由器會根據消息的目的地判斷下一個路由器的位置,而後將消息發送到下一個路由器,即消息再次通過子網內的集線器被轉發到下一個路由器(上圖②)。前面的過程不斷重複,最終消息就被傳送到了目的地。

2.三、IP地址結構

實際的IP地址是一串32比特(bit)的數字,按照8bit=1byte(字節)爲一組分紅4組,分別用十進制表示。這就是咱們常見的IP地址格式,但僅憑這一串數字咱們沒法區分哪部分是網絡號,哪部分是主機號。在IP地址的規則中,網絡號和主機號連起來總共是32比特,但這兩部分的具體結構是不固定的。在組建網絡時,用戶能夠自行決定它們之間的分配關係,所以,咱們還須要另外的附加信息來表示IP地址的內部結構。

IP地址的表示方法

IP地址舉例

IP地址的主機號:

全0:表示整個子網

全1:表示向子網上全部設備發送包,即『廣播』

【拓展】

問:有了 IP 地址,爲何還要用 MAC 地址?

答:知乎-有了 IP 地址,爲何還要用 MAC 地址?

2.四、瀏覽器如何向DNS服務器發出查詢的呢?

DNS解析器

向 DNS服務器發出查詢,也就是向DNS服務器發送查詢消息,並接收服務器返回的響應消息。換句話說,對於 DNS服務器,咱們的計算機上必定有相應的 DNS客戶端,而至關於 DNS客戶端的部分稱爲 DNS解析器,或者簡稱解析器。經過 DNS查詢 IP地址的操做稱爲域名解析,所以負責執行解析( resolution)這一操做的就叫解析器( resolver)了。解析器其實是一段程序,它包含在操做系統的 Socket庫中。

首先,庫究竟是什麼東西呢?庫就是一堆通用程序組件的集合,其餘的應用程序都須要使用其中的組件。庫有不少好處。首先,使用現成的組件搭建應用程序能夠節省編程工做量;其次,多個程序使用相同的組件能夠實現程序的標準化。除此以外還有不少其餘的好處,所以使用庫來進行軟件開發的思路已經很是普及,庫的種類和數量也很是之多。

Socket庫

Socket庫也是一種庫,是用於調用網絡功能的程序組件集合。其中包含的程序組件可讓其餘的應用程序調用操做系統的網絡功能 ,而解析器就是這個庫中的其中一種程序組件。

2.五、如何經過解析器向DNS服務器發出查詢

代碼調用查詢DNS

根據域名查詢 IP地址時,瀏覽器會使用 Socket庫中的解析器。

調用解析器後,解析器會向 DNS服務器發送查詢消息,而後DNS服務器會返回響應消息。響應消息中包含查詢到的IP地址,解析器會取出 IP地址,並將其寫入瀏覽器指定的內存地址中。只要運行圖 1.11中的這一行程序,就能夠完成前面全部這些工做,咱們也就完成了IP地址的查詢。接下來,瀏覽器在向 Web服務器發送消息時,只要從該內存地址取出 IP地址,並將它與HTTP請求消息一塊兒交給操做系統就能夠了。

調用解析器時,計算機內部工做流程

2.六、如何獲取DNS服務器IP地址?(Domain Name System,域名系統)

向 DNS服務器發送消息時,咱們固然也須要知道 DNS服務器的 IP地址。只不過這個 IP地址是做爲 TCP/ IP的一個設置項目事先設置好的,不須要再去查詢了。不一樣的操做系統中 TCP/ IP的設置方法也有差別, MAC中的設置以下圖所示,解析器會根據這裏設置的 DNS服務器 IP地址來發送消息。

Mac中DNS服務器地址的設置

2.七、DNS服務器是如何工做的

DNS服務器基本工做

DNS服務器會從域名與 IP地址的對照表中查找相應的記錄,並返回 IP地址。

域名

例如:www.baidu.com

服務器、郵件服務器(郵件地址中 @後面的部分)的名稱

Class

在最先設計 DNS方案時, DNS在互聯網之外的其餘網絡中的應用也被考慮到了,而 Class就是用來識別網絡的信息。不過,現在除了互聯網並無其餘的網絡了,所以 Class的值永遠是表明互聯網的 IN

記錄類型

例如:A = IP地址

MX = 郵件服務器

CNAME = 域名相關的別名

表示域名對應何種類型的記錄。例如,當類型爲 A時,表示域名對應的是 IP地址;當類型爲 MX時,表示域名對應的是郵件服務器。對於不一樣的記錄類型,服務器向客戶端返回的信息也會不一樣

2.八、如何在數萬DNS服務器中找到目標DNS服務器

域名層次結構

DNS中的域名都是用句點來分隔的,好比 www.lab.glasscom.com,這裏的句點表明了不一樣層次之間的界限,就至關於公司裏面的組織結構不用部、科之類的名稱來劃分,只是用句點來分隔而已 。

在域名中,越靠右的位置表示其層級越高,好比 www. lab. glasscom. com這個域名若是按照公司裏的組織結構來講,大概就是「 com事業集團 glasscom部 lab科的 www」這樣。其中,至關於一個層級的部分稱爲域。所以, com域的下一層是 glasscom域,再下一層是 lab域,再下面纔是 www這個名字。

根域

com、jp、cn這些域(稱爲頂級域)就是最頂層了,它們各自負責保存下級DNS服務器的信息,但實際上並不是如此。在互聯網中,com和 jp的上面還有一級域,稱爲根域。根域不像 com、 jp那樣有本身的名字,所以在通常書寫域名時常常被省略,若是要明確表示根域,應該像 www. lab. glasscom. com.這樣在域名的最後再加上一個句點,而這個最後的句點就表明根域。不過,通常都不寫最後那個句點,所以根域的存在每每被忽略,但根域畢竟是真實存在的,根域的 DNS服務器中保管着 com、 jp等的 DNS服務器的信息。因爲上級 DNS服務器保管着全部下級 DNS服務器的信息,因此咱們能夠從根域開始一路往下順藤摸瓜找到任意一個域的 DNS服務器。

經過根域找到目標DNS服務器

還須要完成另外一項工做,那就是將根域的 DNS服務器信息保存在互聯網中全部的 DNS服務器中。這樣一來,任何 DNS服務器就均可以找到並訪問根域 DNS服務器了。所以,客戶端只要可以找到任意一臺 DNS服務器,就能夠經過它找到根域 DNS服務器,而後再一路順藤摸瓜找到位於下層的某臺目標 DNS服務器。分配給根域 DNS服務器的 IP地址在全世界僅有 13個,並且這些地址幾乎不發生變化,所以將這些地址保存在全部的 DNS服務器中也並非一件難事。實際上,根域 DNS服務器的相關信息已經包含在 DNS服務器程序的配置文件中了,所以只要安裝了 DNS服務器程序,這些信息也就被自動配置好了。

查找目標DNS服務器

3、瀏覽器委託協議棧發送消息

總體流程一覽圖

3.一、建立套接字

<描述符> = socket(<使用IPv4>,<使用TCP>,...)

瀏覽器調用Socket庫中socket程序組件,和調用解析器同樣,調用socket以後,控制流程會轉移到socket內部並執行建立套接字的操做,完成以後控制流程又會被移交回應用程序。

應用程序調用 socket申請建立套接字,協議棧根據應用程序的申請執行建立套接字的操做。在這個過程當中,協議棧首先會分配用於存放一個套接字所需的內存空間,而後寫入初始狀態。此內存空間用於記錄套接字的控制信息。

套接字 建立成功後,協議棧會返回一個描述符,應用程序會將收到的描述符存放在內存中。

描述符

應用程序是經過「描述符」這一類 似號碼牌的東西來識別套接字的。

描述符是用來識別不一樣的套接字的,你們能夠做以下理解。咱們如今只關注了瀏覽器訪問 Web服務器的過程,但實際上計算機中會同時進行多個數據的通訊操做,好比能夠打開兩個瀏覽器窗口,同時訪問兩臺 Web服務器。這時,有兩個數據收發操做在同時進行,也就須要建立兩個不一樣的套接字。這個例子說明,同一臺計算機上可能同時存在多個套接字,在這樣的狀況下,咱們就須要一種方法來識別出某個特定的套接字,這種方法就是描述符。咱們能夠將描述符理解成給某個套接字分配的編號。也許光說編號還不夠形象,你們能夠想象一下在酒店寄存行李時的場景,酒店服務人員會給你一個號碼牌,向服務人員出示號碼牌,就能夠取回本身寄存的行李,描述符的原理和這個差很少。當建立套接字後,咱們就可使用這個套接字來執行收發數據的操做了。這時,只要咱們出示描述符,協議棧就可以判斷出咱們但願用哪個套接字來鏈接或者收發數據了。

因爲套接字中記錄了通訊雙方的信息以及通訊處於怎樣的狀態,因此只要經過描述符肯定了相應的套接字,協議棧就可以獲取全部的相關信息,這樣一來,應用程序就不須要每次都告訴協議棧應該和誰進行通訊了。

協議棧內部

socket所在位置

套接字

socket本質是編程接口(API),對TCP/IP的封裝,TCP/IP也要提供可供程序員作網絡開發所用的接口,這就是Socket編程接口。

套接字是網絡通訊過程當中端點的抽象表示,包含進行網絡通訊必需的五種信息:鏈接使用的協議,本地主機的IP地址,本地進程的協議端口,遠地主機的IP地址,遠地進程的協議端口。

socket = IP address + TCP/UDP + port。

Mac查看實際的套接字

Mac查看實際的套接字

協議棧

操做系統中的網絡控制軟件也就是協議棧,網絡硬件是網卡。

套接字與協議棧之間的關係

套接字中記錄了用於控制通訊操做的各類控制信息,協議棧則須要根據這些信息判斷下一步的行動,這就是套接字的做用。

協議棧是根據套接字中記錄的控制信息來工做的。

網絡協議

OSI七層網絡模型(Open System Interconnect) TCP/IP網絡模型 對應網絡協議
應用層(Application) HTTP、FTP、TFTP、SMTP、NFS
表示層(Presentation) 應用層
會話層(Session) SMTP、DNS
傳輸層(Transport) 傳輸層 TCP、UDP
網絡層(Network) 網絡層 IP、ARP、ICMP
數據鏈路層(Data Link) 數據鏈路層
物理層(Physical) 物理層

3.二、鏈接服務器

#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr* servaddr, socklen_t addrlen); // 返回:成功爲0,出錯-1
複製代碼

應用程序經過調用 Socket庫中的名爲 connect的程序組件來完成這一操做。

第一個參數:即描述符,connect會將應用程序指定的描述符告知協議棧,而後協議棧根據這個描述符來判斷到底使用哪個套接字去和服務器端的套接字進行鏈接,並執行鏈接的操做

第二個參數,即服務器 IP地址,就是經過 DNS服務器查詢獲得的咱們要訪問的服務器的 IP地址。

第三個參數,即端口號,IP地址是爲了區分網絡中的各個計算機而分配的數值。所以,只要知道了 IP地址,咱們就能夠識別出網絡上的某臺計算機。可是,鏈接操做的對象是某個具體的套接字,所以必需要識別到具體的套接字才行,而僅憑IP地址是沒法作到這一點的。

若是說描述符是用來在一臺計算機內部識別套接字的機制,那麼端口號就是用來讓通訊的另外一方可以識別出套接字的機制。

服務器上所使用的端口號是根據應用的種類事先規定好的,僅此而已。

Web是 80號端口,電子郵件是 25號端口 65

問題:咱們知道了服務器的端口號,可是服務器不知道客戶端的端口號?

既然肯定鏈接對象的套接字須要使用端口號,那麼服務器也得知道客戶端的套接字號碼才行吧,這個問題是怎麼解決的呢?

事情是這樣的,首先,客戶端在建立套接字時,協議棧會爲這個套接字隨便分配一個端口號。接下來,當協議棧執行鏈接操做時,會將這個隨便分配的端口號通知給服務器。

鏈接服務器本質

鏈接其實是通訊雙方交換控制信息

控制信息

通訊操做中使用的控制信息分爲兩類。

(1)頭部中記錄的信息

(2)套接字(協議棧中的內存空間)中記錄的信息

控制信息一:頭部中記錄的信息

他們是客戶端和服務器相互聯絡時交換的控制信息。這些字段是固定的,在鏈接、收發、斷開等各個階段中,每次客戶端和服務器之間進行通訊時,都須要提供這些控制信息。具體來講,這些信息會被添加在客戶端與服務器之間傳遞的網絡包的開頭。在鏈接階段,因爲數據收發尚未開始,網絡包中沒有實際的數據,只有控制信息。這些控制信息位於網絡包的開頭,所以被稱爲頭部。此外,以太網和IP協議也有本身的控制信息,這些信息也叫 頭部,爲了不各類不一樣的頭部發生混淆,咱們通常會記做 TCP頭部、以太網頭部、 IP頭部

TCP頭部格式

網絡包中各個頭部

控制信息二:套接字(協議棧中的內存空間)中記錄的信息

那就是保存在套接字中,用來控制協議棧操做的信息。應用程序傳遞來的信息以及從通訊對象接收到的信息都會保存在這裏,還有收發數據操做的執行狀態等信息也會保存在這裏,協議棧會根據這些信息來執行每一步的操做。

3.2.一、鏈接操做的實際過程

這個過程是從應用程序調用 Socket庫的connect開始的(看上圖『總體流程一覽圖』中②)。 >

connect(<描述符>,<服務器IP地址和端口號>, …)

鏈接操做的第一步是在 TCP模塊處建立表示鏈接控制信息的頭部。

經過 TCP頭部中的發送方和接收方端口號能夠找到要鏈接的套接字。

TCP創建鏈接要進行「三次握手」

  • 客戶端向服務器發送一個SYN J
  • 服務器向客戶端響應一個SYN K,並對SYN J進行確認ACK J+1
  • 客戶端再向服務器發一個確認ACK K+1

TCP三次握手

從圖中能夠看出,當客戶端調用connect時,觸發了鏈接請求,向服務器發送了SYN J包,這時connect進入阻塞狀態;服務器監聽到鏈接請求,即收到SYN J包,調用accept函數接收請求向客戶端發送SYN K ,ACK J+1,這時accept進入阻塞狀態;客戶端收到服務器的SYN K ,ACK J+1以後,這時connect返回,並對SYN K進行確認;服務器收到ACK K+1時,accept返回,至此三次握手完畢,鏈接創建。

創建鏈接以後,協議棧的鏈接操做就結束了,也就是說 connect已經執行完畢,控制流程被交回到應用程序。

3.三、收發數據

3.3.一、將HTTP請求消息交給協議棧

接下來就進入數據收發階段了。數據收發操做是從應用程序調用 write將要發送的數據交給協議棧開始的(看上圖『總體流程一覽圖』中③),協議棧收到數據後執行發送操做。

MTU/MSS

MTU: Maximum Transmission Unit,最大傳輸單元。一個網絡包的最大長度,以太網中通常爲 1500字節。

MSS: Maximum Segment Size,最大分段大小。除去頭部以後,一個網絡包所能容納的 TCP數據的最大長度。TCP和 IP的頭部加起來通常是 40字節,所以 MTU減去這個長度就是 MSS。例如,在以太網中, MTU爲 1500,所以 MSS就是 1460。 TCP/ IP可使用一些可選參數( protocol option),如加密等,這時頭部的長度會增長,那麼 MSS就會隨着頭部長度增長而相應縮短。

3.3.二、對較大數據進行拆分

應用程序的數據通常都比較大,所以 TCP會按照網絡包的大小對數據進行拆分。

數據拆分

3.3.三、TCP經過ACK號確保網絡包是否收到

經過「序號」和「 ACK號」能夠確認接收方是否收到了網絡包。

ACK原理

3.3.四、接受HTTP響應消息

首先,瀏覽器在委託協議棧發送請求消息以後,會調用read程序(看上圖『總體流程一覽圖』中④)來獲取響應消息。而後,控制流程會經過read轉移到協議棧,而後協議棧會執行接下來 的操做。和發送數據同樣,接收數據也須要將數據暫存到接收緩衝區中,這裏的操做過程以下。首先,協議棧嘗試從接收緩衝區中取出數據並傳遞給應用程序,但這個時候請求消息剛剛發送出去,響應消息可能還沒返回。響應消息的返回還須要等待一段時間,所以這時接收緩衝區中並無數據,那麼接收數據的操做也就沒法繼續。這時,協議棧會將應用程序的委託,也就是從接收緩衝區中取出數據並傳遞給應用程序的工做暫時掛起,等服務器返回的響應消息到達以後再繼續執行接收操做。

協議棧會檢查收到的數據塊和 TCP頭部的內容,判斷是否有數據丟失,若是沒有問題則返回 ACK號。而後,協議棧將數據塊暫存到接收緩衝區中,並將數據塊按順序鏈接起來還原出原始的數據,最後將數據交給應用程序。具體來講,協議棧會將接收到的數據複製到應用程序指定的內存地址中,而後將控制流程交回應用程序。將數據交給應用程序以後,協議棧還須要找到合適的時機向發送方發送窗口更新。

3.四、斷開鏈接,並刪除套接字

3.4.一、從服務器端斷開鏈接

這裏咱們以服務器一方發起斷開過程爲例來進行講解。

首先,服務器一方的應用程序會調用Socket庫的close程序。而後,服務器的協議棧會生成包含斷開信息的 TCP頭部,具體來講就是將控制位中的 FIN比特設爲 1。接下來,協議棧會委託 IP模塊向客戶端發送數據。同時,服務器的套接字中也會記錄下斷開操做的相關信息。

服務器端斷開socket

3.4.二、從客戶端斷開鏈接

  • 應用進程首先調用close主動關閉鏈接,這時TCP發送一個FIN M;
  • 另外一端接收到FIN M以後,執行被動關閉,對這個FIN進行確認。它的接收也做爲文件結束符傳遞給應用進程,由於FIN的接收意味着應用進程在相應的鏈接上再也接收不到額外數據;
  • 一段時間以後,接收到文件結束符的應用進程調用close關閉它的socket。這致使它的TCP也發送一個FIN N;
  • 接收到這個FIN的源發送端TCP對它進行確認。

TCP客戶端斷開鏈接

3.4.三、刪除套接字

和服務器的通訊結束以後,用來通訊的套接字也就不會再使用了,這時咱們就能夠刪除這個套接字了。不過,套接字並不會當即被刪除,而是會等待一段時間以後再被刪除。等待這段時間是爲了防止誤操做。

誤操做舉例:若是最後客戶端返回的 ACK號丟失了,結果會如何呢?這時,服務器沒有接收到 ACK號,可能會重發一次 FIN。若是這時客戶端的套接字已經刪除了,會發生什麼事呢?套接字被刪除,那麼套接字中保存的控制信息也就跟着消失了,套接字對應的端口號就會被釋放出來。這時,若是別的應用程序要建立套接字,新套接字碰巧又被分配了同一個端口號,而服務器重發的 FIN正好到達,會怎麼樣呢?原本這個 FIN是要發給剛剛刪除的那個套接字的,但新套接字具備相同的端口號,因而這個 FIN就會錯誤地跑到新套接字裏面,新套接字就開始執行斷開操做了。之因此不立刻刪除套接字,就是爲了防止這樣的誤操做。

TCP整個流程一覽

TCP整個流程

4、IP與以太網的包收發操做

4.一、包的基本知識

TCP模塊在執行鏈接、收發、斷開等各階段操做時,都須要委託 IP模塊將數據封裝成包發送給通訊對象。咱們在 TCP的講解中也常常提到 IP,下面就來討論一下 IP模塊是如何將包發送給對方的。

正式開始這個話題以前,咱們先來介紹一下關於網絡包的一些基本知識。首先,包是由頭部和數據兩部分構成的(下圖(a))。頭部包含目的地址等控制信息,你們能夠把它理解爲快遞包裹的面單;頭部後面就是委託方要發送給對方的數據,也就至關於快遞包裹裏的貨物。一個包發往目的地的過程如圖 2. 15所示。

包的基本結構

4.二、IP模塊的做用

4.2.一、發送包的時候,IP模塊工做

收到委託後, IP模塊會將包的內容看成一整塊數據,在前面加上包含控制信息的頭部。

IP模塊負責添加以下兩個頭部:

(1)IP頭部: IP用的頭部,包含 IP地址。IP頭部中包含 IP協議規定的、根據 IP地址將包發往目的地所需的控制信息;

(2)MAC頭部:以太網用的頭部,包含 MAC地址。MAC頭部包含經過以太網的局域網將包傳輸至最近的路由器所需的控制信息。

總之,加上這兩個頭部以後,一個包就封裝好了,這些就是 IP模塊負責的工做。

4.2.二、接收包的時候,IP模塊工做

返回的包也會經過轉發設備發送回來,而後咱們須要接收這個包。接收的過程和發送的過程是相反的,信息先以電信號的形式從網線傳輸進來,而後由網卡將其轉換爲數字信息並傳遞給 IP模塊(下圖中的「 ③接收」)。接下來, IP模塊會將 MAC頭部和 IP頭部後面的內容,也就是 TCP頭部加上數據塊,傳遞給 TCP模塊。接下來的操做就是咱們以前講過的 TCP模塊負責的部分了。

IP模塊工做圖

4.三、生成包含接收方IP地址的IP頭部

IP頭部

IP頭部的「接收方 IP地址」填寫通訊對象的 IP地址。

發送方 IP地址須要判斷髮送所使用的網卡,並填寫該網卡的 IP地址。

問題來了:一臺計算機多個網卡,如何設置發送方IP地址?

不少服務器上都會安裝多塊網卡,這時一臺計算機就有多個 IP地址,在填寫發送方 IP地址時就須要判斷到底應該填寫哪一個地址。這個判斷至關於在多塊網卡中判斷應該使用哪一塊網卡來發送這個包,也就至關於判斷應該把包發往哪一個路由器,所以只要肯定了目標路由器,也就肯定了應該使用哪塊網卡,也就肯定了發送方的 IP地址。

那麼,咱們應該如何判斷應該把包交給哪塊網卡呢?其實和路由器使用 IP表(也叫路由表)判斷下一個路由器位置的操做是同樣的。由於協議棧的 IP模塊與路由器中負責包收發的部分都是根據 IP協議規則來進行包收發操做的,因此它們也都用相同的方法來判斷把包發送給誰。

(路由器收發下一章節具體說)

查看Mac本機的路由表Route Table

Mac查看RouteTable

查看Windows本機的路由表Route Table

Windows查看RouteTable

4.四、生成以太網用的MAC頭部

MAC頭部

  • 發送方 MAC地址

發送方 MAC地址,這裏填寫網卡自己的 MAC地址。 MAC地址是在網卡生產時寫入 ROM裏的,只要將這個值讀取出來寫入 MAC頭部就能夠了。對於多塊網卡的狀況,請你們回想一下設置發送方 IP地址的方法 。設置發送方 IP地址時,咱們已經判斷出了從哪塊網卡發送這個包,那麼如今只要將這塊網卡對應的 MAC地址填進去就行了。

  • 接收方MAC地址

只要告訴以太網對方的 MAC的地址,以太網就會幫咱們把包發送過去,那麼很顯然這裏應該填寫對方的 MAC地址。然而,在這個時間點上,咱們尚未把包發送出去,因此先得搞清楚應該把包發給誰,這個只要查一下路由表就知道了。在路由表中找到相匹配的條目,而後把包發給 Gateway列中的 IP地址就能夠了。既然已經知道了包應該發給誰,那麼只要將對方的 MAC地址填上去就行了,但到這裏爲止根本沒有出現對方的 MAC地址,也就是說咱們如今根本不知道對方的 MAC地址是什麼。所以,咱們還須要執行根據 IP地址查詢 MAC地址的操做。詳情看 4.4.一、經過 ARP查詢目標路由器的 MAC地址

IP模塊根據路由表 Gateway欄的內容判斷應該把包發送給誰。

4.4.一、經過 ARP查詢目標路由器的 MAC地址

這裏咱們須要使用 ARP協議(網絡層協議),它其實很是簡單。在以太網中,有一種叫做廣播的方法,能夠把包發給鏈接在同一以太網中的全部設備。 ARP就是利用廣播對全部設備提問:「 × ×這個 IP地址是誰的?請把你的 MAC地址告訴我。」而後就會有人回答:「這個 IP地址是個人,個人 MAC地址是 × × × ×。」 (下圖)

ARP: Address Resolution Protocol,地址解析協議。

ARP工做圖

經過ARP緩存提高效率,避免每次發送

Mac查看ARP緩存

Mac查看ARP緩存

Windows查看ARP緩存

Windows查看ARP緩存

MAC地址

MAC格式

MAC: Media Access Control的縮寫。 MAC頭部、 MAC地址中的 MAC也是這個意思。也就是說,經過 MAC模塊控制包收發操做時所使用的頭部和地址就叫做 MAC頭部和 MAC地址。

4.五、網卡-將IP包轉換成電或光信號發送出去

IP生成的網絡包只是存放在內存中的一串數字信息,沒有辦法直接發送給對方。所以,咱們須要將數字信息轉換爲電或光信號,才能在網線上傳輸,也就是說,這纔是真正的數據發送過程。負責執行這一操做的是網卡,但網卡也沒法單獨工做,要控制網卡還須要網卡驅動程序。驅動程序不僅有網卡纔有,鍵盤、鼠標、顯卡、聲卡等各類硬件設備都有。固然,不一樣廠商和型號的網卡在結構上有所不一樣,所以網卡驅動程序也是廠商開發的專用程序。

網卡

網卡

網卡的 ROM中保存着全世界惟一的 MAC地址,這是在生產網卡時寫入的。

網卡是如何將包轉換成電信號併發送到網線中的

網卡驅動從 IP模塊獲取包以後,會將其複製到網卡內的緩衝區中,而後向 MAC模塊發送發送包的命令。接下來就輪到 MAC模塊進行工做了。首先, MAC模塊會將包從緩衝區中取出,並在開頭加上報頭和起始幀分界符,在末尾加上用於檢測錯誤的幀校驗序列

給網絡包再加 3個控制數據

網卡MAC模塊將包從緩衝區中取出,並在開頭加上 報頭起始幀分界符,在末尾加上用於檢測錯誤的 幀校驗序列

網卡包格式

4.5.一、報頭

報頭做用

報頭是一串像 10101010…這樣 1和 0交替出現的比特序列,長度爲 56比特,它的做用是肯定包的讀取時機。當這些 1010的比特序列被轉換成電信號後,會造成如圖這樣的波形。接收方在收到信號時,遇到這樣的波形就能夠判斷讀取數據的時機。

網卡包的報頭

如何經過電信號來讀取數據

用電信號來表達數字信息時,咱們須要讓 0和 1兩種比特分別對應特定的電壓和電流,例以下圖( a)這樣的電信號就能夠表達數字信息。經過電信號來讀取數據的過程就是將這種對應關係顛倒過來。也就是說,經過測量信號中的電壓和電流變化,還原出 0和 1兩種比特的值。然而,實際的信號並不像下圖所示的那樣有分隔每一個比特的輔助線,所以在測量電壓和電流時必須先判斷出每一個比特的界限在哪裏。可是,像下圖( a)右邊這種 1和 0連續出現的信號,因爲電壓和電流沒有變化,咱們就沒辦法判斷出其中每一個比特到底應該從哪裏去切分。

經過時鐘測量讀取信號的時機

經過時鐘測量讀取信號的時機

如何判斷出其中每一個比特到底應該從哪裏去切分?

要解決這個問題,最簡單的方法就是在數據信號以外再發送一組用來區分比特間隔的時鐘信號。如圖( b)所示,當時鍾信號從下往上變化時讀取電壓和電流的值,而後和 0或 1進行對應就能夠了。可是這種方法存在問題。當距離較遠,網線較長時,兩條線路的長度會發生差別,數據信號和時鐘信號的傳輸會產生時間差,時鐘就會發生偏移。

數據信號和時鐘信號的傳輸會產生時間差,時鐘就會發生偏移。

另一種方法是當時鍾信號從上往下變化時進行讀取。要解決這個問題,能夠採用將數據信號和時鐘信號疊加在一塊兒的方法。這樣的信號如圖( c)所示,發送方將這樣的信號發給接收方。因爲時鐘信號是像圖( b)這樣按固定頻率進行變化的,只要可以找到這個變化的週期,就能夠從接收到的信號( c)中提取出時鐘信號( b),進而經過接收信號( c)和時鐘信號( b)計算出數據信號( a),這和發送方將數據信號和時鐘信號進行疊加的過程正好相反。而後,只要根據時鐘信號( b)的變化週期,咱們就能夠從數據信號( a)中讀取相應的電壓和電流值,並將其還原爲 0或 1的比特了。

4.5.二、起始幀分界符

起始幀分界符,它的末尾比特排列有少量變化。接收方以這一變化做爲標記,從這裏開始提取網絡包數據。也就是說,起始幀分界符是一個用來表示包起始位置的標記。

4.5.三、幀校驗序列

末尾的 FCS(幀校驗序列)用來檢查包傳輸過程當中因噪聲致使的波形紊亂、數據錯誤,它是一串 32比特的序列,是經過一個公式對包中從頭至尾的全部內容進行計算而得出來的。具體的計算公式在此省略,它和磁盤等設備中使用的 CRC錯誤校驗碼是同一種東西,當原始數據中某一個比特發生變化時,計算出來的結果就會發生變化。在包傳輸過程當中,若是受到噪聲的干擾而致使其中的數據發生了變化,那麼接收方計算出的 FCS和發送方計算出的 FCS就會不一樣,這樣咱們就能夠判斷出數據有沒有錯誤。

4.5.四、向集線器發送網絡包

網卡的 MAC模塊生成通用信號,而後由 PHY( MAU)模塊轉換成可在網線中傳輸的格式,並經過網線發送出去。

4.六、接收返回包

網卡接收網絡包

接收操做的第一步就是無論三七二十一把這些信號全都收進來再說。信號的開頭是報頭,經過報頭的波形同步時鐘,而後遇到起始幀分界符時開始將後面的信號轉換成數字信息。這個操做和發送時是相反的,即 PHY( MAU)模塊先開始工做,而後再輪到 MAC模塊。首先, PHY( MAU)模塊會將信號轉換成通用格式併發送給 MAC模塊, MAC模塊再從頭開始將信號轉換爲數字信息,並存放到緩衝區中。當到達信號的末尾時,還須要檢查 FCS。具體來講,就是將從包開頭到結尾的全部比特套用到公式中計算出 FCS,而後和包末尾的 FCS進行對比,正常狀況下二者應該是一致的,若是中途受到噪聲干擾而致使波形發生紊亂,則二者的值會產生差別,這時這個包就會被看成錯誤包而被丟棄。若是 FCS校驗沒有問題,接下來就要看一下 MAC頭部中接收方 MAC地址與網卡在初始化時分配給本身的 MAC地址是否一致,以判斷這個包是否是發給本身的。咱們不必去接收發給別人的包,所以若是不是本身的包就直接丟棄,若是接收方 MAC地址和本身 MAC地址一致,則將包放入緩衝區中 。到這裏, MAC模塊的工做就完成了,接下來網卡會通知計算機收到了一個包。

網卡中斷計算機,網卡驅動從網卡緩存中讀取數據

通知計算機的操做會使用一個叫做中斷的機制。在網卡執行接收包的操做的過程當中,計算機並非一直監控着網卡的活動,而是去繼續執行其餘的任務。所以,若是網卡不通知計算機,計算機是不知道包已經收到了這件事的。網卡驅動也是在計算機中運行的一個程序,所以它也不知道包到達的狀態。在這種狀況下,咱們須要一種機制可以打斷計算機正在執行的任務,讓計算機注意到網卡中發生的事情,這種機制就是中斷。具體來講,中斷的工做過程是這樣的。首先,網卡向擴展總線中的中斷信號線發送信號,該信號線經過計算機中的中斷控制器鏈接到 CPU。當產生中斷信號時, CPU會暫時掛起正在處理的任務,切換到操做系統中的中斷處理程序 。而後,中斷處理程序會調用網卡驅動,控制網卡執行相應的接收操做。

網卡驅動被中斷處理程序調用後,會從網卡的緩衝區中取出收到的包,並經過 MAC頭部中的以太類型字段判斷協議的類型。如今咱們在大多數狀況下都是使用 TCP/ IP協議,但除了 TCP/ IP以外還有不少其餘類型的協議,例如 NetWare中使用的 IPX/ SPX,以及 Mac電腦中使用的 AppleTalk等協議。這些協議都被分配了不一樣的以太類型,如 0080(十六進制)表明 IP協議,網卡驅動就會把這樣的包交給 TCP/ IP協議棧;若是是 809B則表示 AppleTalk協議,就把包交給 AppleTalk協議棧,以此類推。

4.七、將服務器的響應包從 IP傳遞給 TCP

下面咱們假設 Web服務器返回了一個網絡包,那麼協議棧會進行哪些處理呢 100?服務器返回的包的以太類型應該是 0800,所以網卡驅動會將其交給 TCP/ IP協議棧來進行處理。接下來就輪到 IP模塊先開始工做了,第一步是檢查 IP頭部,確認格式是否正確。若是格式沒有問題,下一步就是查看接收方 IP地址。若是接收網絡包的設備是一臺 Windows客戶端計算機,那麼服務器返回的包的接收方 IP地址應該與客戶端網卡的地址一致,檢查確認以後咱們就能夠接收這個包了。

IP模塊檢查IP頭部,若是接收方 IP地址不是本身的地址,經過ICMP反饋回去

若是接收方 IP地址不是本身的地址,那必定是發生了什麼錯誤。客戶端計算機不負責對包進行轉發,所以不該該收到不是發給本身的包 101。當發生這樣的錯誤時, IP模塊會經過 ICMP消息將錯誤告知發送方(圖 2. 1)。 ICMP規定了各類類型的消息,如表所示。當咱們遇到這個錯誤時, IP模塊會經過表中的 Destination unreachable消息通知對方。從這張表的內容中咱們能夠看到在包的接收和轉發過程當中可以遇到的各類錯誤,所以但願你們看一看這張表。

ICMP格式

IP模塊檢查IP頭部,若是接收方 IP地址是本身的地址,進行分片重組

若是接收方 IP地址正確,則這個包會被接收下來,這時還須要完成另外一項工做。 IP協議有一個叫做分片的功能。簡單來講,網線和局域網中只能傳輸小包,所以須要將大的包切分紅多個小包。若是接收到的包是通過分片的,那麼 IP模塊會將它們還原成原始的包。分片的包會在 IP頭部的標誌字段中進行標記,當收到分片的包時, IP模塊會將其暫存在內部的內存空間中,而後等待 IP頭部中具備相同 ID的包所有到達,這是由於同一個包的全部分片都具備相同的 ID。此外, IP頭部還有一個分片偏移量( fragment offset)字段,它表示當前分片在整個包中所處的位置。根據這些信息,在全部分片所有收到以後,就能夠將它們還原成原始的包,這個操做叫做分片重組。

TCP模塊接收包

接下來包會被交給 TCP模塊。 TCP模塊會根據 IP頭部中的接收方和發送方 IP地址,以及 TCP頭部中的接收方和發送方端口號來查找對應的套接字。找到對應的套接字以後,就能夠根據套接字中記錄的通訊狀態,執行相應的操做了。例如,若是包的內容是應用程序數據,則返回確認接收的包,並將數據放入緩衝區,等待應用程序

5、集線器、交換機、路由器

(1)路由器根據目標地址判斷下一個路由器的位置

(2)集線器在子網中將網絡包傳輸到下一個路由

實際上,集線器是按照以太網規則傳輸包的設備,而路由器是按照 IP規則傳輸包的設備,所以咱們也能夠做以下理解。

(1)IP協議根據目標地址判斷下一個 IP轉發設備的位置

(2)子網中的以太網協議將包傳輸到下一個轉發設備

場景設定:網絡包在進入互聯網以前經歷的傳輸過程。這裏咱們假設客戶端計算機鏈接的局域網結構是像下圖這樣的。也就是說,網絡包從客戶端計算機發出以後,要通過集線器、交換機和路由器最終進入互聯網。實際上,咱們家裏用的路由器已經集成了集線器和交換機的功能,像圖上這樣使用獨立設備的狀況不多見。

局域網的結構

5.一、信號在網線中傳播

網卡 -> 網線 -> 集線器

從信號流出網卡進入網線開始。網卡中的 PHY( MAU) 2模塊負責將包轉換成電信號,信號經過 RJ-45接口進入雙絞線,這部分的放大圖以下圖的右側部分所示。以太網信號的本質是正負變化的電壓,你們能夠認爲網卡的 PHY( MAU)模塊就是一個從正負兩個信號端子輸出信號的電路。

網卡與集線器用雙絞線鏈接的形態

網卡與集線器用雙絞線鏈接的形態

問題來了:信號衰減

信號在網線的傳輸過程當中,能量會逐漸損失。網線越長,信號衰減就越嚴重。集線器收到的信號有時會出現衰減。以下圖。

接收方信號變得難以識別

「雙絞」是爲了抑制噪聲

局域網網線使用的是雙絞線,其中「雙絞」的意思就是以兩根信號線爲一組纏繞在一塊兒,這種擰麻花同樣的設計是爲了抑制噪聲的影響。

噪聲是如何產生的

首先,咱們來看看噪聲是如何產生的。產生噪聲的緣由是網線周圍的電磁波,當電磁波接觸到金屬等導體時,在其中就會產生電流。所以,若是網線周圍存在電磁波,就會在網線中產生和本來的信號不一樣的電流。因爲信號自己也是一種帶有電壓變化的電流,其本質和噪聲產生的電流是同樣的,因此信號和噪聲的電流就會混雜在一塊兒,致使信號的波形發生失真,這就是噪聲的影響。

電磁波來源有兩種:外部和內部

影響網線的電磁波分爲兩種:

一種是由電機、熒光燈、 CRT顯示器等設備泄漏出來的電磁波,這種電磁波來自網線以外的其餘設備,

另外一種電磁波是從網線中相鄰的信號線泄漏出來的。因爲傳輸的信號自己就是一種電流,當電流流過期就會向周圍發出電磁波,這些電磁波對於其餘信號線來講就成了噪聲。這種內部產生的噪聲稱爲串擾( crosstalk)。

雙絞線對噪聲的抑制

a)經過兩根信號線的纏繞抵消外源性噪聲;

b)經過改變節距抑制內源性噪聲。

雙絞線對噪聲的抑制

5.二、集線器將信號發往全部設備

集線器的做用?

集線器將信號發送給全部鏈接在它上面的線路。

信號到達集線器的 PHY( MAU)模塊後,會進入中繼電路。中繼電路的基本功能就是將輸入的信號廣播到集線器的全部端口上。固然,也有一些產品具備信號整形、錯誤抑制等功能,但基本上就是將輸入的信號原封不動地輸出到網線接口。接下來,信號從全部接口流出,到達鏈接在集線器上的全部設備。而後,這些設備在收到信號以後會經過 MAC頭部中的接收方 MAC地址判斷是否是發給本身的,若是是發給本身的就接受,不然就忽略。這樣,網絡包就可以到達指定 MAC地址的接收方了。

因爲集線器只是原封不動地將信號廣播出去,因此即使信號受到噪聲的干擾發生了失真,也會原樣發送到目的地。這時,接收信號的設備,也就是交換機、路由器、服務器等,會在將信號轉換成數字信息後經過 FCS8校驗發現錯誤,並將出錯的包丟棄。固然,丟棄包並不會影響數據的傳輸,由於丟棄的包不會觸發確認響應。所以協議棧的 TCP模塊會檢測到丟包,並對該包進行重傳。

5.三、交換機的包轉發操做


對於交換機暫時理解不深入


5.四、路由器的包轉發操做

5.4.一、路由器內部結構

你們只要看明白路由器包括轉發模塊和端口模塊兩部分就能夠了。其中轉發模塊負責判斷包的轉發目的地,端口模塊負責包的收發操做。換句話說,路由器轉發模塊和端口模塊的關係,就至關於協議棧的 IP模塊和網卡之間的關係。

路由器內部結構

路由器的各個端口都具備 MAC地址和 IP地址。

5.4.二、路由器的工做原理

路由器在轉發包時,首先會經過端口將發過來的包接收進來,這一步的工做過程取決於端口對應的通訊技術。對於以太網端口來講,就是按照以太網規範進行工做,而無線局域網端口則按照無線局域網的規範工做,總之就是委託端口的硬件將包接收進來。接下來,轉發模塊會根據接收到的包的 IP頭部中記錄的接收方 IP地址,在路由表中進行查詢,以此判斷轉發目標。而後,轉發模塊將包轉移到轉發目標對應的端口,端口再按照硬件的規則將包發送出去,也就是轉發模塊委託端口模塊將包發送出去的意思。

5.4.三、路由器根據路由表對包進行轉發

交換機是經過 MAC頭部中的接收方 MAC地址來判斷轉發目標的,而路由器則是根據 IP頭部中的 IP地址來判斷的。

路由表

交換機在地址表中只匹配徹底一致的記錄,而 路由器則會忽略主機號部分,只匹配網絡號部分。打個比方,路由器在轉發包的時候只看接收方地址屬於哪一個區, × ×區發往這一邊, × ×區發往那一邊。

5.4.四、路由器的包接收操做

路由器的整個工做過程。首先,路由器會接收網絡包。路由器的端口有各類不一樣的類型,這裏咱們只介紹以太網端口是如何接收包的。以太網端口的結構和計算機的網卡基本相同,接收包並存放到緩衝區中的過程也和網卡幾乎沒有區別。首先,信號到達網線接口部分,其中的 PHY( MAU)模塊和 MAC模塊將信號轉換爲數字信息,而後經過包末尾的 FCS進行錯誤校驗,若是沒問題則檢查 MAC頭部中的接收方 MAC地址,看看是否是發給本身的包,若是是就放到接收緩衝區中,不然就丟棄這個包。若是包的接收方 MAC地址不是本身,說明這個包是發給其餘設備的,若是接收這個包就違反了以太網的規則。

路由器的端口都具備 MAC地址,只接收與自身地址匹配的包,遇到不匹配的包則直接丟棄。

5.4.五、查詢路由表肯定輸出端口

MAC頭部做用

完成包接收操做以後,路由器就會丟棄包開頭的 MAC頭部。 MAC頭部的做用就是將包送達路由器,其中的接收方 MAC地址就是路由器端口的 MAC地址。所以,當包到達路由器以後, MAC頭部的任務就完成了,因而 MAC頭部就會被丟棄。

經過路由器轉發的網絡包,其接收方 MAC地址爲路由器端口的 MAC地址。

路由器會根據 IP頭部中的內容進行包的轉發操做

  • a)查詢路由表判斷轉發目標

關於具體的工做過程,咱們仍是來看一個實際的例子,如上圖的狀況,假設地址爲 10. 10. 1. 101的計算機要向地址爲 192. 168. 1. 10的服務器發送一個包,這個包先到達圖中的路由器。判斷轉發目標的第一步,就是根據包的接收方 IP地址查詢路由表中的目標地址欄,以找到相匹配的記錄。就像前面講過的同樣,這個匹配並非匹配所有 32個比特,而是根據子網掩碼列中的值判斷網絡號的比特數,並匹配相應數量的比特 33。例如,上圖的第 3行,子網掩碼列爲 255. 255. 255. 0,就表示須要匹配從左起 24個比特。網絡包的接收方 IP地址和路由表中的目標地址左起 24個比特的內容都是 192. 168. 1,所以二者是匹配的,該行記錄就是候選轉發目標之一。

  • b)路由器修改包的有效期
  • c)路由器經過分片功能拆分大網絡包
  • d)路由器的發送操做

這一步操做取決於輸出端口的類型。若是是以太網端口,則按照以太網的規則將包轉換爲電信號發送出去;若是是 ADSL則按照 ADSL的規則來轉換,以此類推。在家庭網絡中,路由器後面通常鏈接 ADSL等線路接入互聯網,所以路由器會根據接入網的規則來發送包。不過,要理解具體的操做過程,須要先理解相應的通訊線路 ,比較複雜,所以咱們留到下一章探索互聯網內部時再講解。這裏,咱們假設路由器位於公司等局域網的內部,即輸出端口也是以太網,看看這種狀況是如何操做的。

以太網的包發送操做是根據以太網規則來進行的,即使設備種類不一樣,規則也是相同的。也就是說,其基本過程和協議棧中的 IP模塊發送包的過程是相同的,即在包前面加上 MAC頭部,

設置其中的一些字段,而後將完成的包轉換成電信號併發送出去。下面來簡單複習一下這個過程。首先,爲了判斷 MAC頭部中的 MAC地址應該填寫什麼值,咱們須要根據路由表的網關列判斷對方的地址。若是網關是一個 IP地址,則這個 IP地址就是咱們要轉發到的目標地址;若是網關爲空,則 IP頭部中的接收方 IP地址就是要轉發到的目標地址。知道對方的 IP地址以後,接下來須要經過 ARP根據 IP地址查詢 MAC地址,並將查詢的結果做爲接收方 MAC地址。路由器也有 ARP緩存,所以首先會在 ARP緩存中查詢,若是找不到則發送 ARP查詢請求。

路由器判斷下一個轉發目標的方法以下。

  • 若是路由表的網關列內容爲 IP地址,則該地址就是下一個轉發目標。
  • 若是路由表的網關列內容爲空,則 IP頭部中的接收方 IP地址就是下一個轉發目標。

路由器也會使用 ARP來查詢下一個轉發目標的 MAC地址。

網絡包完成後,接下來會將其轉換成電信號並經過端口發送出去。這一步的工做過程和計算機也是相同的。例如,當以太網工做在半雙工模式時,須要先確認線路中沒有其餘信號後才能發送,若是檢測到碰撞,則須要等待一段時間後重發。若是以太網工做在全雙工模式,則不須要確認線路中的信號,能夠直接發送。若是輸出端口爲以太網,則發送出去的網絡包會經過交換機到達下一個路由器。因爲接收方 MAC地址就是下一個路由器的地址,因此交換機會根據這一地址將包傳輸到下一個路由器。接下來,下一個路由器會將包轉發給再下一個路由器,通過層層轉發以後,網絡包就到達了最終的目的地。

5.五、路由器與交換機的關係

IP協議自己沒有傳輸包的功能,所以包的實際傳輸要委託以太網來進行。

路由器是基於 IP設計的,而交換機是基於以太網設計的,所以 IP與以太網的關係也就是路由器與交換機的關係。換句話說,路由器將包的傳輸工做委託給交換機來進行

IP(路由器)負責將包送達通訊對象這一總體過程,而其中將包傳輸到下一個路由器的過程則是由以太網(交換機)來負責的。

6、探索接入網和網絡運營商

此章節沒啥好說的,瞭解下便可!

7、服務器端的局域網中有什麼玄機

7.一、防火牆

防火牆基本佈局

防火牆的基本思路

防火牆的基本思路,即只容許發往特定服務器中的特定應用程序的包經過,而後屏蔽其餘的包。

主流的是包過濾方式的防火牆

包過濾方式的防火牆可根據接收方 IP地址、發送方 IP地址、接收方端口號、發送方端口號、控制位等信息來判斷是否容許某個包經過。

防火牆的不足

防火牆沒法抵禦的攻擊

防火牆能夠根據包的起點和終點來判斷是否容許其經過,但僅憑起點和終點並不能篩選出全部有風險的包。

好比,假設 Web服務器在收到含有特定數據的包時會引發宕機。可是防火牆只關心包的起點和終點,所以即使包中含有特定數據,防火牆也沒法發現,因而包就被放行了。而後,當包到達 Web服務器時,就會引起服務器宕機。經過這個例子你們能夠看出,只有檢查包的內容才能識別這種風險,所以防火牆對這種狀況無能爲力。

對防火牆沒法抵禦攻擊的應對方法

a)方法一:這個問題的根源在於 Web服務器程序的 Bug,所以修復 Bug防止宕機就是其中一種方法。這類 Bug中,危險性較高的會做爲安全漏洞公佈出來,開發者會很快發佈修復了 Bug的新版本,所以持續關注安全漏洞信息並更新軟件的版本是很是重要的。

b)另外一種方法就是在防火牆以外部署用來檢查包的內容並阻止有害包的設備或軟件。

7.二、負載均衡

7.2.一、多臺服務器 -- 分佈式架構

使用多臺服務器來分擔負載的方法更有效。這種架構統稱爲分佈式架構。

  • DNS輪詢分配服務器IP地址

最簡單的一種是經過 DNS服務器來分配。當訪問服務器時,客戶端須要先向 DNS服務器查詢服務器的 IP地址,若是在 DNS服務器中填寫多個名稱相同的記錄,則每次查詢時 DNS服務器都會按順序返回不一樣的 IP地址。

DNS輪詢不足之處

例如:假如多臺 Web服務器中有一臺出現了故障,這時咱們但願在返回 IP地址時可以跳過故障的 Web服務器,然而普通的 DNS服務器並不能確認 Web服務器是否正常工做,所以即使 Web服務器宕機了,它依然可能會返回這臺服務器的 IP地址。

  • 使用負載均衡器分配訪問

負載均衡器分配訪問

7.2.二、緩存服務器

臨時保存內容並代替 Web服務器返回內容的緩存服務器

臨時保存內容並代替 Web服務器返回內容的緩存服務器

緩存服務器三種部署

緩存服務器三種部署

7.三、內容分發服務

根據緩存服務器分佈第三種方式,進行佈局。

8、請求到達Web服務器,響應返回瀏覽器

8.一、服務器概覽

服務器工做過程

8.二、服務器的接收操做

8.2.一、 網卡將接收到的信號轉換成數字信息

服務器將接收到的電信號還原數字信息

網卡將接收到的信號轉換成數字信息

根據信號還原的數字信息

根據信號還原的數字信息

網卡的 MAC模塊將網絡包從信號還原爲數字信息,校驗 FCS並存入緩衝區。

在這個過程當中,服務器的 CPU並非一直在監控網絡包的到達,而是在執行其餘的任務,所以 CPU並不知道此時網絡包已經到達了。但接下來的接收操做須要 CPU來參與,所以網卡須要經過 中斷 將網絡包到達的事件通知給 CPU。接下來, CPU就會暫停當前的工做,並切換到網卡的任務。而後,網卡驅動會開始運行,從網卡緩衝區中將接收到的包讀取出來,根據 MAC頭部的以太類型字段判斷協議的種類,並調用負責處理該協議的軟件。這裏,以太類型的值應該是表示 IP協議,所以會調用 TCP/ IP協議棧,並將包轉交給它。

網卡驅動會根據 MAC頭部判斷協議類型,並將包交給相應的協議棧。

8.2.二、IP模塊接收操做

( 1)IP模塊首先會檢查 IP頭部的格式是否符合規範,而後檢查接收方 IP地址,看包是否是發給本身的;

( 2)判斷網絡包是否通過分片;

( 3)須要檢查 IP頭部的協議號字段,並將包轉交給相應的模塊。例如,若是協議號爲 06(十六進制),則將包轉交給 TCP模塊;若是是 11(十六進制),則轉交給 UDP模塊。

8.2.三、TCP模塊如何處理鏈接包

TCP三次握手

第一步:當 TCP頭部中的控制位 SYN爲 1時,表示這是一個發起鏈接的包。這時, TCP模塊會執行接受鏈接的操做,不過在此以前,須要先檢查包的接收方端口號,並確認在該端口上有沒有與接收方端口號相同且正在處於等待鏈接狀態的套接字。若是指定端口號沒有等待鏈接的套接字,則向客戶端返回錯誤通知的包。向客戶端返回一個表示接收方端口不存在等待鏈接的套接字的 ICMP消息。

第二步:若是存在等待鏈接的套接字,則爲這個套接字複製一個新的副本,並將發送方 IP地址、端口號、序號初始值、窗口大小等必要的參數寫入這個套接字中,同時分配用於發送緩衝區和接收緩衝區的內存空間。而後生成表明接收確認的 ACK號,用於從服務器向客戶端發送數據的序號初始值,表示接收緩衝區剩餘容量的窗口大小,並用這些信息生成 TCP頭部,委託 IP模塊發送給客戶端。

第三步:這個包到達客戶端以後,客戶端會返回表示接收確認的 ACK號,當這個 ACK號返回服務器後,鏈接操做就完成了。這時,服務器端的程序應該進入調用 accept的暫停狀態,當將新套接字的描述符轉交給服務器程序以後,服務器程序就會恢復運行。

8.2.四、TCP模塊如何處理數據包

( 1)收到數據包時, TCP模塊會根據收到的包的發送方 IP地址、發送方端口號、接收方 IP地址、接收方端口號找到相對應的套接字;

( 2)將數據塊拼合起來並保存在接收緩衝區中;

( 3)向客戶端返回 ACK。

8.2.五、TCP模塊的斷開操做

在TCP協議的規則中,斷開操做能夠由客戶端或服務器任何一方發起,具體的順序是由應用層協議決定的。Web中,這一順序隨HTTP協議版本不一樣而不一樣,在HTTP1.0中,是服務器先發起斷開操做。

TCP客戶端斷開鏈接

(1)服務器會調用Socket庫的socket,TCP模塊會生成一個 FIN爲 1的 TCP頭部,並委託 IP模塊發送給客戶端

(2)當客戶端收到這個包後,會返回一個ACK號,

(3)接下來客戶端會調用close,生成一個 FIN爲 1的 TCP頭部發給服務器,

(4)服務器再返回一個 ACK號。

8.三、Web服務器程序解釋請求消息並做出響應

8.四、瀏覽器接收到響應並顯示內容

拓展閱讀

完整的一次 HTTP 請求響應過程(一)

完整的一次 HTTP 請求響應過程(二)

相關文章
相關標籤/搜索