---
tags: 電腦網路, 大二筆記
---
# 電腦網路 Chapter 2 : Application Layer
## Principles of Network Applications
### 網路應用程式架構 Network Application Architecture
#### 主從式架構 Clinent-server Architecture
* 主從式架構中,一定有個 **伺服器 (Server)** 來服務 **客戶端 (Client)** 所發送來的請求
* 伺服器 Server
* 不會關機
* 擁有固定的 IP 位址
* 通常位於 **資料中心 (data center)**,以提供大量的流量服務
* 客戶端 Client
* 向伺服器端發送請求
* 浮動 IP 位址
* 每個客戶端無法互相溝通
* 基於主從式架構的服務:HTTP, FTP, Email
#### 對等式架構 Peer-to-peer Architecture
* 不需要依賴資料中心的伺服器,而是對等的主機互相連接,因而稱為 **peer-to-peer (P2P)**
* 去中心化,在資源的使用上較有效率,但是缺乏安全性
* P2P 具備 **自我擴展性能 (Self Scalabiliity)**,可根據需求自動調整以實現更高的可擴展性和性能
* 主機間的 IP 會浮動,所以常常會使用混和式架構:伺服器用以追蹤各個客戶端的 IP,而通信則是使用 P2P 的方式在電腦間互傳
### 程序間溝通 Processes Communicating
* 兩個執行在不同終端裝置上的 **程序 (Process)** 需要透過網路來交換 **訊息 (Message)**
* 會有專門的程序將訊息發送到網路上,也有專門收訊息的程序
#### Client and Server Processes
* 我們將兩個進行通訊的程序分為 **客戶端 (Client)** 和 **伺服器端 (Server)**
> 無論是在主從式架構或是 P2P 都是以這種方式,發起通訊的電腦會被定義為 **客戶端**
#### 插座 Socket
* 兩個網路應用程式透過網路傳遞訊息使用的介面
* 應用程式將訊息由 Socket 送出至傳輸層,而傳輸層會幫助將訊息送到目的地;收信方也需要透過自己的 Socket 去收取信息

* 可以看到 Socket 是位於應用層和傳輸層中間溝通的介面,因此又稱為應用程式與網路間的 **應用程式介面 (Application Programming Interface, API)**
* 開發者只對應用層有操控權,上到傳輸層就由系統控制
#### Addressing Processes
* 電腦傳輸信息時,除了需要知道收信端程序的位址,還要知道是哪個程序要收信。因此程序需要一個 **識別符 (Identifier)**:
* 識別符內容包含:
* **IP 位址**:收信電腦的位址
* **埠號 (Port)**:用以辨別收信的程序 (準確來說是 Socket)
#### 應用層協議 Application-layer Protocol
* 協定內容:
* 交換訊息的形式
* request, response...
* 訊息的語法
* 有哪些欄位,欄位怎麼分配
* 訊息的語意
* 欄位代表的意義
* 規則
* 送出或接收到訊息後要做的事情
* Open Protocol
* 通用的協定,大家都可以通用
* HTTP, SMTP
* Proprietary Protocol
* 私人的協議
* Skype
### Transport Services Available to Applications
傳輸層協定提供的程式服務大致分為四個面向:
#### 資料完整性 Data Integrity
* 有些應用程式不能遺失封包,例如網路銀行轉帳
* 有些協議能提供某種機制,保證封包能完整到達目的地,我們稱他提供 **可靠的資料傳輸 (Reliable Data Transfer)**
* 不是每個應用程式都需要,例如大部分的語音及視訊通話,掉包頂多延遲而已
#### 吞吐量 Throughput
* 一些應用程式需要一定的吞吐量來維持品質,如語音通話
* 這種對吞吐量有要求的應用程式我們稱為 **對頻寬敏感的應用 (Bandwidth-sensitive Application)**
* 而相對的 **有彈性的應用程式 (Elastic Application)** 對吞吐量的要求不大,有多少用多少。如:網頁服務、Email
#### 時間差 Timing
* 網路遊戲、網路電話這種需要低網路延遲的應用程式,就需要保證其封包傳輸的時間差
#### 安全性 Security
* 傳輸層協定可以提供跟安全性有關的服務
* 加密、資料完整性和終端身分驗證
> 這裡的資料完整性比較像是:確保資訊不受未授權的竄改或在竄改後能及時被發現
|應用服務|是否能忍受掉包|對吞吐量的需求|對最大時差是否有要求|
|:-:|:-:|:-:|:-:|
|**檔案傳輸/下載服務**|不能掉包|沒有特殊需求|沒有要求|
|**Email**|不能掉包|沒有特殊需求|沒有要求|
|**網頁服務**|不能掉包|沒有特殊需求(只會用固定幾 kbps)|沒有要求|
|**網路電話/視訊會議**|可以掉包|音訊: few kbps - 1 Mbps<br>影片: 10 kbps - 5 Mbps|不得超過 100 msec|
|**影音串流**|可以掉包|同上|不能超過數秒|
|**互動式遊戲**|可以掉包|few kbps - 10 kbps|不得超過 100 msec|
|**文字訊息**|不能掉包|沒有特殊需求|有時有有時沒有|
### Transport Services Provided by the Internet
#### TCP Service
* 可靠的資料傳輸 Reliable Transport
* TCP 可以確保傳送出去的資料都能完整的並按照順序送到收信端
* 流量控制 Flow Control
* 保證收發兩端的傳輸速度保持一致
* 壅塞控制 Congestion Control
* 將長度過長的訊息切小,壅塞時自動降速
* 連線導向的服務 Connection-oriented Service
* TCP 規定兩台電腦傳遞訊息 **之前**,要先進行 **交握 (Handshaking)**
* 當交握完成,我們會說一個 **TCP 連線** 存在於雙方的 **Socket** 之間
* 為 **全雙工 (Full-duplex)** 的連線,雙方可以同時傳訊息給對方
* 傳輸完成後,連線就必須關閉
* **並沒有** 提供
* 時間差
* 最低頻寬保證
* 安全性
#### UDP Service
* 提供最輕量化的傳輸協定,講難聽點就是啥都沒有
* 資料傳輸前不需要交握,也沒有可靠的資料傳輸
* 代表把資料丟進 UDP 的 Socket,不保證資料一定能到對方手上,順序也無法保證
* **沒有** 提供
* 可靠的資料傳輸
* 流量控制
* 壅塞控制
* 連線的建立
* TCP 沒有的服務
|應用服務|應用層協定|底下的傳輸層協定|
|-|-|-|
|**電子郵件**|SMTP [RFC 5321]|TCP|
|**遠端終端機存取**|Telnet [RFC 854]|TCP|
|**網頁服務**|HTTP [RFC 2616]|TCP|
|**檔案傳輸**|FTP [RFC 959]|TCP|
|**多媒體串流**|HTTP (e.g., Youtube)|TCP|
|**網路電話**|SIP [RFC 3261], RTP [RFC 3550],或是專有軟體 (e.g., Skype)|UDP or TCP|
電子郵件、終端機存取、網頁服務及檔案傳輸都無法容忍掉包,需要可靠的資料傳輸,因此選用 TCP;而網路電話可以容忍掉包,但對於最小傳輸速率有要求,因而使用 UDP,可以規避一些 TCP 的流量控制及壅塞控制
#### Securing TCP
可以發現,原本的 TCP 是沒有加密服務的,那上傳密碼不就被看光光
* 傳輸層安全協定 Trnasport Layer Security, TLS
* 提供加密的 TCP 連線
* 資料完整性 (Data Integrity)
> 確保信息沒有遭竄改
* 提供端點認證 (End-point Authentication)
## Web and HTTP
### HTTP Overview
超文本傳輸協定 (HyperText Transfer Protocol, HTTP),為網頁所使用的應用層協定
* **網頁 (Web Page)**,由多個物件組成
* **物件 (Object)** 是一個簡單的檔案,例如:HTML頁面、圖片或影片。每個物件都能用一個 **URL** 來定址
* 大部分網頁都由一個 **Base HTML-file** 和多個被 **參照 (referenced)** 的物件組成
* **URL** 用以參照物件,每個 URL 都有兩個部分
* 主機名稱 (下圖的 ```www.someSchool.edu```)
* 檔案路徑 (下圖的 ```someDepartment/picture.gif```)
```
http://www.someSchool.edu/someDepartment/picture.gif
```
* 網頁瀏覽器 (Web Browser) 為 HTTP 的客戶端,用來發送 **請求 (Request)**,接收並顯示網頁物件
* 網頁伺服器 (Web Server) 為 HTTP 的伺服器端,用來存放物件,並在接受到請求後發送 **回應 (Response)**

* HTTP 使用 TCP 協定,因此 HTTP 訊息一發送,絕對會送到對方手中,也不用擔心順序問題
* HTTP 為 **無狀態的協定 (Stateless Protocol)**,並不會記錄客戶端的狀態
> 這就是為什麼打開一個網頁用 F12 亂改後,重新整理網頁又會恢復如初
### HTTP Connections
#### 非持續性的連線 Non-persistent HTTP
* 一次 TCP 連線只會傳送一個物件,因此當要下載多個物件時,就需要建立多個連線
* 假設有一個網頁由一個 base HTML file 和 10 個圖片所組成,11 個物件都放在同台主機上, base HTML file 的網址為:
```
http://www.someSchool.edu/someDepartment/home.index
```
那整個傳輸過程就會是:
1. HTTP 客戶端的程式會要求對 `www.someSchool.edu` 這個主機發起一個 TCP 連線,指定埠號 80
> 80 為 HTTP 協定預設的埠號
2. HTTP 伺服器端回復客戶端,同意連接
3. 客戶端會透過 Socket 送出一個 **HTTP 請求訊息** 到伺服器端,請求包含 `someDepartment/home.index` 這個名稱
4. 伺服器端收到這則 HTTP 訊息後,就會找出 `someDepartment/home.index` 這個物件,將其封裝為 **HTTP 回應訊息**,再藉由 Socket 送出這則訊息回客戶端
5. 確認客戶端收到後,伺服器關閉 TCP 連線
6. 客戶端收到回應訊息,TCP 連線關閉,將回應訊息中的檔案 (HTML) 抽出來,檢查 HTML 檔案,在當中尋找到 10 個圖片的參照
7. 重複以上的動作直到取得每一個圖片
* 上述的例子中,每傳完一個物件,TCP 連線就會被關閉,因此像這次有 11 個物件要傳,就會建立 11 個 TCP 連線
* **往返時間 (Round-trip Time, RTT)**:封包由客戶端送出抵達伺服器端,再從伺服器端回來所需的時間
* 以這個例子來講,網頁的傳輸大概需要兩個 RTT 外加網頁的傳輸時間

* 缺點:非持續性連線每次傳一個物件就需要一個新的 TCP 連線,而每次傳輸都要耗費兩個 RTT,非常浪費資源,因此才有下面的持續性連線
#### 持續性的連線 Persistent HTTP
* 一個連線可以傳送多個物件
* 可以實現 **管線化 (Pipelining)**
### HTTP Message Format
分為請求訊息和回應訊息
#### HTTP Request Message
HTTP 請求訊息:
```
GET /somedir/page.html HTTP/1.1
Host: www.someschool.edu
Connection: close
User-agent: Mozilla/5.0
Accept-language: fr
```
* 第一行為 **請求行 (Request Line)**,分為三個欄位:
* 方法欄位:有以下幾種
* GET 從伺服器傳送資料要求
* POST 建立或取代伺服器上的資源
* HEAD 擷取伺服器的 HTTP 回應標頭
* PUT 更新伺服器上的資源
* DELETE 從伺服器中刪除資源
* URL 欄位:要請求一個物件的時候,物件的位址就會寫在 URL 欄位
* HTTP 版本號欄位
* 第二行以下都是 **標頭行 (Header Lines)
* `Host: www.someschool.edu`:說名要請求的物件是被放在 `www.someschool.edu` 這個主機上
* `Connection: close`:回復這個請求後就將連線關閉
* `User-agent: Mozilla/5.0`:說明是哪種 user agent,也就是甚麼種類的瀏覽器,這個例子中,請求是由 Firefox 發出的
* `Accept-language: fr`:使用者想看到的語言

#### HTTP Response Message
```
HTTP/1.1 200 OK
Connection: close
Date: Tue, 18 Aug 2015 15:44:04 GMT
Server: Apache/2.2.3 (CentOS)
Last-Modified: Tue, 18 Aug 2015 15:11:03 GMT
Content-Length: 6821
Content-Type: text/html
(data data data data data ...)
```
* 第一行為 **狀態行 (Status Line)**,有三個欄位
* 版本號欄位:伺服器使用 HTTP 版本號為 1.1
* 狀態碼
* 狀態訊息
:::info
* 200 OK:請求成功執行,回應正常回傳
* 301 Moved Permanently:物件被移動到另一個地方了,新的 URL 會寫在標頭中 `Location:` 欄位
* 400 Bad Request:當伺服器看不懂請求時會用的錯誤碼
* 404 Not Found:請求的檔案不在這個伺服器上
* 505 HTTP Version Not Supported:請求所使用的 HTTP 版本不支援
:::
* 二到七行為 **標頭行 (Header Lines)**
* `Connection: close`:告訴客戶端伺服器會把 TCP 連線關掉
* `Date: Tue, 18 Aug 2015 15:44:04 GMT`:這段回應訊息被送出的時間
* `Server: Apache/2.2.3 (CentOS)`:伺服器是 Apache 網頁伺服器
* `Last-Modified: Tue, 18 Aug 2015 15:11:03 GMT`:請求的物件最後被修改的時間
* `Content-Length: 6821`:送出的物件長度為 6821 位元組
* `Content-Type: text/html`:送出的物件是個 HTML 文字檔
> 檔案類型以標頭內的為準,而不是看副檔名

* 最後面為 **實體主體**
### Cookies
由於 HTTP 伺服器是無狀態的,因此要使用 Cookies 紀錄使用者

* Cookies 包含四個部分
1. HTTP 回應訊息中的 cookies 標頭欄位
2. HTTP 請求訊息中的 cookies 標頭欄位
3. 由瀏覽器管理的 cookies 檔案
4. 在伺服器端的資料庫
* 使用者第一次造訪某網站時,伺服器會回傳 **set-cookie** 給瀏覽器,而之後使用者發出請求時,瀏覽器就會將 cookie 加在請求的標頭內,這樣伺服器就認出該使用者
### Web Caching
* **Web 快取**,又稱 **代理伺服器 (Proxy Server)**,可以儲存最近有人存取過的網頁物件副本
* 假如一瀏覽器想請求 `http://www.someschool.edu/campus.gif`:
1. 瀏覽器建立一個通往代理伺服器的 HTTP 請求,並請求物件
2. 代理伺服器會先檢查自己有沒有該物件的副本,如果有,直接把物件回應給瀏覽器
3. 沒有的話就會開啟通往原伺服器的 TCP 連線,並請求物件
4. 當代理伺服器從原伺服器收到該物件,會先存一份副本在自己這裡,然後將副本回應給瀏覽器
* 由 ISP 購入並安裝
* 優點:
1. 大幅降低客戶端請求物件所需時間
2. 減少大型機構的接取網路與網路核心間的流量
3. 減少 Web 服務在整個網際網路中的流量
* 來看一個範例:

* 有兩個網路:大型機構的網路和公用網際網路。機構網路內部傳輸速率為 1 Gbps,機構網路的路由器和網際網路的路由器由一條傳輸速率 1.54 Mbps 的線路連接,假設一個網頁物件的大小為 100K bits,而機構網路中瀏覽器發送 HTTP 請求的平均速度為每秒 15 個請求,RTT (**網際網路延遲**) 為 2 秒,求總回應時間
> 網際網路延遲 Internet Delay:發出一個請求到收到請求的回應經過的時間
* 總回應時間 (End-end Delay) = 區域網路延遲 (LAN Delay) + 接取網路延遲 (Access Link Delay) + Internet Delay
* 先計算流量強度
* 區域網路流量強度為:$$15*(100*10^3)/(1*10^9)=0.0015$$
* 接取網路流量強度為:$$15*(100*10^3)/(1.54*10^6)=0.97$$
* 我們幾乎可以忽略區域網路延遲,但是接收網路的流量強度接近 1,造成的延遲就會很大。那我們該如何解決這個問題
* 增加接取線路的頻寬,增加至 154 Mbps,這樣流量強度就變成$$15*(100*10^3)/(154*10^6)=0.0097$$但是這是一筆不小的開銷
* 因此我們可以選擇使用 Web 快取,將其安裝在機構網路裡面,如下圖

* 假設快取的 **命中率 (Hit Rate)** 為 0.4%,則有 40% 的請求可以由快取中取得,大約花費 10 毫秒;而另外 60% 則需要通過接取線路經由網際網路中的原伺服器來滿足
* 因為通過存取線路的流量下降至 60%,因此接取往流量強度會降低為 0.6,而 0.6 時在此線路上延遲已經變成毫秒等級
* 因此我們可以計算:$$d_{end-end-delay}=0.6*2.01+0.4*0.01=1.21secs$$
* 又快又便宜
### The Conditional GET
當伺服器上的檔案被修改時,快取的副本還會是舊版,為了補全這個錯誤,HTTP 有個機制為 **條件請求 (Conditional GET)**
* 滿足條件
1. 請求方法為 **GET**
2. 請求的標頭內有一個 `If-Modified-Since:`
* 範例:當一個物件可能被修改過,當有瀏覽器請求這個物件時
1. 快取會向原伺服器發送請求:
```
GET /fruit/kiwi.gif HTTP/1.1
Host: www.exotiquecuisine.com
If-modified-since: Wed, 9 Sep 2015 09:23:24
```
`If-modified-since:` 告訴伺服器檔案如果在這個時間後有被修改,才需要傳檔案過來
2. 如果檔案沒有被修改,則回應:
```
HTTP/1.1 304 Not Modified
Date: Sat, 10 Oct 2015 15:39:29
Server: Apache/1.3.0 (Unix)
(empty entity body)
```
狀態為 `304 Not Modified` 告訴快取直接使用你的副本即可
3. 如果檔案有被修改:
```
HTTP/1.1 200 OK
.
.
.
data...
```
這時就會用新的檔案將舊的副本覆蓋,接著將副本回應給瀏覽器
### HTTP/2
目標:希望降低具有很多物件的 HTTP 請求的延遲
* **HTTP 1.1**:一個 TCP 連線中,有多個且管線化的 GETs (持續性的連線)
* 伺服器端按照順序依序回應 GET 請求 (**first-come-first-served secheduling, FCFS**)
* 大物件在傳輸時,小物件就須在大物件後等待 (**head-of-line blocking, HOL**)
* 萬一有封包丟失,在重傳期間傳輸會暫停

* **HTTP/2**:降低多物件 HTTP 請求的延遲
* 請求、回應欄位均與 HTTP1.1 大致相同
* 由客戶端指定物件的優先度來決定傳輸順序
* 在客戶端還沒發送特定物件請求前,就先將該物件 **push** 給客戶端
* 將物件打包成二進位的 **訊框 (frame)**,調度每個訊框減輕 HOL blocking

* 封包丟失時,物件的傳輸還是會暫停
* 沒有安全性保護
* **HTTP/3**:增加安全性保護、透過 UDP 來實現物件錯誤及壅塞控制
## E-mail
<img src="https://hackmd.io/_uploads/SyAyhNAyA.png" height="500">
* 三大元件
1. 使用者代理 User Agent, UA
2. 信件伺服器 Mail Server
3. 簡單郵件傳輸協定 Simple Main Transfer Protocol, SMTP
### 使用者代理 User Agent
* 功能:讀、寫、轉發、儲存信件
* 寄信時,使用者代理會將信寄給信件伺服器
* 當收信時,使用者代理會從伺服器抓取信件
### 信件伺服器 Mail Server
* **信箱 (Mail Box)** 位於信件伺服器中,儲存該使用者收到的信件
* 電子郵件會經過以下路徑:
1. 寄件人的使用者代理
2. 寄件人的信箱
3. 收信人的信件伺服器
4. 收信人的信箱
* 如果送出的信件沒有成功送達,會被暫存於 **信件隊伍 (Message Queue)**,並稍後嘗試重傳
### 簡單郵件傳輸協定 SMTP
* 規範於 RFC 5321
* 使用 TCP 保證訊息能正確送達
* 埠號通常為 25
* 訊息編碼為 7-bits ASCII
* 假設 Alice 要傳送 Email 給 Bob:
1. Alice 使用 UA 提供 Bob 的信箱地址 `bob@someschool.edu`,並寫了一封信寄出
2. Alice 的 UA 將信建送到她的信件伺服器,這封信被放在信件隊伍中
3. 客戶端的 SMTP 與 Bob 的信件伺服器的伺服器端 SMTP 建立 TCP 連線
4. SMTP 客戶端將 Alice 的信件送入 TCP
5. Bob 的信件伺服器上,SMTP 伺服器端收到了信件,將其放入郵箱中
6. Bob 透過 UA 閱讀信件

* 特別注意,SMTP 不會使用中介伺服器,就算兩個信件伺服器遠在地球另一端,SMTP 還是會建立一個直通的 TCP 連線,因此如果另一端的信件伺服器未開啟,信件就需一直待在信件隊伍中等待發送
### Comparison with HTTP
* HTTP 為 Pull Protocol:TCP 連線是由收信方建立
* SMTP 為 Push Protocol:TCP 連線是由送信方建立
* SMTP 需使用 7-bits ASCII,如果出現非 7-bits ASCII 的字元,須將其重新編碼為 7-bits ASCII,而 HTTP 不需要
* HTTP 的每個物件單獨使用一個訊息傳送,而 SMTP 則將全部的訊物件放於同一條訊息內傳送
### Mail Message Format
* 規範於 RFC 5322
* 格式:
* 標頭:
```
From: alice@crepes.fr
To: bob@hamburger.edu
Subject: Searching for the meaning of life.
```
> 所有標頭必須包含 `From:` `To:`,而 `Subject:` 不強迫
* 一行空格
* 最後為 **實體主體**,只有 ASCII 字元
### 郵件存取協議 Mail Access Protocols
如果說 SMTP 專門用來送郵件,那我們還需要一個協議來讓收信人存取信件
* 郵局協定第 3 版 Post Office Protocol -- Version 3, POP3
UA 開啟一個通往信件伺服器的 TCP 連線 (埠號 110),當連線建立完成,執行三階段:
* 身分認證:UA 必須傳送正確的使用者名稱及密碼
* 交易:獲取信件、標記刪除信件、移除標記及獲取信件統計資料
* 更新:在客戶端發出 `quit` 結束 POP3 之後觸發,信件伺服器會刪除標記的信件
* 網際網路資料存取協定 Internet Message Access Protocol, IMAP
* IMAP 允許使用者在信件伺服器上創建資料夾,使其較方便管理
* 所有操作都在伺服器上完成,因此不同裝置不會有不同步的問題
* 允許使用者下載郵件的部分元素
### Web-based Email
* 網頁瀏覽器當作 UA 來使用
* 使用 HTTP 與遠端信箱通訊,讀信寄信都是,但伺服器間還是使用 SMTP
## 網域名稱系統 Domain Name System, DNS
人類喜歡用 **主機名稱 (Hostname)** 來辨認主機 `www.facebook.com`
而路由器偏好 **IP 位址** `157.240.31.35`
因此我們需要一個類似查號台的服務,而這就是 **DNS** 的用處
### DNS
RFC 1034
* 一個由 DNS 伺服器以階層式架構所組成的 **分散式資料庫 (Distributed Database)**
* 一個讓所有主機能夠查詢上述分散式資料庫的應用層協定
* 提供的服務有:
* 將主機名稱換成 IP 位址
瀏覽器請求 `www.someschool.edu/index.html` 時,該使用者的機器有 DNS 的客戶端
1. 瀏覽器會將 `www.someschool.edu` 傳給 DNS 客戶端
2. DNS 客戶端會發送包含主機名稱的請求到 DNS 伺服器端
3. DNS 客戶端會收到一個來自 DNS 伺服器的回應,回應中包含對應主機名稱的 IP 地址
4. 瀏覽器收到 IP 地址,就可以與 HTTP 主機建立 TCP 連線
* 主機別名 Host Aliasing
* 假如一個主機名稱太長,我們就可以幫它取別名
* 而原本的名稱被稱為 **正規主機名稱 (Canonical Hostname)**
* 別名則稱為 **主機別名 (Aliasing Hostname)**
* 信件伺服器別名 Mail Server Aliasing
* 負載分散 Load Distribution
* 流量大的主機都會有許多 **副本伺服器 (Replicated Web Server)**,擁有不同的 IP 位址
* 正規主機名稱對應到的是這些副本伺服器 IP 位址的集合
> DNS 客戶端請求到對應的正規主機名稱,DNS 伺服器會回應整個 IP 地址的集合,並將集合順序輪轉一格。因為瀏覽器使用的都會是集合中的第一個,因此這樣能夠分散流量的效果
### Overview of How DNS Works
#### A Distributed, Hierarchical Database

* DNS 伺服器可以分成三類
* 根域名 DNS 伺服器 Root DNS Server
* 如果其他 DNS 伺服器無法解析的主機名稱,就會送到這裡來
* DNSSEC:提供安全性
* 由 **ICANN (Internet Corporation for Assigned Names and Numbers)** 所管理
* 頂級域名 DNS 伺服器 Top-level Domain (TLD) DNS Server
* 所有的頂級域名或是國家域名 `.com` `.org` `.tw` `.jp` 等,都有一個對應的 TLD 伺服器
* 權威域名 DNS 伺服器 Authoritative DNS Server
* 想在網際網路上提供公開存取的主機的組織,要提供自己的主機名稱對應到的 IP 位址,權威域名伺服器就是用來存儲這些資訊的
* 他們可以選擇自行實作權威域名伺服器,或是外包給其他服務商
* 本地 DNS 伺服器 Local DNS Server
* 不嚴格屬於上面那幾類
* 每一個 ISP 都有自己專屬的本地伺服器
> 又稱 **預設域名伺服器 (Default Name Server)**
* 當有主機送出 DNS 查詢時,會先經過本地伺服器,會由這個機器作為代理,將請求轉發到上面提到的幾種伺服器

* 查詢順序範例:假設 `cse.nyu.edu` 想要查詢 `gaia.cs.umass.edu` 的 IP 位址,而本地 DNS 主機名稱為 `dns.nyu.edu` 且負責 `gaia.cs.umass.edu` 的權威域名 DNS 主機名稱為 `dns.umass.edu`
1. `cse.nyu.edu` 會先往 **本地** 伺服器 `dns.nyu.edu` 送出請求,請求內容包含 `gaia.cs.umass.edu`
2. **本地** 會將請求轉達至 **根域名** 伺服器
3. **根域名** 就會根據 `.edu` 而回傳負責 `.edu` 的 **頂級域名** 伺服器列表
4. **本地** 隨機挑選一個 **TLD** 並將原本的請求發送過去
5. **TLD** 根據 `umass.edu` 傳回麻薩諸塞大學 (UMASS) 的 **權威域名** 伺服器的 IP 位址 `dns.umass.edu`
6. **本地** 將請求發到 `dns.umass.edu`
7. **權威域名** 就會將 `gaia.cs.umass.edu` 的 IP 地址回傳到 **本地**
8. **本地** 再將結果回傳給 `cse.nyu.edu`
* 以上的例子使用了 **迭代查詢 (Iterative Query)** 與 **遞迴查詢 (Recrusive Query)**
* 迭代查詢:回應直接傳給請求的主機
> 「我不知道欸,你可以問他」
> 上個例子的 (2, 3), (4, 5), (6, 7)
* 遞迴查詢:被請求的主機幫忙尋問其他主機去找到結果
> 「我不知道欸,但我可以幫你問」
> 上個例子的 (1, 8)
#### DNS Cashing
* 每當一個 DNS 伺服器收到一個回應,就可以將其對應表存入自身的記憶體中,下次有人來問就可以直接回答
* 能讓大部分 DNS 請求跳過根域名伺服器
### DNS Records and Messages
DNS 資料庫中,儲存了 **資源紀錄 (Resource Records, RRs)**
* RRs 由四個元組組成:
```
(Name, Value, Type, TTL)
```
> TTL:該紀錄的存活時間,紀錄什麼時候這筆資料要從快取中刪除
* `Type=A` 時,`Name` 為主機名稱,`Value` 為 IP 位址
* `Type=NS` 時,`Name` 為網域名稱,`Value` 為該網域的權威域名 DNS 伺服器的主機名稱
* `Type=CNAME` 時,`Name` 為某個主機的別名,`Value` 為其正規名稱
* `Type=MX` 時,`Name` 為某信件伺服器的別名,`Value` 為其正規名稱
### DNS Messages
DNS只有兩種訊息:**詢問 (Query)** 及 **回應 (Reply)**,兩者格式一模一樣

* 前面 12 Byte 為標頭區段 (Header Section):
* 識別碼 (Identification),為 16-bit 的數字,會被複製到該詢問的回應上,讓客戶端辨別該回應是對應到哪個詢問
* 旗標欄位 (Flags),
* 1-bit 標示訊息是詢問 (0) 或是回應 (1)
* 1-bit 回應的 DNS 伺服器是權威域名時為 1
* 1-bit 當客戶端請求希望使用遞迴查詢時設定為 1
* 1-bit 收到請求的 DNS 主機支持遞迴查詢時,回應時會設定為 1
* 問題區段 (Question Section)
* 一個 name 欄位,代表所詢問的主機名稱
* 一個 type 欄位,代表欲查詢的紀錄為哪種類型
* 回答區段 (Answers Section)
* 包含原本查詢的名字的 RRs
* 權威區段 (Authority Section)
* 包含其他權威域名伺服器的紀錄
* 備註區段 (Additional Section)
* 提供有用信息
### Inserting Records into DNS Database
* 域名註冊商 DNS register
負責驗證域名的獨一性、把域名輸入資料庫
* 例:我們現在要向域名註冊商註冊 `networkutopia.com` 這個網域名稱
1. 要向註冊商報備主要及次要的權威域名伺服器的主機名稱和 IP 位址
> 假設主機名稱為`dns1.networkutopia.com` `dns2.networkutopia.com`
> 對應的 IP 位址為 `212.212.212.1` `212.212.212.2`
2. 將以下資訊註冊到 DNS 系統中
```
(networkutopia.com, dns1.networkutopia.com, NS)
(dns1.networkutopia.com, 212.212.212.1, A)
```
## Peer-to-peer File Distribution
* 沒有保持開啟的伺服器,只有斷斷續續連線的主機,這些主機我們稱之為 **Peer**
* 相比於主從式有一個固定 IP 的伺服器,P2P 之間都是使用浮動 IP
* P2P 相較主從式架構有更好的 **自擴展性 (Self Scalability)**,每多一個新的 peer,就能帶來更好的服務能力
* 假設一台伺服器要向大量的主機分享大型檔案,如果使用主從式架構,伺服器就需要親自將每個檔案送到每個主機上,容易造成伺服器的負擔
* 在這個情況下使用 P2P,每個 peer 都可以把自己手上的檔案分享給其他 peer,而收到的 peer 再將檔案分享給其他 peer,這樣伺服器的負擔就會相對較小
* 舉例來說:假設有個伺服器和 N 個 peers 都透過接取線路連接到網際網路上,現在伺服器要將一份大小為 F bits 的檔案送給所有的 peers,我們將伺服器的上傳速率設為 $u_{s}$,第 $i$ 個 peer 的上傳速率與下載速率分別為 $u_{i}$ 和 $d_{i}$
* 先來計算主從式架構的傳送時長,將其計為 $D_{cs}$
* 由於不會有任何 peer 幫忙傳遞,所以伺服器總共要上傳 $NF$ bits,因此上傳需要花費 $NF/u_{s}$ 秒
* 接下來我們再取得下載最慢的機器會花費多少時間:$F/min\{d_{1}, d_{2}...d_{N}\}=F/d_{min}$
* 考慮以上兩點,我們可以得到:$$D_{cs}\geq max\{\frac{NF}{u_{s}}, \frac{F}{d_{min}}\}$$
* 我們可以看到,N 越大,所需要花費的時間也會劇烈增加
* 接下來使用 P2P 的方式,將其計為 $D_{P2P}$
* 首先,伺服器要先上傳檔案到整個 peers 系統裡面:$F/u_{s}$ 秒
> 不一定要傳第二次,因為 peers 之間會幫忙傳遞
* 我們一樣要考慮下載最慢的機器所花的時間:$F/min\{d_{1}, d_{2}...d_{N}\}=F/d_{min}$ 秒
* 如果我們將整個系統視為一體,則系統的上傳速率會等於伺服器的上傳速率加上所有 peers 的上傳速率,而總共要上傳 $NF$ 個 bits,因此最小傳遞時長為 $NF/(u_{s}+u_{1}+u_{2}+...+u_{N})=NF/u_{s}+\sum_{i=1}^N u_{i}$ 秒
* 考慮以上三點,我們可以得到:$$D_{P2P}=max\{\frac{F}{u_{s}}, \frac{F}{d_{min}}, \frac{NF}{u_{s}+\sum_{i=1}^N u_{i}}\}$$

### BitTorrent
檔案傳輸用的 P2P 協議
* **Torrent**:共同參與傳遞檔案的 peers 的集合
* **Tracker**:用來跟蹤 Torrent 裡面的 peers
* 通常會把一個大檔案拆成一個個 **Chunk**,一個 Chunk一般來說是 256KB
* 簡單來說:
* 當一個 peer 剛加入一個 torrent 時:
* 先向 tracker 註冊,並且定期告訴它自己還在裡面
* 嘗試與所有 peer 建立 TCP 連線,順利連接的 peer 我們稱為 **鄰接 (Neighboring Peers)**
> 隨著時間經過,會有其他 peers 想要與我們建立 TCP 連線,因此一個鄰接會是浮動的
* 下載進行中:
* 每個 peer 都會擁有目標檔案的 chunk,我們會定期向鄰接的 peers 要求他們擁有的 chunk 列表,這樣就知道缺哪個 chunk 要向誰發送請求
> 通常會 **先拿最稀有的**
* 當收到請求時,會先優先回覆*提供他資料速率最快的鄰居*
* 假如說挑出最快的四個鄰居,我們會傳送 chunk 給他們
* 每 10 秒鐘會重新測一次速率
* 這些人被稱為 **unchocked**
* 每隔 30 秒,會隨機選擇一個鄰居並傳送 chunk 給他
* 我們稱這個人為 **optimistically unchoked**
## Video Streaming and Content Distribution Networks
### Internet Video
* 影片 Video:一連串的照片,以固定的 **幀率 (frame rate)** 進行播放
* **位元速率**:影片位元速率愈高,畫質愈好
> 100kbps 低畫質
> 3Mbps 高畫質
### DASH Dynamic, Adaptive Streaming over HTTP
* 伺服器將影片分成一個個資料塊
* **清單檔案 (manifest file)**:記錄每一個資料塊的位置
* 持續監控使用者的流量速度,決定一個適合使用者的檔案 (解析度)
### Content Distribution Network, CDN
我們該如何串流影片同時送給數百萬個使用者?
* 建立一個大型資料中心?
* 如果客戶端很遠,就會導致延遲
* 同一個影片可能在一條線路被傳送了很多次
* 單一資料中心會有單點故障問題
* 因此我們會使用 **內容傳遞網路 (CDN)** 來實現
* CDN 通常會遵循以下兩個原則:
* Enter Deep:伺服器部屬到世界各地,盡可能接近使用者
* Bring Home:將伺服器部屬於網際網路交換中心 (IXP)
### CDN Operation
使用者透過瀏覽器請求下載某影片時,CDN 會將請求攔截下來以決定:
1. 使用哪個伺服器來服務這個客戶端
2. 將該請求導向到適合的伺服器