瀏覽器中常見網(wǎng)絡協(xié)議介紹
實際上,瀏覽器為了完成 WEB 應用的各項功能,需要跟各種網(wǎng)絡協(xié)議打交道,HTTP 只是其中一種。本文會介紹瀏覽器中常見的網(wǎng)絡協(xié)議,以及各種協(xié)議之間的關系。
我們經(jīng)常會聽到「TCP/IP 協(xié)議」這個名詞,從字面上看,有人會認為它專指 TCP 和 IP 兩種協(xié)議。實際上大多數(shù)情況,TCP/IP 協(xié)議指的是整個網(wǎng)際協(xié)議族(Internet Protocol Suite),是利用 IP 協(xié)議進行通訊的其他協(xié)議統(tǒng)稱。TCP/IP 包含的協(xié)議眾多,還有一個分層模型。相比較 OSI 模型,TCP/IP 的分層更簡單,從下到上分別為:物理層、數(shù)據(jù)鏈路層、網(wǎng)絡層、傳輸層和應用層。
IP(Internet Protocol)屬于網(wǎng)絡層協(xié)議,負責聯(lián)網(wǎng)主機之間的路由選擇和尋址。IPv4 中的 4 指的是 TCP/IP 協(xié)議的第 4 個版本,直到這個版本,IP 協(xié)議才單獨拆出來,所以并沒有單獨的 IPv1 - IPv3。而 IPv5 分給了一個沒什么進展的試驗性協(xié)議,所以下一個版本的 IP 協(xié)議變成了 IPv6。
TCP(Transmission Control Protocol)和 UDP(User Datagram Protocol)是整個 TCP/IP 協(xié)議中最重要的兩個傳輸層協(xié)議。TCP 是面向連接的、可靠的流協(xié)議;UDP 是不具有可靠性的數(shù)據(jù)報協(xié)議。后面可以看到,對可靠性要求比較高的上層協(xié)議一般會基于 TCP;而對高速傳輸和實時性有較高要求的上層協(xié)議一般會基于 UDP。
介紹完比較低層的 IP、TCP 和 UDP 之后,下面看幾個瀏覽器中常見的應用層協(xié)議。
HTTP 與 WebSocket
HTTP 協(xié)議是瀏覽器需要用到的最重要的網(wǎng)絡協(xié)議,它包括很多版本,例如最常見的 HTTP/1.1,剛剛發(fā)布的 HTTP/2,還有 Google 實現(xiàn)的過渡版本 SPDY 等等。本文不討論 HTTP 的細節(jié)以及各版本之間的差異,只打算列出 HTTP 與其他協(xié)議 / 應用之間的關系,見下圖:
+-------------+-------------+--------------+
| XHR | SSE | WS |
+-------------+-------------+------+ +
| HTTP | |
+----------------------------------+-------+
| TLS * |
+------------------------------------------+
| TCP |
+------------------------------------------+
| IP |
+------------------------------------------+
從上圖可以看出 HTTP 是在 TCP 之上實現(xiàn)的,所以 HTTP 中并不需要關注數(shù)據(jù)傳輸?shù)目煽啃?,類似于順序控制、重發(fā)這樣的機制在傳輸層已經(jīng)有了。同時,HTTP 也擁有 TCP 的一些缺點,給 WEB 性能優(yōu)化帶來挑戰(zhàn)。
XHR(XmlHTTPRequest)和 SSE(Server-Sent Events)都是瀏覽器提供的數(shù)據(jù)交互功能,它們的本質(zhì)都還是 HTTP。XHR 是 Ajax 技術的核心,大家都很熟,這里略過不討論;SSE 概念還算新,多說幾句。我們知道 HTTP 只能由客戶端發(fā)起請求,再由服務端響應。SSE 也是這樣,只不過服務端會保持住這個 HTTP 連接,多次發(fā)送響應,不像平時發(fā)送完響應就結束了。實際上,很早之前在 WebIM 中類似的 HTTP 長連接技術就已經(jīng)很盛行了,有興趣的同學可以看下這篇八年前的文章:Comet:基于 HTTP 長連接的「服務器推」技術。
既然 XHR 和 SSE 本質(zhì)都是 HTTP 連接,所以 HTTP 協(xié)議中一些常見概念,例如請求方式(GET、POST 等),請求響應頭部(Cookie、內(nèi)容編碼、傳輸編碼、緩存等)等等,依然存在。
而 WS(WebSocket)是直接基于 TCP 實現(xiàn)的,HTTP 協(xié)議中的那些概念都不復存在。需要注意的是,從前面圖表中可以看出,它還是依賴于 HTTP,這是因為 WebSocket 握手利用了 HTTP 的 Upgrade 機制。一旦握手完成,后續(xù)數(shù)據(jù)傳輸就直接在 TCP 上完成。瀏覽器中新協(xié)議借助 HTTP 作為引導,是一個較為普遍的做法。
TLS(Transport Layer Security,傳輸層安全),作用是保證數(shù)據(jù)在傳輸過程中的完整性和保密性,屬于可選項。啟用了 TLS 之后,HTTP 協(xié)議的 URL 前綴需要由 http:// 改成 https://;WebSocket 協(xié)議的 URL 前綴需要由 ws:// 改成 wss://。
DNS
DNS(Domain Name System),就是大家熟知的域名解析服務,提供了從域名到 IP 的轉換。瀏覽器中大部分網(wǎng)絡交互都會使用域名,而傳輸層協(xié)議需要的是 IP,所以 DNS 是基礎。
+-------------------------------+
| DNS |
+-------------------------------+
| TCP | UDP |
+---------------+---------------+
| IP |
+-------------------------------+
DNS 服務默認使用 UDP 協(xié)議獲得查詢結果,通常僅當結果超過 512 字節(jié)或者進行 DNS 服務器同步時才會使用 TCP 協(xié)議。這是因為 DNS 的使用非常頻繁,又是基礎,響應速度是優(yōu)先需要考慮的。使用 UDP 可以滿足速度上的要求,但同時也引入了類似于「DNS 緩存投毒」這類問題。
WebRTC
WebRTC(Web Real-Time Communication)出現(xiàn)之前,DNS 幾乎是瀏覽器唯一使用的基于 UDP 的協(xié)議。WebRTC 提供的三大功能中,MediaStream 與網(wǎng)絡無關,RTCPeerConnection 和 RTCDataChannel 都是基于 UDP,如圖:
+-----------------------+-------------------------+
| RTCPeerConnection | RTCDataChannel |
+-----------------------+-------------------------+
| SRTP | SCTP |
+ +---------+-------------------------+
| | DTLS |
+-------------+-----------------------------------+
| ICE, STUN, TURN |
+-------------------------------------------------+
| UDP |
+-------------------------------------------------+
| IP |
+-------------------------------------------------+
這個圖比較復雜,我們從下往上介紹:
ICE(Interactive Connectivity Establishment)框架,作用是在端與端之間建立一條有效的通道,優(yōu)先直連,其次用 STUN 協(xié)商,再不行只能用 TURN 轉發(fā):
STUN(Session Traversal Utilities for NAT)協(xié)議,解決了三個問題:1)獲得外網(wǎng) IP 和端口;2)在 NAT 中建立路由條目,綁定外網(wǎng)端口,使得到達外網(wǎng) IP 和端口的入站分組能找到應用程序,不被丟棄;3)定義了一個簡單的 keep-alive 機制,保證 NAT 路由條目不會因為超時而被刪除。STUN 服務器必須架設在公網(wǎng)上,可以自己搭建,也可以使用第三方提供的公開服務,例如 Google 的「stun:stun.l.google.com:19302」。
TURN(Traversal Using Relays around NAT)協(xié)議,依賴外網(wǎng)中繼設備在兩端之間傳遞數(shù)據(jù)。簡單說就是通過兩端都可以訪問的 TURN 服務轉發(fā)消息,間接把兩端連起來。
DTLS(Datagram Transport Layer Security,數(shù)據(jù)報傳輸層安全),本質(zhì)上就是 TLS,只是為了兼容 UDP 的數(shù)據(jù)報傳輸而做了一些微小的修改,可以簡單把它理解為 UDP 版的 TLS。
再往上就兵分兩路,一路的目標是 RTCPeerConnection,負責音頻和視頻數(shù)據(jù)通信,對傳輸速度和實時性有很高的要求,這里又有兩個新的協(xié)議出現(xiàn):
SRTP(Secure Real-time Transport Protocol,安全實時傳輸協(xié)議)。WebRTC 中的音頻和視頻等實時數(shù)據(jù)都是通過這個協(xié)議傳輸。它是 RTP 協(xié)議的安全版。
SRTCP(Secure Real-Time Control Transport Protocol,安全實時控制傳輸協(xié)議)。它會跟蹤 SRTP 的運行情況,以便調(diào)整每個流的發(fā)送速率、編碼品質(zhì)和其他參數(shù)。它是 RTCP 協(xié)議的安全版。
另一路的目標是 RTCDataChannel,用來在端到端之間傳輸任意應用數(shù)據(jù),SRTP 是專門為傳輸媒體數(shù)據(jù)為設計的,不適合傳輸應用數(shù)據(jù),所以這里又需要一個新的協(xié)議:
SCTP(Stream Control Transmission Protocol,流控制傳輸協(xié)議)。本身 SCTP 是一個傳輸層協(xié)議,直接運行在 IP 協(xié)議之上,與 TCP 和 UDP 類似。但在 WebRTC 這里,SCTP 卻運行于 DTLS 之上。SCTP 很好的一點是提供了交付屬性選項,使用者可以指定消息是有序還是亂序,是可靠還是部分可靠,部分可靠時還可以指定使用超時重傳還是計數(shù)重傳策略。
QUIC
Google 正在試驗一種新的傳輸層協(xié)議:QUIC(Quick UDP Internet Connections),它的本質(zhì)是基于 UDP 實現(xiàn) HTTP,相當于之前的 TCP + TLS。從目前的資料來看,QUIC 可以大幅減少建立連接的時間,這是通過簡化握手步驟從而減少 RTT(Round-Trip Time)來實現(xiàn)的,類似于 TFO(TCP Fast Open)。有興趣的同學可以點這個連接圍觀,據(jù)說 Google 自家服務來自 Chrome 的請求中,已經(jīng)有 50% 使用了 QUIC 協(xié)議。
最后表達下對 Google 的佩服。Google 為了優(yōu)化 WEB 性能,在瀏覽器(Chrome)、排版引擎(Blink)、JS 引擎(V8)、圖片格式(WebP)、傳輸層協(xié)議(TCP 的 TFO,QUIC)、應用層協(xié)議(SPDY)以及 HTML5(從 Google Gears 開始)等等方面都做了大量努力,實在是技術型公司典范,嘆為觀止!




















