本文將介紹從瀏覽器輸入URL到服務器響應數據,中間到底經歷了哪些階段,本文將帶你完全走進網絡的世界,讓咱們從瀏覽器出入URL開始,而後一步一步的分析中間的過程。html
咱們如今輸入了一個網址,www.xxxx.com, 在介紹瀏覽器的工做方 式以前,讓咱們先來介紹一下網址。網址,準確來講應該叫 URL,若是我 說它就是以 http:// 開頭的那一串東西,恐怕你們一會兒就明白了,但實際 上除了「http:」,網址還能夠以其餘一些文字開頭,例如「ftp:」,「file:」,「mailto:」 等。git
這裏先說明一下什麼是協議:協議就是一種通訊規則的定義,好比咱們發送了一個使用http協議的數據,那麼接收方也必須使用http協議來解析數據,若是不使用http協議就識別不了該數據。web
之因此有各類各樣的 URL,是由於儘管咱們一般是使用瀏覽器來訪問Web 服務器的,但實際上瀏覽器並不僅有這一個功能,它也能夠用來在 FTP 服務器上下載和上傳文件,同時也具有電子郵件客戶端的功能。能夠 說,瀏覽器是一個具有多種客戶端功能的綜合性客戶端軟件,所以它須要 一些東西來判斷應該使用其中哪一種功能來訪問相應的數據,而各類不一樣的 URL 就是用來幹這個的,好比訪問 Web 服務器時用「http:」,而訪問 FTP 服務器時用「ftp:」。編程
下面舉例一些互聯網中的一些常見的URL,根據訪問目標的不一樣,URL的寫法也會不一樣 瀏覽器
瀏覽器要作的第一步工做就是對 URL 進行解析,從而生成發送給 Web 服務器的請求消息。剛纔咱們已經講過,URL 的格式會隨着協議的不一樣而不一樣,所以下面咱們以訪問 Web 服務器的狀況爲例來進行講解。緩存
先分析圖中a這個url,能夠看到url是先有一個http
,這個就是url使用的服務器訪問協議,瀏覽器經過分析協議來決定消息的生成方式,而後就是//
,後面跟着的是Web服務器名
,這個web服務器名就是咱們須要訪問的域名,再而後就是咱們須要訪問的數據的路徑名,可是路徑名是能夠省略的。 服務器
上圖是一個以「http:」開頭的典型 URL,但有時候咱們也會見到一些不太同樣的 URL,例以下面這個 URL 是以「/」來結尾的網絡
咱們能夠這樣理解,以「/」結尾表明 /dir/ 後面原本應該有的文件名被 省略了。根據 URL 的規則,文件名能夠像前面這樣省略。性能
不過,沒有文件名,服務器怎麼知道要訪問哪一個文件呢?其實,咱們 會在服務器上事先設置好文件名省略時要訪問的默認文件名。這個設置根 據服務器不一樣而不一樣,大多數狀況下是 index.html 或者 default.htm 之類的 文件名。所以,像前面這樣省略文件名時,服務器就會訪問 /dir/index.html 或者 /dir/default.htm。編碼
在解析完URL以後,咱們就知道應該要訪問的目標在哪裏了。接下來,瀏覽器會使用 http 協議來訪問 Web 服務器
讓咱們回到對瀏覽器自己的探索中來,對 URL 進行解析以後,瀏覽器肯定了 Web 服務器和文件名,接下來就是根據這些信息來生成 HTTP 請求消息了。實際上,HTTP 消息在 格式上是有嚴格規定
的,所以瀏覽器會按照規定的格式來生成請求消息。 ( 看下圖 ) 首先,請求消息的第一行稱爲請求行。這裏的重點是最開頭的方法,方法能夠告訴 Web 服務器它應該進行怎樣的操做。不過這裏必須先解決一 個問題,那就是方法有不少種,咱們必須先判斷應該選用其中的哪種。
解決這個問題的關鍵在於瀏覽器的工做狀態。此次探索之旅是從在瀏 覽器頂部的地址欄中輸入網址開始的,但瀏覽器並不是只有在這一種場景下 纔會向 Web 服務器發送請求消息。好比點擊網頁中的超級連接,或者在表單中填寫信息後點擊「提交」按鈕,這些場景都會觸發瀏覽器的工做,而 選用哪一種方法也是根據場景來肯定的
咱們的場景是在地址欄中輸入網址並顯示網頁,所以這裏應該使用 GET 方法。點擊超級連接的場景中也是使用 GET 方法。若是是表單,在 HTML 源代碼中會在表單的屬性中指定使用哪一種方法來發送請求,多是 GET 也 多是 POST。
頭字段類型 | 含義 |
---|---|
Date | 表示請求和響應生成的日期 |
Pragma | 表示數據是否容許緩存的通訊選項 |
Cache-Control | 控制緩存的相關信息 |
Connection | 設置發送響應以後 TCP 鏈接是否繼續保持的通訊選項 |
Transfer-Encoding | 表示消息主體的編碼格式 |
Via | 記錄途中通過的代理和網關 |
頭字段類型 | 含義 |
---|---|
Authorization | 身份認證數據 |
From | 請求發送者的郵件地址 |
If-Modified-Since | 若是但願僅當數據在某個日期以後有更新時才執 行請求,能夠在這個字段指定但願的日期。通常 來講,這個功能的用途在於判斷客戶端緩存的數 據是否已通過期,若是已通過期則獲取新的數據 |
Referer | 當經過點擊超級連接進入下一個頁面時,在這裏 會記錄下上一個頁面的 URI |
User-Agent | 客戶端軟件的名稱和版本號等相關信息 |
Accept | 客戶端可支持的數據類型(Content-Type),以 MIME 類型來表示 |
Accept-Charset | 客戶端可支持的字符集 |
Accept-Encoding | 客戶端可支持的編碼格式(Content-Encoding), 通常來講表示數據的壓縮格式 |
Accept-Language | 客戶端可支持的語言,漢語爲 zh,英語爲 en |
Host | 接收請求的服務器 IP 地址和端口號 |
If-Match | 參見 Etag |
If-None-Match | 參見 Etag |
If-Unmodified-Since | 當指定日期以後數據未更新時執行請求 |
Range | 當須要只獲取部分數據而不是所有數據時,可通 過這個字段指定要獲取的數據範圍 |
頭字段類型 | 含義 |
---|---|
Location | 表示信息的準確位置。當請求的 URI 爲相對路徑 時,這個字段用來返回絕對路徑 |
Server | 服務器程序的名稱和版本號等相關信息 |
WWW-Authenticate | 當請求的信息存在訪問控制時,返回身份認證用 的數據(Challenge) |
Accept-Ranges | 當但願僅請求部分數據(使用 Range 來指定範圍) 時,服務器會告知客戶端是否支持這一功能 |
頭字段類型 | 含義 |
---|---|
Allow | 表示指定的 URI 支持的方法 |
Content-Encoding | 當消息體通過壓縮等編碼處理時,表示其編碼格式 |
Content-Length | 表示消息體的長度 |
Content-Type | 表示消息體的數據類型,以 MIME 規格定義的數 據類型來表示 |
Expires | 表示消息體的有效期 |
Last-Modified | 數據的最後更新日期 |
Content-Language | 表示消息體的語言。漢語爲 zh,英語爲 en |
Content-Location | 表示消息體在服務器上的位置(URI) |
Content-Range | 當僅請求部分數據時,表示消息體包含的數據範圍 |
Etag | 在更新操做中,有時候須要基於上一次請求的響應 數據來發送下一次請求。在這種狀況下,這個字段 能夠用來提供上次響應與下次請求之間的關聯信息。 上次響應中,服務器會經過 Etag 向客戶端發送一 個惟一標識,在下次請求中客戶端能夠經過 If- Match、If-None-Match、If-Range 字段將這個標識 告知服務器,這樣服務器就知道該請求和上次的響 應是相關的。這個字段的功能和 Cookie 是相同的, 但 Cookie 是網(Netscape)公司自行開發的規格, 而 Etag 是將其進行標準化後的規格 |
生成 HTTP 消息以後,接下來咱們須要託操做系統將消息發送給 Web 服務器。儘管瀏覽器可以解析網址並生成 HTTP 消息,但它自己並不具有將消息發送到網絡中的功能
,所以這一功能須要委託操做系統來實現。在進行這一操做時,咱們還有一個工做須要完成,那就是查詢網址中服務器域名對應的 IP 地址。在委託操做系統發送消息時,必需要提供的不是通訊對象的域名,而是它的 IP 地址。所以,在生成 HTTP 消息以後,下 一個步驟就是根據域名查詢 IP 地址。在講解這一操做以前,讓咱們先來簡 單瞭解一下 IP 地址。
互聯網和公司內部的局域網都是基於 TCP/IP 的思路來設計的,因此我 們先來了解 TCP/IP 的基本思路。TCP/IP 的結構以下圖所示,就是由一些 小的子網,經過路由器鏈接起來組成一個大的網絡。這裏的子網能夠理解 爲用集線器鏈接起來的幾臺計算機,咱們將它看做一個單位,稱爲子網。 將子網經過路由器鏈接起來,就造成了一個網絡。 在網絡中,全部的設備都會被分配一個地址。這個地址就至關於現實 中某條路上的「×× 號 ×× 室」。其中「號」對應的號碼是分配給整個子 網的,而「室」對應的號碼是分配給子網中的計算機的,這就是網絡中的 地址。「號」對應的號碼稱爲網絡號,「室」對應的號碼稱爲主機號,這個 地址的總體稱爲 IP 地址。經過 IP 地址咱們能夠判斷出訪問對象服務器的 位置,從而將消息發送到服務器。消息傳送的具體過程在後面的章節有詳 細講解,不過如今咱們先簡單瞭解一下。發送者發出的消息首先通過子網中的集線器,轉發到距離發送者最近的路由器上。接下來, 路由器會根據消息的目的地判斷下一個路由器的位置,而後將消息發送 到下一個路由器,即消息再次通過子網內的集線器被轉發到下一個路由 器(圖 1.8 2)。前面的過程不斷重複,最終消息就被傳送到了目的地。
前面這些就是 TCP/IP 中 IP 地址的基本思路。瞭解了這些知識以後, 讓咱們再來看一下實際的 IP 地址。以下圖所示,實際的 IP 地址是一串 32 比特的數字,按照 8 比特(1 字節)爲一組分紅 4 組,分別用十進制表示 而後再用圓點隔開。這就是咱們日常常常見到的 IP 地址格式,但僅憑這一 串數字咱們沒法區分哪部分是網絡號,哪部分是主機號。在 IP 地址的規則 中,網絡號和主機號連起來總共是 32 比特,但這兩部分的具體結構是不固 定的。在組建網絡時,用戶能夠自行決定它們之間的分配關係,所以,我 們還須要另外的附加信息來表示 IP 地址的內部結構。
這一附加信息稱爲子網掩碼。子網掩碼的格式以下圖所示,是一 串與 IP 地址長度相同的 32 比特數字,其左邊一半都是 1,右邊一半都是0。其中,子網掩碼爲 1 的部分表示網絡號,子網掩碼爲 0 的部分表示主機 號。將子網掩碼按照和 IP 地址同樣的方式以每 8 比特爲單位用圓點分組後 寫在 IP 地址的右側,這就是圖下圖的方法。這種寫法太長,咱們也可 以把 1 的部分的比特數用十進制表示並寫在 IP 地址的右側,如圖下圖所示。這兩種方式只是寫法上的區別,含義是徹底同樣的。
TCP/IP是經過IP地址來肯定通訊對象的,所以不知道IP地址就沒法將消息發送給對方,這和咱們打電話的時候必需要知道對方的電話號 碼是一個道理。所以,在委託操做系統發送消息時,必需要先查詢好對方 的IP地址。
可能你會問「既然如此,那麼在網址中不寫服務器的名字,直接寫 IP 地址不就行了嗎?」實際上,若是用 IP 地址來代替服務器名稱也是可以正常工做的。然而,就像你很難記住電話號碼同樣,要記住一串由數字組成 的 IP 地址也很是困難。所以,相比 IP 地址來講,網址中仍是使用服務器名稱比較好。
那麼又有人問了:「既然如此,那乾脆不要用 IP 地址,而是用名稱來肯定 通訊對象不就行了嗎?互聯網中使用的是最新的網絡技術,和電話那種老古 董可不同,這樣的功能應該仍是作獲得的吧?」這樣的想法其實並不奇怪 。不過從運行效率上來看,這並不能算是一個好主意。互聯網中存在無數的路由器,它們之間相互配合,根據 IP 地址來判斷應該把數據傳送到什麼地方。那麼若是咱們不用 IP 地址而是改用名稱會怎麼樣呢? IP 地址的長度 爲 32 比特,也就是 4 字節,相對地,域名最短也要幾十個字節,最長甚至 能夠達到 255 字節。換句話說,使用 IP 地址只須要處理 4 字節的數字,而 域名則須要處理幾十個到 255 個字節的字符,這增長了路由器的負擔,傳送 數據也會花費更長的時間 D。可能有人會說:「那使用高性能路由器不就能解 決這個問題了嗎?」然而,路由器的速度是有極限的,而互聯網內部流動的 數據量已然讓路由器疲於應付了,所以咱們不該該再採用效率更低的設計。 隨着技術的發展,路由器的性能也會不斷提高,但與此同時,數據量也在以更快的速度增加,在可預見的將來,這樣的趨勢應該不會發生變化。出於這樣的緣由,使用名稱自己來肯定通訊對象並非一個聰明的設計。
因而,如今咱們使用的方案是讓人來使用名稱,讓路由器來使用 IP 地 址。爲了填補二者之間的障礙,須要有一個機制可以經過名稱來查詢 IP 地 址,或者經過 IP 地址來查詢名稱,這樣就可以在人和機器雙方都不作出犧牲的前提下完美地解決問題。這個機制就是 DNS。
查詢 IP 地址的方法很是簡單,只要詢問最近的 DNS 服務器「www. lab.glasscom.com 的 IP 地址是什麼」就能夠了,DNS 服務器會回答說「該 服務器的 IP 地址爲 xxx.xxx.xxx.xxx」。這一步很是簡單,不少讀者也都很 熟悉,那麼瀏覽器是如何向 DNS 服務器發出查詢的呢?讓咱們把向 Web 服務器發送請求消息的事情放一放,先來探索一下 DNS。
向 DNS 服務器發出查詢,也就是向 DNS 服務器發送查詢消息,並接收服務器返回的響應消息。換句話說,對於 DNS 服務器,咱們的計算機上 必定有相應的 DNS 客戶端,而至關於 DNS 客戶端的部分稱爲 DNS 解析器,或者簡稱解析器。經過 DNS 查詢 IP 地址的操做稱爲域名解析,所以負責執行解析(resolution)這一操做的就叫解析器(resolver)了。
解析器其實是一段程序,它包含在操做系統的 Socket 庫中,在介紹解析器以前,咱們先來簡單瞭解一下 Socket 庫。首先,庫究竟是什麼東西 呢?庫就是一堆通用程序組件的集合,其餘的應用程序都須要使用其中的 組件。庫有不少好處。首先,使用現成的組件搭建應用程序能夠節省編程 工做量;其次,多個程序使用相同的組件能夠實現程序的標準化。除此之 外還有不少其餘的好處,所以使用庫來進行軟件開發的思路已經很是普及, 庫的種類和數量也很是之多。Socket 庫也是一種庫,其中包含的程序組件可讓其餘的應用程序調用操做系統的網絡功能,而解析器就是這個庫中的其中一種程序組件。
解析器的用法很是簡單。Socket 庫中的程序都是標準組件,只要從應用 程序中進行調用就能夠了。具體來講,在編寫瀏覽器等應用程序的時候,只要像下圖這樣寫上解析器的程序名稱「gethostbyname」以及 Web 服務器的域名「www.lab.glasscom.com」 就能夠了,這樣就完成了對解析器的調用 。
調用解析器後,解析器會向 DNS 服務器發送查詢消息,而後 DNS 服務器會返回響應消息。響應消息中包含查詢到的 IP 地址,解析器會取出 IP 地址,並將其寫入瀏覽器指定的內存地址中。只要運行上圖中的這一行程序,就能夠完成前面全部這些工做,咱們也就完成了 IP 地址的查詢。接 下來,瀏覽器在向 Web 服務器發送消息時,只要從該內存地址取出 IP 地 址,並將它與 HTTP 請求消息一塊兒交給操做系統就能夠了。
順帶一提,向 DNS 服務器發送消息時,咱們固然也須要知道 DNS 服 務器的 IP 地址。只不過這個 IP 地址是做爲 TCP/IP 的一個設置項目事先設 置好的,不須要再去查詢了。不一樣的操做系統中 TCP/IP 的設置方法也有差 異,Windows 中的設置以下圖所示,解析器會根據這裏設置的 DNS 服 務器 IP 地址來發送消息。
前文介紹瞭解析器與 DNS 服務器之間的交互過程,下面來了解一下 DNS 服務器的工做。DNS 服務器的基本工做就是接收來自客戶端的查詢消息,而後根據消息的內容返回響應。
其中,來自客戶端的查詢消息包含如下 3 種信息。
域名 服務器、郵件服務器(郵件地址中 @ 後面的部分)的名稱
Class 在最先設計 DNS 方案時,DNS 在互聯網之外的其餘網絡中的應用,也被考慮到了,而 Class 就是用來識別網絡的信息。不過,現在除了互聯網並無其餘的網絡了,所以 Class 的值永遠是表明互聯網的 IN
記錄類型 表示域名對應何種類型的記錄。例如,當類型爲 A 時,表示域名 對應的是 IP 地址;當類型爲 MX 時,表示域名對應的是郵件服務器。對於不一樣的記錄類型,服務器向客戶端返回的信息也會不一樣
DNS 服務器上事先保存有前面這 3 種信息對應的記錄數據,以下圖所示。DNS 服務器就是根據這些記錄查找符合查詢請求的內容並對客戶端 做出響應的。
例如,若是要查詢 www.lab.glasscom.com 這個域名對應的 IP 地址,客 戶端會向 DNS 服務器發送包含如下信息的查詢消息。
而後,DNS 服務器會從已有的記錄中查找域名、Class 和記錄類型所有匹配的記錄。假如 DNS 服務器中的記錄如上圖所示,那麼第一行記錄與查詢消息中的 3 個項目徹底一致。因而,DNS 服務器會將記錄中的 192.0.2.226 這個值返回給客戶端。然而,Web 服務器的域名有不少都是像 www.lab.glasscom.com 這樣以 www 開頭的,但這並非必定之規,只是由於 最先設計 Web 的時候,不少 Web 服務器都採用了 www 這樣的命名,後來就 造成了一個慣例而已。所以,不管是WebServer1 也好,MySrv 也好,只要是 做爲 AA 記錄在 DNS 服務器上註冊的,均可以做爲 Web 服務器的域名。
在查詢 IP 地址時咱們使用 A 這個記錄類型,而查詢郵件服務器時則 要使用 MXC 類型。這是由於在 DNS 服務器上,IP 地址是保存在 A 記錄中 的,而郵件服務器則是保存在 MX 記錄中的。例如,對於一個郵件地址 tone@glasscom.com,當須要知道這個地址對應的郵件服務器時,咱們須要提供 @ 後面的那一串名稱。查詢消息的內容以下。
DNS 服務器會返回 10 和 mail.glasscom.com 這兩條信息。當記錄類型 爲 MX 時,DNS 服務器會在記錄中保存兩種信息,分別是郵件服務器的域名和優先級。此外,MX 記錄的返回消息還包括郵件服務器 mail.glasscom. com 的 IP 地址。上表的第三行就是 mail.glasscom.com 的 IP 地址,所以只要用 mail.glasscom.com 的域名就能夠找到這條記錄。
綜上所述,DNS 服務器的基本工做就是根據須要查詢的域名和記錄類型查找相關的記錄,並向客戶端返回響應消息。
在前面的講解中,咱們假設要查詢的信息已經保存在 DNS 服務器內部 的記錄中了。若是是在像公司內部網絡這樣 Web 和郵件服務器數量有限的 環境中,全部的信息均可以保存在一臺 DNS 服務器中,其工做方式也就完 全符合咱們前面講解的內容。然而,互聯網中存在着不可勝數的服務器,將這些服務器的信息所有保存在一臺 DNS 服務器中是不可能的,所以必定 會出如今 DNS 服務器中找不到要查詢的信息的狀況。下面來看一看此時 DNS 服務器是如何工做的。
直接說答案的話很簡單,就是將信息分佈保存在多臺 DNS 服務器中, 這些 DNS 服務器相互接力配合,從而查找出要查詢的信息。不過,這個機 制其實有點複雜,所以咱們先來看一看信息是如何在 DNS 服務器上註冊並保存的。
首先,DNS 服務器中的全部信息都是按照域名以分層次的結構來保存 的。層次結構這個詞聽起來可能有點不容易懂,其實就相似於公司中的事業集團、部門、科室這樣的結構。層次結構可以幫助咱們更好地管理大量的信息。
DNS 中的域名都是用句點來分隔的,好比 www.lab.glasscom.com,這 裏的句點表明了不一樣層次之間的界限,就至關於公司裏面的組織結構不用 部、科之類的名稱來劃分,只是用句點來分隔而已。在域名中,越靠右的 位置表示其層級越高,好比 www.lab.glasscom.com 這個域名若是按照公司 裏的組織結構來講,大概就是「com 事業集團 glasscom 部 lab 科的 www」 這樣。其中,至關於一個層級的部分稱爲域。所以,com 域的下一層是 glasscom 域,再下一層是 lab 域,再下面纔是 www 這個名字。
下面再來看一看如何找到 DNS 服務器中存放的信息。這裏的關鍵在於 如何找到咱們要訪問的 Web 服務器的信息歸哪一臺 DNS 服務器管。
互聯網中有數萬臺 DNS 服務器,確定不能一臺一臺挨個去找。咱們可 以採用下面的辦法。首先,將負責管理下級域的 DNS 服務器的 IP 地址注 冊到它們的上級 DNS 服務器中,而後上級 DNS 服務器的 IP 地址再註冊到 更上一級的 DNS 服務器中,以此類推。也就是說,負責管理 lab.glasscom.com 這個域的 DNS 服務器的 IP 地址須要註冊到 glasscom.com 域的 DNS 服務器中,而 glasscom.com 域的 DNS 服務器的 IP 地址又須要註冊到 com 域的 DNS 服務器中。這樣,咱們就能夠經過上級 DNS 服務器查詢出下級 DNS 服務器的 IP 地址,也就能夠向下級 DNS 服務器發送查詢請求了。
在前面的講解中,彷佛 com、jp 這些域(稱爲頂級域)就是最頂層了, 它們各自負責保存下級 DNS 服務器的信息,但實際上並不是如此。在互聯網 中,com 和 jp 的上面還有一級域,稱爲根域。根域不像 com、jp 那樣有自 己的名字,所以在通常書寫域名時常常被省略,若是要明確表示根域,應該像 www.lab.glasscom.com. 這樣在域名的最後再加上一個句點,而這個最 後的句點就表明根域。不過,通常都不寫最後那個句點,所以根域的存在 每每被忽略,但根域畢竟是真實存在的,根域的 DNS 服務器中保管着 com、jp 等的 DNS 服務器的信息。因爲上級 DNS 服務器保管着全部下級 DNS 服務器的信息,因此咱們能夠從根域開始一路往下順藤摸瓜找到任意 一個域的 DNS 服務器。
除此以外還須要完成另外一項工做,那就是將根域的 DNS 服務器信息保 存在互聯網中全部的 DNS 服務器中。這樣一來,任何 DNS 服務器就均可 以找到並訪問根域 DNS 服務器了。所以,客戶端只要可以找到任意一臺 DNS 服務器,就能夠經過它找到根域 DNS 服務器,而後再一路順藤摸瓜 找到位於下層的某臺目標 DNS 服務器(以下圖)。分配給根域 DNS 服務器 的 IP 地址在全世界僅有 13 個 A,並且這些地址幾乎不發生變化,所以將這 些地址保存在全部的 DNS 服務器中也並非一件難事。實際上,根域 DNS 服務器的相關信息已經包含在 DNS 服務器程序的配置文件中了,因 此只要安裝了 DNS 服務器程序,這些信息也就被自動配置好了。
收到客戶端的查詢消息以後,DNS 服務器會按照前面的方法來查詢 IP 地址,並返回給客戶端。這樣,客戶端就知道了 Web 服務器 的 IP 地址,也就可以對其進行訪問了。
知道了 IP 地址以後,就能夠託操做系統內部的協議棧向這個目標 IP 地址,也就是咱們要訪問的 Web 服務器發送消息了。要發送給 Web 服務 器的HTTP消息是一種數字信息(digital data),所以也能夠說是託協議 棧來發送數字信息。收發數字信息這一操做不只限於瀏覽器,對於各類使 用網絡的應用程序來講都是共通的。所以,這一操做的過程也不只適用於 Web,而是適用於任何網絡應用程序。下面就來一塊兒探索這一操做的過程。
和向 DNS 服務器查詢 IP 地址的操做同樣,這裏也須要使用 Socket 庫中 的程序組件。不過,查詢 IP 地址只須要調用一個程序組件就能夠了,而這 裏須要按照指定的順序調用多個程序組件,這個過程有點複雜。發送數據是 一系列操做相結合來實現的,若是不能理解這個操做的全貌,就沒法理解其 中每一個操做的意義。所以,咱們先來介紹一下收發數據操做的總體思路。
使用 Socket 庫來收發數據的操做過程以下圖所示。簡單來講,收發數據的兩臺計算機之間鏈接了一條數據通道,數據沿着這條通道流動,最終到達目的地。咱們能夠把數據通道想象成一條管道,將數據從一端送入 管道,數據就會到達管道的另外一端而後被取出。數據能夠從任何一端被送入管道,數據的流動是雙向的。不過,這並非說現實中真的有這麼一條管道,只是爲了幫助你們理解數據收發操做的全貌。
收發數據的總體思路就是這樣,但還有一點也很是重要。光從圖上來 看,這條管道好像一開始就有,實際上並非這樣,在進行收發數據操做 以前,雙方須要先創建起這條管道才行。創建管道的關鍵在於管道兩端的 數據出入口,這些出入口稱爲套接字。咱們須要先建立套接字
,而後再將 套接字鏈接起來造成管道。實際的過程是下面這樣的。首先,服務器一方 先建立套接字,而後等待客戶端向該套接字鏈接管道。當服務器進入等待狀態時,客戶端就能夠鏈接管道了。具體來講,客戶端也會先建立一個套 接字,而後從該套接字延伸出管道,最後管道鏈接到服務器端的套接字上。 當雙方的套接字鏈接起來以後,通訊準備就完成了。接下來,就像咱們剛 剛講過的同樣,只要將數據送入套接字就能夠收發數據了。