1.2 向DNS服務器查詢Web服務器的IP地址
1.2.1 IP 地址的基本知識
委托操作系統發送消息前需要根據域名查詢 IP 地址。
生成 HTTP 消息之后,需要委托操作系統將消息發送給Web 服務器。
瀏覽器能夠解析網址並生成 HTTP 消息,但它本身不能消息發送到網絡中,這一功能需要委托操作系統來實現。
在委托操作系統發送消息時,必須要提供通信對象的 IP 地址,所以在委托前需要查詢網址中服務器域名對應的 IP 地址。
因此在生成 HTTP 消息之后,下一個步驟就是根據域名查詢 IP 地址。
在講解這一操作之前,讓我們先來簡單了解一下 IP 地址。
IP地址的基本概念
TCP/IP的基本思路
互聯網和公司內部的局域網都是基於 TCP/IP 的思路來設計的,所以我們先來了解 TCP/IP 的基本思路。
TCP/IP 的結構如圖下圖所示,是由一些小的子網通過路由器連接起來組成一個大的網絡。
這里的子網可以理解為用集線器連接起來的幾台計算機,我們將它看作一個單位,稱為子網。
將子網通過路由器連接起來,就形成了一個網絡。
在網絡中,所有的設備都會被分配一個地址,這個地址就相當於現實中某條路上的“×× 號 ×× 室”。
其中“號”對應的號碼是分配給整個子網的,而“室”對應的號碼是分配給子網中的計算機的,這就是網絡中的地址。
“號”對應的號碼稱為網絡號,“室”對應的號碼稱為主機號,這個地址的整體稱為 IP 地址。
IP地址的格式
前面這些就是 TCP/IP 中 IP 地址的基本思路。再來看一下實際的 IP 地址。
如下圖所示,實際的 IP 地址是一串32 比特的數字,按照 8 比特(1 字節)為一組分成 4 組,分別用十進制表示然后再用圓點隔開。
這就是我們平常經常見到的 IP 地址格式,但僅憑這一串數字我們無法區分哪部分是網絡號,哪部分是主機號。
在 IP 地址的規則中,網絡號和主機號連起來總共是 32 比特,但這兩部分的具體結構是不固定的。
子網掩碼
在組建網絡時,用戶可以自行決定它們之間的分配關系,因此,我們還需要另外的附加信息來表示 IP地址的內部結構。
這一附加信息稱為子網掩碼。子網掩碼的格式如下圖所示,是一串與 IP 地址長度相同的 32 比特數字,其左邊一半都是 1,右邊一半都是0。
其中,子網掩碼為 1 的部分表示網絡號,子網掩碼為 0 的部分表示主機號。
將子網掩碼按照和 IP 地址一樣的方式以每 8 比特為單位用圓點分組后寫在 IP 地址的右側,這就是圖上圖的方法。
這種寫法太長,我們也可以把 1 的部分的比特數用十進制表示並寫在 IP 地址的右側,如下圖所示。
這兩種方式只是寫法上的區別,含義是完全一樣的。
主機號全為0或1的情況
主機號部分的比特全部為 0 或者全部為 1 時代表兩種特殊的含義。
主機號部分全部為 0 代表整個子網而不是子網中的某台設備。
此外,主機號部分全部為 1 代表向子網上所有設備發送包,即廣播,如下圖所示。
1.2.2 域名和 IP 地址並用的理由
TCP/IP 網絡是通過 IP 地址來確定通信對象的,不知道 IP 地址就無法將消息發送給對方。
因此,在委托操作系統發送消息時,必須要先查詢好對方的 IP 地址。
為什么不直接輸入IP地址訪問服務器
要記住一串由數字組成的 IP 地址也非常困難相比 IP 地址來說,網址中使用服務器名稱比較好。
為什么不直接使用域名進行通信
IP 地址的長度為 32 比特,也就是 4 字節,相對地,域名最短也要幾十個字節,最長甚至可以達到 255 字節。
這增加了路由器的負擔,傳送數據也會花費更長的時間。路由器的速度是有極限的,因此我們不應該再采用效率更低的設計。
使用DNS查詢域名和IP地址
為了填補兩者之間的障礙,需要有一個機制能夠通過名稱來查詢 IP 地或者通過 IP 地址來查詢名稱。
這樣就能夠在人和機器雙方都不做出犧牲的前提下完美地解決問題。這個機制就是 DNS。
DNS:Domain Name System,域名服務系統。
將服務器名稱和 IP 地址進行關聯是 DNS 最常見的用法,但 DNS 的功能並不僅限於此,它還可以將郵件地址和郵件服務器進行關聯,以及為各種信息關聯相應的名稱。
1.2.3 Socket 庫提供查詢 IP 地址的功能
DNS解析器
瀏覽器是如何向 DNS 服務器發出查詢的
向 DNS 服務器發出查詢,也就是向 DNS 服務器發送查詢消息,並接收服務器返回的響應消息。
換句話說,對於 DNS 服務器,我們的計算機上一定有相應的 DNS 客戶端,而相當於 DNS 客戶端的部分稱為 DNS 解析器,或者簡稱解析器。
通過 DNS 查詢 IP 地址的操作稱為域名解析,負責執行解析(resolution)這一操作的就叫解析器(resolver)。
解析器實際上是一段程序,它包含在操作系統的 Socket 庫中,在介紹解析器之前,我們先來簡單了解一下 Socket 庫。
Socket庫
庫就是一堆通用程序組件的集合,其他的應用程序都需要使用其中的組件。
Socket 庫也是一種庫,其中包含的程序組件可以讓其他的應用程序調用操作系統的網絡功能。
而解析器就是這個庫中的其中一種程序組件。
1.2.4 通過解析器向 DNS 服務器發出查詢
解析器的用法非常簡單。Socket 庫中的程序都是標准組件,只要從應用程序中進行調用就可以了。
具體來說,在編寫瀏覽器等應用程序的時候,只要像下圖這樣寫上解析器的程序名稱“gethostbyname”以及 Web 服務器的域名“www.lab.glasscom.com”就可以了,這樣就完成了對解析器的調用。
調用解析器后,解析器會向 DNS 服務器發送查詢消息,然后 DNS 服務器會返回響應消息。
響應消息中包含查詢到的 IP 地址,解析器會取出 IP地址,並將其寫入瀏覽器指定的內存地址中。
只要運行上圖中的這一行程序,就可以完成前面所有這些工作,我們也就完成了 IP 地址的查詢。
接下來,瀏覽器在向 Web 服務器發送消息時,只要從該內存地址取出 IP 地址,並將它與 HTTP 請求消息一起交給操作系統就可以了。
1.2.5 解析器的內部原理
由於調用了其他程序,原本運行的程序進入暫停狀態,而被調用的程序開始運行,被稱為“控制流程轉移”。
應用程序調用解析器
網絡應用程序調用解析器時,程序的控制流程就會轉移到解析器的內部。
一般來說,應用程序編寫的操作內容是從上往下按順序執行的,當到達需要調用解析器的部分時,對應的那一行程序就會被執行,應用程序本身的工作就會暫停,如下圖①所示。
然后Socket庫中的解析器開始運行如下圖②所示,完成應用程序委托的操作。
解析器生成查詢消息
當控制流程轉移到解析器后,解析器會生成要發送給 DNS 服務器的查詢消息。
這個過程與瀏覽器生成要發送給 Web 服務器的 HTTP 請求消息的過程類似,
解析器會根據 DNS 的規格,生成一條表示“請告訴我 www.lab.glasscom.com 的 IP 地址”的數據(HTTP 消息是用文本編寫的,但 DNS 消息是使用二進制數據編寫的),並將它發送給 DNS 服務器,如下圖③所示。
委托操作系統的協議棧發送消息
發送消息這個操作並不是由解析器自身來執行,而是要委托給操作系統內部的協議棧來執行。
這是因為和瀏覽器一樣,解析器本身也不具備使用網絡收發數據的功能。
協議棧
操作系統內部的網絡控制軟件,也叫“協議驅動”“TCP/IP驅動”等。
協議棧通過網卡發送消息
解析器調用協議棧后,控制流程會再次轉移,協議棧會執行發送消息的操作,然后通過網卡將消息發送給 DNS 服務器
DNS服務器根據消息進行查詢
當 DNS 服務器收到查詢消息后,它會根據消息中的查詢內容進行查詢。
總之,如果要訪問的 Web 服務器已經在 DNS 服務器上注冊,那么這條記錄就能夠被找到,然后其 IP 地址會被寫入響應消息並返回給客戶端。
DNS服務返回響應消息
接下來,消息經過網絡到達客戶端,再經過協議棧被傳遞給解析器,如下圖⑦⑧所示。
協議棧傳遞給解析器,解析器取出IP
然后解析器讀取出消息取出 IP 地址,並將 IP 地址傳遞給應用程序如下圖 ⑨所示。
解析器將IP存入指定內存
實際上,解析器會將取出的 IP 地址寫入應用程序指定的內存地址中。
到這里,解析器的工作就完成了,控制流程重新回到應用程序(瀏覽器)。
現在應用程序已經能夠從內存中取出 IP 地址了,所以說 IP 地址是用這種方式傳遞給應用程序的。
DNS服務器IP是系統設置好的
向 DNS 服務器發送消息時,我們當然也需要知道 DNS 服只不過這個 IP 地址是作為 TCP/IP 的一個設置項目事先設置好的,不需要再去查詢了。