助記提要
- 服務器程序的結構
- 套接字的指代方式
- MAC模塊的接收過程
- IP模塊的接收過程
- TCP模塊處理連接包
- TCP模塊處理數據包
- TCP模塊的斷開操作
- URI轉換為實際文件路徑
- URI調用程序
- Web服務器訪問控制
- 響應內容的類型
6章 請求到達服務器,響應返回瀏覽器
1 服務器概覽
在數據收發層面,不需要區分客戶端和服務器。連接操作上需要區分:發起連接的是客戶端,等待連接的是服務器。
服務器和客戶端的網絡相關的組件是相同的,但用法不同。
服務器可以與多臺客戶端通信,它的程序結構和客戶端也不同。
1.1 服務器程序結構
服務器程序分為等待連接模塊和與客戶端通信的模塊。程序啟動并完成初始化后,就運行等待連接模塊,創建套接字后進入等待連接的暫停狀態。
客戶端發起連接時,該模塊恢復運行,并接受連接,啟動客戶端通信模塊,并移交完成連接的套接字。
客戶端通信模塊使用已連接的套接字和客戶端進行通信。通信結束后,通信模塊會退出。
每次有新的客戶端發起連接,都會啟動一個新的客戶端通信模塊,與客戶端是一對一的關系。
1.2 服務器程序調用socket庫的通信操作
accept接受到客戶端的包時,協議棧會給等待連接的套接字復制一個副本,并把連接對象等控制信息寫到新的套接字中。這時等待連接模塊會啟動客戶端通信模塊,并將套接字副本會轉交給客戶端通信模塊。
1.3 多個套接字副本的端口號
復制出套接字副本后,原先的套接字仍然處于等待連接狀態。新的客戶端的包到達時,它又會執行接受連接操作,再次復制一個套接字副本。
- 套接字的指代方式
新創建的套接字副本和原來等待連接的套接字具有一樣的的端口號,以讓客戶端判斷收到的包是正確的程序發來的,比如http的連接套接字都使用80端口號。但是當客戶端的包到達時,服務器僅憑接收方端口號無法判斷該把包交給哪一個套接字。
服務器的套接字可能有相同的端口號,但是客戶端的套接字都是對應不同的端口號的。因此能通過客戶端的端口號確定服務器上的某個套接字。
在有多個客戶端時,不同客戶端的端口號可能是重復的,所以必須再加上客戶端的IP地址才能判斷。
IP頭部和TCP頭部包含了4項信息:接收方IP、接收方端口號、發送方IP、發送方端口號。通過這4項信息就能確定某個套接字。
- 描述符指代套接字
描述符也用來指代套接字。因為在等待連接的時候,沒有客戶端IP和端口號。而且描述符僅使用一種信息,表示起來比4種信息簡單。
2 服務器的接收操作
2.1 網卡把信號還原為數字信息
- 從報頭讀取識別時鐘信號,按相同的周期延長時鐘信號;
- 在每個時鐘周期位置檢測信號的變化方向,根據信號變化方向還原出0和1;
- 根據校驗公式計算數字信息,與包尾的幀校驗序列比較;如果不一致,說明數據錯誤,包會被丟棄(TCP檢測到丟包后會自動處理)。
- 校驗成功后,就檢查MAC頭部的接收方MAC地址,確認這個包是發給自己的。
- 都確認無誤后,把數字信息保存在網卡的緩沖區中。
- 網卡通過中斷,告知CPU有網絡包到達;
- CPU切換到網卡驅動程序,從網卡緩沖區讀取包,根據MAC頭部的以太類型字段判斷協議種類,然后交給相應的協議棧。
2.2 IP模塊接收步驟
- 檢查IP頭部格式是否符合規范;
- 查看接收方IP地址是不是自己;
- 檢查包有沒有被分片,如果是分片的包,就把包暫存在內存中,等所有分片到達后組裝為原始包。
- 檢查IP頭部的協議號字段,交給對應的模塊。如協議號為06交給TCP模塊,協議號為11交給UDP模塊。
2.3 TCP模塊的操作
TCP模塊處理連接包
TCP模塊發現TCP頭部控制位的SYN為1時,說明是一個發起連接的包。
- TCP模塊檢查包的接收方端口號,看該端口上有沒有正處于等待連接狀態的套接字。如果沒有等待連接的套接字,則像客戶端返回錯誤通知。
- 如果存在等待連接的套接字,就為這個套接字復制一個新的副本,將發送方IP、端口、序號初始值、窗口大小等信息寫入這個套接字,并分配用于發送緩沖區和接收緩沖區的內存空間。
- 生成代表確認的ACK號,和發送數據的序號初始值、接收緩沖區的窗口大小等信息生成TCP頭部,委托IP模塊發給客戶端。
- 客戶端收到后,返回表示確認的ACK號。ACK號到達服務器后,連接就完成了。
TCP模塊處理數據包
- 根據包的IP頭部的發送方IP、接收方IP,和TCP頭部的接收方端口、發送方端口找到數據包對應的套接字。
- 根據套接字中保存的上一個序號和數據長度計算下一個序號,檢查該序號和包的TCP頭部中的序號是否一致。一致說明包未丟失,這時TCP模塊從包中提取數據放到接收緩沖區,和之前的數據連接起來。
- 數據進入接收緩沖區后,TCP模塊生成確認應答的TCP頭部,根據接收包的序號和數據長度計算出ACK號,委托IP模塊發給客戶端。
- 應用程序調用read,TCP模塊把接收緩沖區的數據轉交給應用程序。
TCP模塊的斷開操作
- 服務器程序調用close時,TCP模塊生成控制位FIN為1的TCP頭部,委托IP模塊發送給客戶端;
- 客戶端收到后,返回一個ACK號,確認收到;
- 客戶端調用close,生成一個FIN為1的TCP頭部發送給服務器;
- 服務器返回ACK號,完成斷開操作。對應的套接字一段時間后會被刪除。
3 Web服務器程序解釋請求消息并作出響應
3.1 URI轉換為實際文件名
請求消息中包括請求方法和表示數據源的URI,服務器程序根據這些信息向客戶端返回數據。
Web服務器公開的目錄不是磁盤上的實際目錄,而是虛擬目錄。URI中寫的就是在虛擬目錄結構下的路徑名。在讀取文件時,需要先查詢虛擬目錄與實際目錄的對應關系,并將URI轉換成實際的文件名,才能讀取并返回數據。
URI中省略文件名時,服務器會讀取預先設定好的默認文件名。
可以設置文件名改寫規則,在URI中的路徑符合改寫規則時,將URI中的文件名改寫為其他文件名進行訪問。這在服務器的目錄和文件發生變化并且需要用戶通過原來的網址訪問時很有用。
3.2 CGI程序
URI指定的文件內容不一定是HTML文檔,也可能時一個程序。這時服務器會運行這個程序,然后將程序的輸出返回給客戶端。
瀏覽器將需要服務器程序處理的數據放在HTTP請求消息中發送給服務器。數據加在HTTP消息中的兩種方法,一是通過GET方法,把輸入的數據作為參數添加在URI后面;二是通過POST方法,把數據放在HTTP請求體中發送給服務器。
收到請求消息后,Web服務器檢查URI指定的文件名是不是程序。如果是程序,Web服務器會委托操作系統運行這個程序,然后從請求消息中取出數據交給該程序。
程序處理后,輸出結果一般會嵌入HTML中。Web服務器將其作為響應消息返回給客戶端。
3.3 Web服務器訪問控制
訪問控制可以根據預先設定的規則,允許或禁止訪問。
收到請求時,服務器根據URI判斷數據源,并檢查數據源對應的訪問控制規則,只有允許訪問時才讀取文件或運行程序。
根據IP地址控制
接受連接時就能知道客戶端的IP地址,可以檢查是否允許訪問。
根據客戶端域名控制
先根據IP地址向DNS服務器查詢客戶端域名,然后再用該域名查詢一下IP地址,看結果是否和發送方IP一致。如果一致則檢查對應的訪問控制規則。
這種方式需要和DNS服務器做多次查詢,會使Web服務器響應速度變慢。
有一種在DNS服務器上注冊假域名的攻擊方式,因此需要雙重檢查。
根據用戶名和密碼控制
收到需要用戶名和密碼的訪問時,Web服務器會向客戶端發送一條響應消息,告訴用戶需要在請求消息中放入用戶名和密碼。
瀏覽器收到該消息,會彈出輸入用戶名和密碼的窗口,用戶輸入用戶名和密碼后,瀏覽器把這些消息放入請求消息中重新發給服務器。
服務器檢查收到的用戶名和密碼,與注冊的信息一致時,才返回數據。
3.4 做出響應
Web服務器調用write,把響應消息交給協議棧,告訴協議棧這個消息對應的套接字。
協議棧會把數據拆分為多個包,加上頭部發出去。
4 瀏覽器接收響應消息并顯示內容
4.1 通過響應的數據類型判斷內容
Web可以處理很多類型的數據,每種類型的顯示方法都不同。
可以根據響應消息的頭部字段Content-Type判斷數據類型。
Content-Type: 主類型/子類型; charset=utf-8
Content-Type定義的數據類型:
主類型 | 含義 | 子類型 |
---|---|---|
text | 文本數據 | html,HTML文檔; plain,純文本; |
image | 圖像數據 | jpeg,JPEG格式圖片; gif,GIF格式圖片; |
audio | 音頻數據 | mpeg,MP2、MP3格式的音頻; |
video | 視頻數據 | mpeg,MPEG格式的視頻; quicktime,Quicktime格式的視頻; |
model | 對物體的形狀和動作進行建模的數據 | vrml,VRML格式的建模數據; |
application | 應用程序數據 | pdf,PDF文檔數據; msword,MS-WORD格式的文檔數據; |
message | 直接存放郵件等消息時使用的類型 | rfc822,一般的郵件數據,包含From、Date等頭部數據; |
multipart | 消息體中包含多個部分的數據 | mixed,消息體中包含不同格式的數據,其中每部分數據都有單獨定義的媒體類型; |
當數據類型為文本時,需要用charset附加文本的編碼信息。utf-8表示Unicode,euc-jp表示EUC編碼,ISO-022-jp表示JIS編碼,shift_jis表示JIS編碼。
如果消息的內容是通過壓縮或編碼技術轉換過的,還需要檢查Content-Encoding字段,得知如何將消息中的數據還原為原始數據。
4.2 瀏覽器在網頁顯示內容
HTML文檔按照標簽表示文檔的布局和字體等樣式信息。瀏覽器解釋這些標簽,并按照指定的樣式顯示文檔內容。
HTML文檔中有表示圖片和視頻的標簽。瀏覽器遇到這些標簽時,會向服務器請求其中的圖片或視頻數據。Web服務器返回數據后,瀏覽器解壓該數據,然后委托操作系統顯示。
Web服務器還會返回一些應用程序的數據,瀏覽器會調用相應的程序,或者是自身的插件。不同類型的數據和不同程序的對應關系在瀏覽器中已經設置好了。
顯示操作實際上是操作系統完成的,瀏覽器負責對系統發出指令。