網路是怎樣連線的-第一章-委託協議棧傳送訊息
1.4 委託協議棧傳送訊息
1.4.1 資料收發操作概覽
獲得 IP 地址後,就可以委託作業系統內部的協議棧向這個目標 IP地址,也就是我們要訪問的 Web 伺服器傳送訊息。
要傳送給 Web 伺服器的 HTTP 訊息是一種數字資訊(digital data),因此也可以說是委託協議棧來發送數字資訊。
這一操作的過程也不僅適用於Web,而是適用於任何網路應用程式。和向 DNS 伺服器查詢 IP 地址的操作一樣,這裡也需要使用 Socket 庫中的程式元件。
向作業系統內部的協議棧發出委託時,需要按照指定的順序來呼叫 Socket 庫中的程式元件。
收發資料操作的整體思路
使用 Socket 庫來收發資料的操作過程如下圖所示 。圖中展示的是用 TCP 協議來收發資料的過程,還有另外一種名為UDP的協議
簡單來說,收發資料的兩臺計算機之間連線了一條資料通道,資料沿著這條通道流動,最終到達目的地。
在進行收發資料操作之前,雙方需要先建立起這條管道才行。
建立管道的關鍵在於管道兩端的資料出入口,這些出入口稱為套接字。
我們需要先建立套接字,然後再將套接字連線起來形成管道。
建立連線的具體流程
首先,伺服器一方先建立套接字,然後等待客戶端向該套接字連線管道。當伺服器進入等待狀態時,客戶端就可以連線管道了。
客戶端也會先建立一個套接字,然後從該套接字延伸出管道,最後管道連線到伺服器端的套接字上。
當雙方的套接字連線起來之後,通訊準備就完成了。接下來只要將資料送入套接字就可以收發資料。
收發資料操作結束時的情形
當資料全部發送完畢之後,連線的管道將會被斷開。
管道在連線時是由客戶端發起的,但在斷開時可以由客戶端或伺服器任意一方發起。
其中一方斷開後,另一方也會隨之斷開,當管道斷開後,套接字也會被刪除。
到此為止,通訊操作就結束了。
收發資料操作總結
綜上所述,收發資料的操作分為若干個階段,可以大致總結為以下 4 個。
(1)建立套接字(建立套接字階段)
(2)將管道連線到伺服器端的套接字上(連線階段)
(3)收發資料(通訊階段)
(4)斷開管道並刪除套接字(斷開階段)
在每個階段,Socket 庫中的程式元件都會被呼叫來執行相關的資料收發操作。
前面這4個操作都是由作業系統中的協議棧來執行的,瀏覽器等應用程式並不會自己去做連線管道、放入資料這些工作,而是委託協議棧來代勞。
本章將要介紹的只是這個“委託”的操作。關於協議棧收到委託之後具體是如何連線管道和放入資料的,我們將在第 2 章介紹。
這些委託的操作都是通過呼叫 Socket 庫中的程式元件來執行的,但這些資料通訊用的程式元件其實僅僅充當了一個橋樑的角色,並不執行任何實質性的操作,應用程式的委託內容最終會被原原本本地傳遞給協議棧。
因此,後文將會採用 將 Socket 庫和協議棧看成一個整體的講法,讓人更容易理解。不要忘記Socket 庫這一橋樑的存在。
1.4.2 建立套接字階段
應用程式委託收發資料的過程
需要按照一定的順序呼叫若干個程式元件,過程如下圖所示。
套接字建立階段
客戶端建立套接字的操作非常簡單,只要呼叫 Socket 庫中的 socket 程式元件就可以了(圖 1.18 ①)。
呼叫 socket 之後,控制流程會轉移到 socket 內部並執行建立套接字的操作,完成之後控制流程又會被移交回應用程式。
第2章會細講解這部分。只要知道呼叫 socket 後套接字就建立好了就可以了。
協議棧返回給應用程式描述符
套接字建立完成後,協議棧會返回一個描述符應用程式會將收到的描述符存放在記憶體中。
描述符是用來識別不同的套接字的。
當建立套接字後,我們就可以使用這個套接字來執行收發資料的操作了。
這時,只要我們出示描述符,議棧就能夠判斷出我們希望用哪一個套接字來連線或者收發資料了。
1.4.3 連線階段:把管道接上去
我們需要委託協議棧將客戶端建立的套接字與伺服器那邊的套接字連線起來。
應用程式通過呼叫 Socket 庫中的名為 connect 的程式元件來完成這一操作。這裡的要點是當呼叫 connect 時,需要指定描述符、伺服器 IP 地址和埠號這 3 個引數,如上圖②所示。
Connect的三個引數
描述符
是在建立套接字的時候由協議棧返回的那個描述符。
connect 會將應用程式指定的描述符告知協議棧,然後協議棧根據這個描述符來判斷到底使用哪一個套接字去和伺服器端的套接字進行連線,並執行連線的操作。
IP 地址
就是通過 DNS 伺服器查詢得到的要訪問的伺服器的 IP 地址。
埠號
描述符是和委託建立套接字的應用程式進行互動時使用的,並不是用來告訴網路連線的另一方的,因此另一方並不知道這個描述符。
我們需要另外一個對客戶端也同樣適用的機制,而這個機制就是埠號。
如果說描述符是用來在一臺計算機內部識別套接字的機制,那麼埠號就是用來讓通訊的另一方能夠識別出套接字的機制 。
埠號的執行機制
只要指定了事先規定好的埠號,就可以連線到相應的伺服器程式的套接字。
也就是說,瀏覽器訪問 Web 伺服器時使用 80 號埠,這是已經規定好的。
客戶端在建立套接字時,協議棧會為這個套接字隨便分配一個埠號。
當協議棧執行連線操作時,會將這個隨便分配的埠號通知給伺服器。
描述符
應用程式用來識別套接字的機制
IP 地址和埠號
客戶端和伺服器之間用來識別對方套接字的機制
總結
呼叫 connect 時,協議棧就會執行連線操作。
當連線成功後,協議棧會將對方的 IP 地址和埠號等資訊儲存在套接字中,這樣我們就可以開始收發資料了。
1.4.4 通訊階段:傳遞訊息
將資料送入套接字,資料就會被髮送到對方的套接字中應用程式無法直接控制套接字,因此還是要通過 Socket 庫委託協議棧來完成這個操作。
write元件指定描述符和要傳送的資料
這個操作需要使用 write 這個程式元件,具體過程如下。
①應用程式需要在記憶體中準備好要傳送的資料。根據使用者輸入的網址生成的 HTTP 請求訊息就是我們要傳送的資料。
②當呼叫 write時,需要指定描述符和傳送資料,如上圖③所示。
③協議棧將資料傳送到伺服器。
由於套接字中已經儲存了已連線的通訊物件的相關資訊,
所以只要通過描述符指定套接字,就可以識別出通訊物件,並向其傳送資料。
伺服器接收後向客戶端返回響應訊息
④傳送資料會通過網路到達我們要訪問的伺服器。
⑤伺服器執行接收操作,解析收到的資料內容並執行相應的操作,向客戶端返回響應訊息。
當訊息返回後,需要執行的是接收訊息的操作。
客戶端接收訊息呼叫read元件
接收訊息的操作是通過 Socket 庫中的 read 程式元件委託協議棧來完成的,如上圖③所示。
呼叫read 時需要指定用於存放接收到的響應訊息的記憶體地址,這一記憶體地址稱為接收緩衝區。
⑥當伺服器返回響應訊息時,read 就會負責將接收到的響應訊息存放到接收緩衝區中。
由於接收緩衝區是一塊位於應用程式內部的記憶體空間,因此當訊息被存放到接收緩衝區中時,就相當於已經轉交給了應用程式。
1.4.5 斷開階段:收發資料結束
當瀏覽器收到資料之後,收發資料的過程就結束了。接下來,我們需要呼叫 Socket 庫的 close 程式元件進入斷開階段如上圖 ④。
最終,連線在套接字之間的管道會被斷開,套接字本身也會被刪除。
斷開的過程
Web 使用的 HTTP 協議規定,當 Web 伺服器傳送完響應訊息之後,應該主動執行斷開操作
①Web 伺服器會首先呼叫close 來斷開連線。
②斷開操作傳達到客戶端之後,客戶端的套接字也會進入斷開階段。
③當瀏覽器呼叫 read 執行接收資料操作時,read 會告知瀏覽器收發資料操作已結束,連線已經斷開。瀏覽器得知後,也會呼叫close 進入斷開階段。
註釋
根據應用種類不同,客戶端和伺服器哪一方先執行 close 都有可能。
有些應用中是客戶端先執行 close,而另外一些應用中則是伺服器先執行 close。
圖片等檔案的請求過程
HTTP 協議將 HTML 文件和圖片都作為單獨的物件來處理,每獲取一次資料,就要執行一次連線、傳送請求訊息、接收響應訊息、斷開的過程。
因此後來人們又設計出了能夠在一次連線中收發多個請求和響應的方法。
在 HTTP 版本 1.1 中就可以使用這種方法,在這種情況下,當所有資料都請求完成後,瀏覽器會主動觸發斷開連線的操作。
第一章小測驗
1. http://www.nikkeibp.co.jp/ 中的 http 代表什麼意思?
http是網路協議名稱
2. 下面兩個網址有什麼不同?
a. http://www.nikkeibp.co.jp/sample
b. http://www.nikkeibp.co.jp/sample/
a可能訪問的是sample目錄以及其下的預設主頁,也可能是名為sample的檔案。而b就是訪問域名下sample目錄下的預設主頁
3. 用來識別連線在網際網路上的計算機和伺服器的地址叫什麼?
IP地址
4. 根據Web伺服器的域名來查詢IP地址時所使用的伺服器叫什麼?
DNS伺服器
5. 向 DNS 伺服器傳送請求訊息的程式叫什麼?
解析器