瀏覽器輸入網站發生了什麼

一個程序猿每天打開瀏覽器,輸入網址-查詢信息;從未研究過這短短的幾秒甚至幾百毫秒瀏覽器到底發生了什麼。

瀏覽器

從輸入一個地址開始,它可以是這樣的 www.baidu.com, 也可以是這樣的 https://admin:[email protected]:80/dir/file1.html, 咋一看好像都能看懂,而且還知道這麼輸入會得到什麼,更言之還能斷點調試一下;

其實我們只是在入口和出口處玩耍.殊不知中間發生了什麼…默唸…

URL

我們先來看下URL,URL有很多種,不止我們常用到的http://(google已經快不支持http協議了,轉向https安全協議),還有很多比如"file:" (讀取本地文件) , “ftp:”(文件傳輸協議) , “mailto:”(郵件服務,需要配置正確的電子郵箱)等.

在這裏插入圖片描述

它們擁有同樣的格式,即都需要定義一個訪問方法(協議http,ftp等).

那麼知道這些後瀏覽器做了什麼呢?

瀏覽器解析URL

(宛如廢話的一句解釋…)

瀏覽器首先對URL進行解析,從而生成發送給服務器的請求信息.依據不同的協議訪問不同的服務器,這裏闡述訪問Web服務器的情況.

解析方式如下:
在這裏插入圖片描述

有時候進入主頁的時候文件名經常不寫比如http://www.lab.com/dir/,那麼解析的時候就會去尋找目錄下面的default.html或者index.html具體訪問什麼要看服務器如何配置.當不寫最後一個**/**時,是會先尋找文件夾,再尋找文件名的規則來進行的.

明白了URL,我們來對URL中HTTP進行簡單的說明。

HTTP協議

HTTP協議定義了客戶端和服務器之間交互的消息內容和步驟,請求中包含了對什麼做什麼兩個部分;

對什麼: 這部分就是URI(統一資源標識符),一般來說,URI的內容是一個存放網頁數據的文件名或者是一個CGI程序的文件名.例如/dir/file1.html;不過,URI不僅限於此,也可以直接用"http:"開頭的URL來作爲URI.換句話就是,這裏可以寫各種訪問目標,而這些訪問目標統稱爲URI.

做什麼: 也稱爲方法.表示需要Web服務器做什麼,典型的例子包括讀取URI表示的數據/將客戶端輸入的數據發送給URI表示的程序等.

在這裏插入圖片描述

看到這張圖是不是就對之前所解釋的做什麼有所瞭解了呢!

收到消息之後,Web服務器會對其中的內容進行解析,通過URI和方法來判斷"對什麼",“做什麼”,並根據這些要求完成工作將結果放入響應消息中.

至此我們瞭解了HTTP的全貌,之後會一步步往下深入網絡到底是怎麼連接的…


當我們想寄一封信件的時候,我們需要能夠幫助我們送信的機構,如果要自己送去那還送信做什麼,直接過去把寄信人打一頓就完事了;所以就有了郵局(快遞的你先放下…),每個人都可以將信委託給郵局,讓郵局幫我們將信件寄出去。我們發送一個網絡請求也是,每個應用都可以發送網絡請求,同樣需要一個能夠將消息發送到網絡的機構,這個機構由操作系統來完成組建。所以,瀏覽器解析URL生成HTTP請求後需要委託操作系統將這些消息發送到網絡。

當然,郵局也會要求我們填寫一個寄信單,這個單子包括了寄信人的地址寄信人的聯繫方式收信人的地址收信人的聯繫方式4個重要的信息(還有其他附加信息),填寫正確才能將信件成功寄出。操作系統發送消息也是如此,它需要的是收信人的地址【對方的IP地址】,收信人的聯繫方式【對方的端口號】。發送方的自然也需要,只是兩者綁定在一起,開機的那一刻就已經存在內存中了。

在這之前,來了解一下IP地址是啥子。

IP地址

住在有門牌號的房子的大夥都知道(如果沒有,請默哀兩分鐘!),寄發信件的時候需要填寫自己和對方的具體地址,而這個地址就是小區的某個房間的門牌號,完整的地址包括了國家,省份市直轄區,縣/區,鄉鎮小區等等。國家與國家之間形成了不同的區域,說中國在哪,一定會有答案,再往下,省市區小區直到門牌號,它就像一個唯一的號牌將這個地址標記出來。

IP地址同樣是這樣的道理。

在這裏插入圖片描述

互聯網和公司內部的局域網都是基於TCP/IP的思路來設計的,如上圖,就是由一些小的子網(小區甚至樓層之間),通過路由器連接起來。這裏的子網可以理解成爲用集線器連接起來的幾臺計算機,將它看作一個單位,稱爲子網。將子網連接起來,就形成了一個網絡。

你要說怎麼理解,那看下面這張圖吧(自己畫的可能不準確!)。

在這裏插入圖片描述

在網絡中所有的設備都會被分配一個地址。就好像是XX號XX室。其中對應的號碼是分配給整個子網的,而對應的號碼是分配給子網中的計算機的,這就是網絡中的地址。對應的號碼稱爲網絡號,對應的號碼稱爲主機號,這個地址的整體稱爲IP地址。發送者發送的消息首先經過子網中的集線器,轉發到距離最近的路由器上。接下來,路由器會根據消息的目的地判斷下一個路由去的位置,然後將消息發送到下一個路由器,即消息再次經過子網內的集線器被轉發到下一個路由器。前面的過程不斷重複,最終消息就被傳到了目的地。這個過程就好像你準備好信件由郵局寄出,郵局寄出後會送往下一站,再由下一站判斷你的目的地,再往下送一樣;

那麼這個地址到底是怎麼組成的呢?

在這裏插入圖片描述

如上圖,實際的IP地址是一串32比特的數字,按照1個字節爲一組分成4組,分別用十進制表示然後再用圓點隔開。在IP地址的規則中,網絡號和主機號連接起來總共是32比特,但這兩部分的具體結構是不固定的。在組建網絡時,用戶可以自行決定他們之間的分配關係,因此,這裏還需要另外的附加信息來表示IP地址的內部結構。

這個附加信息就是子網掩碼。子網掩碼的格式如下圖,是一串與IP地址長度相同的32比特數字,左邊一半全是1,代表網絡號,右邊一半全是0,代表主機號。

在這裏插入圖片描述

DNS

那麼要怎麼得到域名對應的IP地址呢?

按照開發的思路,要得到域名對應的IP地址,那肯定需要一個key-value的內存表來記錄域名key對應的IP地址value,這樣取出來即可,可是…這個表在哪裏?

這就要涉及到DNS域名服務器,瀏覽器委託操作系統先去DNS域名服務器查詢域名對應的IP地址,服務器返回需要IP,然後我們就可以用這個IP發送消息了。

在這裏插入圖片描述

等等!我怎麼訪問DNS域名服務器的?我…我怎麼知道它的IP的??

在這裏插入圖片描述

參考DNS 原理入門以及如果你聽英文可以聽得懂的話 AWS的‘什麼是 DNS’?

首先,本機一定要知道DNS服務器的IP地址,否則上不了網。通過DNS服務器,才能知道某個域名的IP地址到底是什麼。

DNS服務器的IP地址,有可能是動態的,每次上網時由網關分配,這叫做DHCP機制;也有可能是事先指定的固定地址。Linux系統裏面,DNS服務器的IP地址保存在/etc/resolv.conf文件。

有一些公網的DNS服務器,也可以使用,其中最有名的就是Google的8.8.8.8和Level 3的4.2.2.2

在linux系統總可以使用dig match 域名 來查看使用的DNS服務器IP地址。

域名的層級結構如下 :

主機名.次級域名.頂級域名.根域名

# 即

host.sld.tld.root

DNS服務器根據域名的層級,進行分級查詢。 就是從根域名開始,依次查詢每一級域名的NS記錄,直到查到最終的IP地址,過程大致如下。

  1. 從"根域名服務器"查到"頂級域名服務器"的NS記錄和A記錄(IP地址)
  2. 從"頂級域名服務器"查到"次級域名服務器"的NS記錄和A記錄(IP地址)
  3. 從"次級域名服務器"查出"主機名"的IP地址

"根域名服務器"的NS記錄和IP地址一般是不會變化的,所以內置在DNS服務器裏面。

知道了對方的IP地址,要怎麼纔算連接呢?以編程者的思想連接如下圖所示。

在這裏插入圖片描述

我們這裏不需要知道編程怎麼實現,因爲不管是哪種編程它們都是在委託操作系統在發送信息,所以基本流程如下圖。

在這裏插入圖片描述

這裏解釋下這張圖!

上文中我們知道連接互聯網的重任不是應用自己連接,而是委託給操作系統來執行連接,瀏覽器或者應用程序調用Socket發起一個連接就是一次創建Socket(FD)套接字的過程。

首先,分配一個內存空間用以存儲套接字信息,然後,將表示這個套接字的描述符告知應用程序。

那何爲套接字描述符呢?在這之前想考一個問題,在計算機中同一時間進行通信操作的應用程序不止一個,這時,我們就需要一種方法來識別出某個特定的套接字,這種方法就是描述符。我們可以理解描述符是給某個套接字分配的唯一編號。當我們使用某個套接字來執行收發數據的操作時,就可以出示所擁有的描述符,協議棧就能夠判斷出我們希望用哪一個套接字來連接或者發送數據了。在win中使用netstat命令查看系統套接字內容,如下圖(這張圖是盜來的):

在這裏插入圖片描述

圖中每一行相當於一個套接字,當創建套接字時,就會增加一行控制信息,賦予“即將開始通信”的狀態,並進行通信的準備工作,如分配用於臨時存放手法數據的緩衝區空間。

接着Socket調用connect連接服務器,這個時候協議棧並不知道要和誰通信,在服務器端甚至應用程序要和誰連接都不曉得,這樣下去都不知道咋整。所以,發起連接的一方需要告知被連接方一些必要的信息,這樣雙方纔知道互連的通信是誰,才能順利的進行收發數據。

那麼,它們如何溝通呢?

需要的前提大部分已經湊齊,開始通信之前我們需要了解一下TPC/IP模型。

網絡模型不是一開始就有的,在網絡剛發展時,網絡協議是由各互聯網公司自己定義的,各家的協議也是不能互通的。這樣大大的阻礙了互聯網的發展,爲了解決這個問題,國際標準化組織 1984 提出的模型標準,簡稱 OSI(Open Systems Interconnection Model)。具體如下圖:
在這裏插入圖片描述

在這裏插入圖片描述

OSI七層模型每一層都有自己的作用,從上到下的作用依次爲:

  • 應用層(Application) :提供網絡與用戶應用軟件之間的接口服務
  • 表示層(Presentation) :提供格式化的表示和轉換數據服務,如加密和壓縮
  • 會話層(Session) 提供包括訪問驗證和會話管理在內的建立和維護應用之間通信的機制
  • 傳輸層(Transimission):提供建立、維護和取消傳輸連接功能,負責可靠地傳輸數據(PC)
  • 網絡層(Network): 處理網絡間路由,確保數據及時傳送(路由器)
  • 數據鏈路層(DataLink): 負責無錯傳輸數據,確認幀、發錯重傳等(交換機)
  • 物理層(Physics) :提供機械、電氣、功能和過程特性(網卡、網線、雙絞線、同軸電纜、中繼器)

七層中應用層、表示層和會話層由軟件控制,傳輸層、網絡層和數據鏈路層由操作系統控制,物理層有物理設備控制。

2 TCP/IP參考模型及協議

1) 模型

TCP/IP 模型是由 OSI 模型演化而來,TCP/IP 模型將 OSI 模型由七層簡化爲五層(一開始爲四層),應用層、表示層、會話層統一爲應用層。

在這裏插入圖片描述

2) 協議

TCP/IP協議被稱爲傳輸控制協議/互聯網協議,又稱網絡通訊協議(Transmission Control Protocol)。是由網絡層的IP協議和傳輸層的TCP協議組成,是一個很大的協議集合。

  • 物理層和數據鏈路層沒有定義任何特定協議,支持所有的標準和專用的協議。
  • 網絡層定義了網絡互聯也就是IP協議,主要包括IP、ARP、RARP、ICMP、IGMP。
  • 傳輸層定義了TCP和UDP(User Datagram Protocol),我們會後面重點介紹一下TCP協議。
  • 應用層定義了HTTP(超文本傳輸協議)、FTP(文件傳輸協議)、DNS(域名系統)等協議。

3 物理層

計算機在傳遞數據的時候傳遞的都是0和1的數字,而物理層關心的是用什麼信號來表示0和1,是否可以雙向通信,最初的連接如何建立以及完成連接如何終止,總之,物理層是爲數據傳輸提供可靠的環境。

4 數據鏈路層

數據鏈路層們於物理層和網絡層之間,用來向網絡層提供數據,就是把源計算機網絡層傳過來的信息傳遞給目標主機。
數據鏈路層主要的作用包括:

  • 如何將數據組合成數據幀(Frame),幀是數據鏈路層的傳輸單位
  • 數據鏈路的建立、維護和拆除
  • 幀包裝、幀傳輸、幀同步
  • 幀的差錯恢復
  • 流量控制

5 網絡層

網絡層位於傳輸層和數據鏈路層之間,用於把數據從源主機經過若干個中間節點傳送到目標主機,並向傳輸層提供最基礎的數據傳輸服務,它要提供路由和選址的工作。

那什麼是路由和選址呢?

選址

交換機是靠MAC來尋址的,而因爲MAC地址是無層次的,所以要靠IP地址來確認計算機的位置,這就是選址。

路由

在能夠選擇的多條道路之間選擇一條最短的路徑就是路由的工作。

路由和選址都離不開IP,我們就詳細介紹一下IP頭部。

IP頭

IP頭部是由20個字節組成的,具體項所佔的位數如下圖:

在這裏插入圖片描述

具體的數據我們用Wireshark來表抓取一下,如圖(藍色部分爲IP數據包):

在這裏插入圖片描述

version - 版本

Header Length - 首部長部

Differentiated Services Field - 優先級與服務類型

Total Length - 總長度,該字段用以指示整個IP數據包的長度,最長爲65535字節,包括頭和數據。

Identification - 標識符,唯一標識主機發送的每一份數據報。

Flags - 標誌。分爲3個字段,依次爲保留位、不分片位和更多片位

Fragment offset - 段偏移量。該分片相對於原始數據報開始處位置的偏移量。

TTL(Time to Live生存時間) - 該字段用於表示IP數據包的生命週期,可以防止一個數據包在網絡中無限循環地發下去。TTL的意思是一個數據包在被丟棄之前在網絡中的最大週轉時間。該數據包經過的每一個路由器都會檢查該字段中的值,當TTL的值爲0時此數據包會被丟棄。TTL對應於一個數據包通過路由器的數目,一個數據包每經過一個路由器,TTL將減去1。

Protocol - 協議號。用以指示IP數據包中封裝的是哪個協議。

Header checksum - 首部校驗和。檢驗和是16位的錯誤檢測字段。目的主機和網絡中的每個網關都要重新計算報頭的校驗和,如果一樣表示沒有改動過。

Source - 源IP地址。該字段用於表示數據包的源地址,指的是發送該數據包的設備的網絡地址。

Destination - 目標IP地址。該字段用於表示數據包的目標的地址,指的是接收節點的網絡地址。

6 傳輸層

傳輸層是面向連接的、可靠的的進程到進程通信的協議。TCP提供全雙工服務,即數據可在同一時間雙向傳播。TCP將若干個字節構成一個分組,此分組稱爲報文段(Segment)。提供了一種端到端的連接。

傳輸層的協議主要有TCP 和 UDP,TCP(Transimision Control Protocal)是一種可靠的、面向連接的協議,傳輸效率低。UDP(User Datagram Protocal)是一種不可靠的、無連接的服務,傳輸效率高。
下面重點介紹一下TCP的三次握手和四次揮手。

1) TCP的功能

TCP主要是將數據進行分段打包傳輸,對每個數據包編號控制順序,運輸中丟失、重發和丟棄處理。

2) TCP頭的介紹

有點和IP頭類似,我們先來張圖看下:

在這裏插入圖片描述

Source Port & Destination Port - 源端口號和目標端口號;計算機通過端口號識別訪問哪個服務,比如http服務或ftp服務;發送方端口號是進行隨機端口;目標端口號決定了接收方哪個程序來接收。

Sequence number - 32位序列號,TCP用序列號對數據包進行標記,以便在到達目的地後重新重裝。在建立連接時通常由計算機生成一個隨機數作爲序列號的初始值。

Acknowledgment number - 32位確認號,確認應答號。發送端接收到這個確認應答後,可以認爲這個位置以前所有的數據都已被正常接收。

Header Length - 首部長度。單位是 ‘4’個’字節’,如果沒有可選字段,那麼這裏的值就是 5。表示 TCP 首部的長度爲 20 字節。

checksum - 16位校驗和。用來做差錯控制,TCP校驗和的計算包括TCP首部、數據和其它填充字節。

flags - 控制位。TCP的連接、傳輸和斷開都受這六個控制位的指揮

window size - 本地可接收數據的數目,這個值的大小是可變的。當網絡通暢時將這個窗口值變大加快傳輸速度,當網絡不穩定時減少這個值可以保證網絡數據的可靠傳輸。它是來在TCP傳輸中進行流量控制的

3) 傳說中的三次握手和四次揮手(抓包演示)

三次握手和四次揮手到底是怎麼回事呢,我用一臺主機A(172.16.50.72:65076)起一個服務,另外一臺主機B(172.16.17.94:8080)請求一下。
在A主機上啓動node服務:

let http = require('http');
let url = require('url');

let server = http.createServer();
server.on('request', (req, res) => {
    let {pathname, querry} = url.parse(req.url, true);
    let result = [];
    req.on('data', (data) => {
        result.push(data);
    })
    req.on('end', () => {
        console.log(Buffer.concat(result).toString());
        res.end('hello world');
    })

})
server.listen(8080, () => {
    console.log('server started');
});

B主機連接A併發送數據:

curl -d "user":"lucy" 172.16.17.94:8080

用wireshark抓包演示一下。如下圖:

在這裏插入圖片描述

上圖中A爲三次握手,B爲數據傳輸,C爲四次揮手。下面我們詳細介紹一下這三個部分。

首先我們先圖解一下wireshark抓到的數據,如下圖:

在這裏插入圖片描述

我們把這個過程分爲三部分,第一部分爲三次握手建立連接,第二部分爲數據傳輸,第三次爲四次揮手斷開連接。

三次握手

我們分析一下三次握手的過程(包括ack 和 seq的值變化)。
在這裏插入圖片描述

爲了方便描述我們將主動發起請求的172.16.17.94:8080 主機稱爲客戶端,將返回數據的主機172.16.17.94:8080稱爲服務器,以下也是。

  • 第一次握手: 建立連接。客戶端發送連接請求,發送SYN報文,將seq設置爲0。然後,客戶端進入SYN_SEND狀態,等待服務器的確認。
  • 第二次握手: 服務器收到客戶端的SYN報文段。需要對這個SYN報文段進行確認,發送ACK報文,將ack設置爲1。同時,自己還要發送SYN請求信息,將seq爲0。服務器端將上述所有信息一併發送給客戶端,此時服務器進入SYN_RECV狀態。
  • 第三次握手: 客戶端收到服務器的ACK和SYN報文後,進行確認,然後將ack設置爲1,seq設置爲1,向服務器發送ACK報文段,這個報文段發送完畢以後,客戶端和服務器端都進入ESTABLISHED狀態,完成TCP三次握手。

數據傳輸
在這裏插入圖片描述

  • 客戶端先向服務器發送數據,該數據報是lenth爲159的數據。
  • 服務器收到報文後, 也向客戶端發送了一個數據進行確認(ACK),並且返回客戶端要請求的數據,數據的長度爲111,將seq設置爲1,ack設置爲160(1 + 159)。
  • 客戶端收到服務器返回的數據後進行確認(ACK),將seq設置爲160, ack設置爲112(1 + 111)。

四次揮手

當客戶端和服務器通過三次握手建立了TCP連接以後,當數據傳送完畢,就要斷開TCP連接了,就有了神祕的“四次揮手”。
在這裏插入圖片描述

  • 第一次揮手:客戶端向服務器發送一個FIN報文段,將設置seq爲160和ack爲112,;此時,客戶端進入 FIN_WAIT_1狀態,這表示客戶端沒有數據要發送服務器了,請求關閉連接;
  • 第二次揮手:服務器收到了客戶端發送的FIN報文段,向客戶端回一個ACK報文段,ack設置爲1,seq設置爲112;服務器進入了CLOSE_WAIT狀態,客戶端收到服務器返回的ACK報文後,進入FIN_WAIT_2狀態;
  • 第三次揮手:服務器會觀察自己是否還有數據沒有發送給客戶端,如果有,先把數據發送給客戶端,再發送FIN報文;如果沒有,那麼服務器直接發送FIN報文給客戶端。請求關閉連接,同時服務器進入LAST_ACK狀態;
  • 第四次揮手:客戶端收到服務器發送的FIN報文段,向服務器發送ACK報文段,將seq設置爲161,將ack設置爲113,然後客戶端進入TIME_WAIT狀態;服務器收到客戶端的ACK報文段以後,就關閉連接;此時,客戶端等待2MSL後依然沒有收到回覆,則證明Server端已正常關閉,客戶端也可以關閉連接了。

注意:在握手和揮手時確認號應該是對方序列號加1,傳輸數據時則是對方序列號加上對方攜帶應用層數據的長度。

7 應用層

應用層常見協議有HTTP、HTTPS 、FTP 、SMTP等。

TCP/IP模型我們基本介紹完了,那層與層之間是怎樣合作和分工的呢,我們用兩張圖介紹一下:
發送方的數據是從上往下傳輸的,即從應用層向物理層傳輸。接收方的數據是從下往上傳輸的,即從物理層嚮應用層傳輸。如下兩張圖。
在這裏插入圖片描述

發送方是從高層到低層封裝數據:

  • 在應用層要把各式各樣的數據如字母、數字、漢字、圖片等轉換成二進制
  • 在TCP傳輸層中,上層的數據被分割成小的數據段,併爲每個分段後的數據封裝TCP報文頭部
  • 在TCP頭部有一個關鍵的字段信息端口號,它用於標識上層的協議或應用程序,確保上層數據的正常通信
  • 計算機可以多進程併發運行,例如在發郵件的同時也可以通過瀏覽器瀏覽網頁,這兩種應用通過端口號進行區分
  • 在網絡層,上層數據被封裝上親的報文頭部(IP頭部),上層的數據是包括TCP頭部的。IP地址包括的最關鍵字段信息就是IP地址,用於標識網絡的邏輯地址。
  • 數據鏈路徑層,上層數據成一個MAC頭部,內部有最關鍵的是MAC地址。MAC地址就是固化在硬件設備內部的全球唯一的物理地址。
  • 在物理層,無論在之前哪一層封裝的報文頭和還是上層數據都是由二進制組成的,物理將這些二進制數字比特流轉換成電信號在網絡中傳輸

在這裏插入圖片描述

接收方是從低層到高層解封裝

  • 數據封裝完畢傳輸到接收方後,將數據要進行解封裝
  • 在物理層,先把電信號轉成二進制數據,並將數據傳送至數據鏈路層
  • 在數據鏈路層,把MAC頭部拆掉,並將剩餘的數據傳送至上一層
  • 在網絡層,數據的IP頭部被拆掉,並將剩餘的數據送至上一層
  • 在傳輸層,把TCP頭部拆掉,將真實的數據傳送至應用層

我嚴重懷疑你在拖文章長度
在這裏插入圖片描述

參考資料:
TPC/IP 詳解 https://zhuanlan.zhihu.com/p/33797520
書籍:網絡是怎樣連接的

待續

轉載請註明出處:https://blog.csdn.net/qq_17238449/article/details/102976359

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