帶你探索網絡里的那些秘密


背景


網絡,網絡...

雖然只是一個簡單的名詞,但是她的背后卻掩藏着太多太多的故事以及知識。

窮其編程的一生,或許也只能探索出那冰山一角,嗨...

小時雖知,學海無涯,卻毫不知意。玩乃天性,卻空流時光。憾...

so,矯情之余,我們來探索一下網絡究竟是怎么傳輸的。

概述


1

探索網絡的范圍,都在上圖有所展示(另存為看大圖)。

正文


一. 生成HTTP請求消息

2

打開一個網站,都是從瀏覽器中輸入網址開始,我們的探索也是從這里開始。

https: 是協議,告訴瀏覽器我們要訪問的目標,而https: 代表的就是訪問Web服務器,當然也有其他的協議。比如ftp:訪問的就是FTP服務器等。

sexyphoenix.github.io 是Web服務器域名,可以告訴我們在哪里可以找到Web服務器。

about/ 是Web服務器里面的文件路徑名,這里的about是目錄名,全路徑可能是about/index.md,而index.md應該被github掩藏了。

瀏覽器首先要做的就是對URL進行解析,知道我們要訪問的是sexyphoenix.github.io這個Web服務器上文件路徑為about目錄下的默認文件。

知道了要訪問的目標,接下來瀏覽器就要生成HTTP的請求信息,介紹到這,就要聊一聊HTTP協議了。

HTTP協議規定了客戶端和服務器通信的內容和步驟,簡單來說,就是兩個部分“對什么”“怎樣的操作”

“對什么”上面已經解析過了,“怎樣的操作”就是HTTP主要的方法:POST、GET、DELETE、PUT等。HTTP格式看下圖。

3

二、查詢Web服務器的IP地址

生成HTTP信息之后,接下來,我們就要發送信息給Web服務器了。但此時我們突然發現我們只有Web服務器的域名,並不知道服務器究竟在哪里。

那么我們應該如何像現實中送快遞一樣,快速的定位到哪一幢哪一室,講到這里,想必大家都有所意會了,IP。

IP地址

IP地址實際就是4個字節,32比特的數字,每8個比特為1組,具體看下圖十進制表示。

4

我們發送的信息,就是通過子網的集成器找到最近的路由器,再通過路由器(基於IP設計)找到最優抵達Web服務器的路由器,這樣不斷的查找網絡中的路由器節點,最終抵達Web服務器。

注意,我們的Web服務器的IP是最終的目的地,它是貫穿路由器---N---路由器---Web服務器整個環節的,是判斷整個網絡走向的依據,存在控制信息中。

路由器都有自己的IP,路由器到路由器就是根據Web服務器的IP(走向),通過本身的IP來移動。

到這里,我們也就了解清楚了通過IP,發送的信息最終可以抵達Web服務器。

那么,我們現在的問題就是如何通過Web服務器的域名找到它的IP? 講到這里,想必大家又都有所意會了,DNS。

域名解析

簡單的來說,DNS服務器維持了一系列關系表,也就是域名和IP對於的關系表。瀏覽器向最近的DNS服務器詢問“sexyphoenix.github.io”的IP地址是多少,DNS服務器會回答Web服務器IP為xxx。這一步也叫域名解析

講到這里,我們就要深究一下,瀏覽器究竟是怎樣向DNS服務器發送查詢的?

首先,我們要清楚一點,瀏覽器等應用程序本身是不能發送信息的,而是委托給操作系統來發送的。

而操作系統有一個超級出名的庫,Socket庫,它是調用網絡功能的程序組件集合。

Socket庫里面有一個函數。

IP信息 = gethostbyname("sexyphoenix.github.io") # 看,應用程序查詢IP很簡單,調用一個函數即可

發送數據有兩種協議,UDP和TCP,域名查詢用的是UDP。數據短速度快。

介紹了域名解析,下面來了解一下DNS服務器的工作。

DNS服務器

5

在上面已經提到過了,DNS服務器維護了一個關系表,上圖的類型A表示域名對應IP地址,MX表示域名對應的郵箱服務器,不同的類型,返回的信息有所不同。

DNS服務器的工作就是根據域名和類型,查找相關的記錄,並向應用程序返回響應信息。

DNS服務器查找

全球共有13台根域名服務器,根域名用“.”表示,其次才是下面的一級域名“com.”、“net.”等,我們平時訪問的域名“sexyphoenix.github.io.”后面有一個點,平時被省略。

我們用一張圖來看下查找順序,更清楚些。

6

先找最近的DNS服務器(一般是本機設置的),沒有再從根域找,然后不斷的向下找,直到找到我們Web服務器IP所在的DNS服務器。

三、TCP/IP傳輸數據

通過DNS服務器查詢,我們已經得到的Web服務器的IP,接下來就要開始發送數據了。而這部分也是比較難寫的一部分,因為我們要深入協議棧的內部,去了解它的結構。

我們都知道數據的傳輸,都是由上層委托給下層工作的。應用程序將發送的信息的行為委派給了操作系統,而操作系統內部就是通過協議棧來工作的。

來看下操作系統協議棧圖。

7

上部分是TCP協議和UDP協議,都是負責數據的收發部分,區別在於TCP是面向連接的,是一種可靠的協議,而UDP只負責發送,不保證准確到達。

下部分是IP協議,負責發送網絡包,其中還包括ICMP協議(檢查發送過程是否存在錯誤)和ARP協議(查詢MAC地址)。

數據收發

在查詢IP地址的時候,我們用到了Socket庫,這里同樣也需要用到它。

不過我們這里需要調用多個組件,才能實現數據的收發,從功能上可以分為四個部分。

  1. 創建套接字 (new Socket)

  2. 連接服務器的套接字 (connection)

  3. 收發數據 (write、read)

  4. 刪除套接字 (close)

在講之前,我們先了解下套接字。

套接字在數據收發中是相當重要的,它是一塊內存空間,里面存放着很重要的的控制信息

這些控制信息存放着通信對象的IP地址、端口、連接狀態、響應時間、數據收發情況等等,只有這些存在,才能知道數據發送到哪里,又發送了多少,有沒有錯誤等等。

創建套接字

創建套接字還是非常簡單的,直接調用Socket庫中的socket組件即可,創建完成之后會返回一個標識符,標識符的主要作用就是為了區別不同的套接字。

連接服務器的套接字

連接服務器用到的是connect組件,參數有標識符、服務器的IP、端口等,相當於和服務器之間連接了一條數據管道,后期數據在其中流通。

同時在這里也會發生著名的“三次握手”。

在剛發生連接階段,管道里面是沒有數據的,但是會有控制信息,這些控制信息包括TCP頭部,以太網頭部、IP頭部。

控制信息

根據層級來,我們會先生成TCP頭部,TCP頭部格式有很多字段,其中重要的就是雙方的端口,序號,ACK號,控制位,窗口等。稍微了解一下這些字段的作用。

端口

端口和IP是一同存在的,在互聯網早期的時候,公司聯網都是直接用公網IP的,但隨着互聯網的發展,公網IP越來越少,於是就出現了公網和內網的區別。

內網IP范圍

  1. 10.0.0.0 ~ 10.255.255.255

  2. 172.16.0.0 ~ 172.31.255.255

  3. 192.168.0.0 ~ 192.168.255.255

每個公司的內部都使用這些內網IP,再通過唯一的一個公網IP訪問互聯網,這樣就可以節省大量的公網IP。

那么公司的這些設置內網IP的電腦是如何通過唯一的公網IP訪問互聯網呢? 互聯網返回的信息又是怎么通過唯一的公網IP,定位到公司的某一台電腦上的?

地址轉換(NAT),這個技術就解決了上面的問題,它的原理就是在轉發網絡包時對IP頭部地址和端口進行改寫。

而端口在其中的作用至關重要,它可以讓路由器(公網IP)知道是那一台內網的電腦與互聯網通信,具體看下圖。

8

公司IP為192.168.23.183的電腦,通過49158端口向互聯網發送連接,當到達公司的公網路由器的時候,路由器的IP模塊會對控制信息進行改寫,最后變成IP為121.225.19.59,端口為1001和通信對象通信。

同時將這條記錄保存在路由器上,當通信對象返回信息時,會通過表格中的信息找到對應的內網電腦IP。

序號

發送方告訴接收方該網絡包在所有發送的數據的第幾個字節,序號的初始值是在連接階段隨機生成的(防止攻擊者猜到),在下面的收發數據階段,就是以這個序號為基數。

ACK號

接收方告訴發送發已經收到所有數據的第幾個字節,相當於序號+發送的數據長度。

控制位

每一個比特代表不同的控制信息,看下圖。

9

圖中解釋了比較重要的控制位。

窗口

接收方告訴發送方的窗口大小,如果接收方接受的速度比較慢,一起傳送的數據量就會變小相當於控制了我們傳送數據的快慢。

介紹了TCP頭部的關鍵字段,接下來我們開始進入連接。

首先,我們會將客戶端的控制位的SYN(1)、生成隨機序號M、窗口大小等,再通過其他層,到達服務器端(第一次握手)。

服務器收到SYN為1的信息,知道客戶端要和我連接,生成ACK號(M+1)、服務器隨機序號N(通信是雙向的,這時的服務器也相當於發送方)、控制位SYN(1)、窗口等發送(第二次握手)。

客戶端收到服務器端的信息,得到ACK號,知道連接正常,發送ACK號(N+1,服務器端的序號)、控制位SYN(1),告訴服務器已建立連接(第三次握手)。

收發數據

管道連接建立成功后,就進入了數據收發階段。

我們發送的信息一般都是比較大的,不可能一次性發送完畢,所以在TCP模塊,就會將應用數據切分成數據塊,切分的每個數據塊(MSS,最大數據長度)加上TCP頭部,IP頭部不能超過MTU大小(MTU,最大傳輸單元)。

接下來,交給IP模塊,生成IP頭部和MAC頭部信息,再通過網卡驅動,網卡設備將數字信息轉變成電信號,傳輸到接收方。接收方收到信息,會返回ACK號,重復以上步驟,直到接收方收到所有數據。

接收方收到全部數據后,同樣會向發送方發送數據,下面的步驟都和上面差不多了,這里不再贅述。

10

刪除套接字

和接收方通信完成之后,套接字不會再使用,這時就可以刪除套接字了。

套接字刪除可以由任何一方發起,這里假設服務器端發起,下面就來講講著名的“四次揮手”。

接收方收到全部數據后,等待一會就會刪除套接字。

  1. 服務器生成斷開信息,即將TCP的頭部控制位的FIN設置為1,發送給客戶端。

  2. 客戶端返回ACK號,表示發送的信息無誤。

  3. 客戶端所有數據處理完成后,向服務器發送FIN為1的斷開信息。

  4. 服務器返回ACK號,表示發送的信息無誤,等待一會,客戶端和服務器端都刪除套接字。

講到這里,數據收發的絕大數內容就講完了,接下來我們聊一聊IP模塊。

IP模塊

前面提到過,在IP模塊會生成IP頭部和以太網頭部。那么這兩個頭部究竟有什么作用?

為了便於理解,我們這里就講的簡單一些。

發送的數據到達子網的集線器或者交換機,通過MAC表,找到下一個轉發設備的MAC地址,以“以太網協議”傳輸到下一個轉發設備。

轉發設備根據目標地址的IP和“IP協議”判斷下一個轉發設備的IP,再通過MAC地址,傳輸到下一個轉發設備。

就這樣,經過多個轉發設備的接力后,網絡包最終到達接收方的網絡設備。

總結:IP協議根據目標地址判斷下一個IP轉發設備的位置,再通過以太網協議將網絡包輸出到下一個轉發設備

四、到達Web服務器

其實在到達Web服務器之前,我們也應該講講數字信號是如何轉化為電子信號的? 數據又是如何通過運營商到達Web服務器的?

只是這部分實在過於復雜,也多數跟硬件以及運維方向有關,這里就不講了。

首先,我們來講一講Web服務器的部署。

Web服務器的部署有三種方式

  1. 直接部署在公司的內網。

  2. 公司的內網和Web服務器分開部署。在接入網之后,部署統一防火牆,再分別進去內網和服務器。

  3. web服務器部署在運營商的數據中心。

三種方式自上而下,性能和安全上會越來越好,只是管理上可能會麻煩些。

為了安全和分擔負載,Web服務器前面會部署防火牆,可能還會有負載均衡器、緩存服務器、內容分發等等。

數據在經過層層過濾后,最終到達Web服務器,服務器的程序和上面創建連接的步驟稍有不同。

  1. 首先是創建套接字(socket)。

  2. 綁定套接字和端口號(bind)。

  3. 等待連接(listen)。

  4. 接受連接(accept)。

服務器的程序會一直等待客戶端的連接。

在接收到客戶端的請求后,Web服務器根據URI轉換為實際的文件名,並作出響應。格式如下。

11

到這里,我們所有的內容就到這里了。

最后,祝大家每天身體健康,開心編程,看的開心。嘿...


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM