重頭梳理網(wǎng)絡(luò)協(xié)議棧

WWW 30 years

從 1989 年 HTTP 0.9 發(fā)布開始,互聯(lián)網(wǎng)的發(fā)展已經(jīng)近三十年,各種網(wǎng)絡(luò)概念也是層出不窮。如 Https, WebSocket, Http 2.0, spdy 等等。

相信大家或多或少能從各種途徑,獲取到詳細(xì)的資料。 這里我想通過另一個(gè)維度,來看看它們是如何演化而來,為什么這么設(shè)計(jì),解決了什么業(yè)務(wù)場(chǎng)景,以及一些基本的入門實(shí)踐等。

我們?cè)噲D從以下幾個(gè)問題出發(fā),解釋這篇文章的初衷。

1. 當(dāng)我們打開瀏覽器訪問一個(gè)網(wǎng)頁(yè)時(shí),它是如何將數(shù)據(jù)安全的發(fā)送給我們的?

2. Http 2.0 為何時(shí)隔10年才出現(xiàn),它解決了什么問題?

3. Socket 和 Http 什么關(guān)系?

4. Web socket 又是什么?它是工作在哪一層的?

5. 想要更輕量,更有效率的數(shù)據(jù)傳輸如何做?

為了解釋以上問題,我們先從網(wǎng)絡(luò)基礎(chǔ)知識(shí)開始,這對(duì)解釋以上問題很重要。


1. 網(wǎng)絡(luò)協(xié)議

1.1 七層協(xié)議

OSI model: The Open Systems Interconnection model
一種概念模型,由國(guó)際標(biāo)準(zhǔn)化組織(ISO)提出,一個(gè)試圖使各種計(jì)算機(jī)在世界范圍內(nèi)互連為網(wǎng)絡(luò)的標(biāo)準(zhǔn)框架。
通俗的說,為了全世界的計(jì)算機(jī)之間相互通信,而設(shè)計(jì)的一種協(xié)議框架,所有需要聯(lián)網(wǎng)的設(shè)備或軟件都需要遵循它的規(guī)則。另外,也為了盡可能避免所有功能混雜在一起,讓不同公司或組織更聚焦在一個(gè)領(lǐng)域上,才有了現(xiàn)在的分層模型。

OSI 七層協(xié)議

我們可以看到在每一層,根據(jù)實(shí)際應(yīng)用場(chǎng)景,都有對(duì)應(yīng)的協(xié)議被設(shè)計(jì)出來。

從上面的模型我們可以知道,大的結(jié)構(gòu)上,分為面向上層應(yīng)用與面向網(wǎng)絡(luò)媒介兩個(gè)部分。應(yīng)用層上主要是面向數(shù)據(jù)與數(shù)據(jù)的傳輸,網(wǎng)絡(luò)媒介主要是面向網(wǎng)絡(luò)通信與硬件。

1.2 TCP/IP

基于 OSI 協(xié)議模型衍生而來,現(xiàn)今使用最多的就是 TCP/IP 協(xié)議棧了。注意這里的 TCP/IP 協(xié)議棧并不只是指 TCP 與 IP 協(xié)議的合集,它是一種更簡(jiǎn)化的 OSI 模型。

通過下圖可以看到它與 OSI 模型區(qū)別:

TCP/IP 與 OSI 對(duì)應(yīng)模型

從 tcp/ip 協(xié)議規(guī)范來看,應(yīng)用層,表示層與傳輸層被合并在一起。主要原因是這三層,在當(dāng)今的實(shí)際使用中有相當(dāng)多耦合關(guān)系,也很難將它們刻意的分離。

實(shí)際上現(xiàn)在的 TCP/IP 模型更加簡(jiǎn)單明了,更適應(yīng)現(xiàn)在的應(yīng)用場(chǎng)景。

TCP/IP 模型

除了以上的協(xié)議棧外,還有當(dāng)今兩個(gè)重要的協(xié)議:TLS 與 SPDY 。

1.3 TLS/SSL

TLS/SSL 是當(dāng)今一個(gè)比較重要的安全傳輸協(xié)議,它不在上面所列的協(xié)議棧中。但它被設(shè)計(jì)位于應(yīng)用層與傳輸層之間。以確保數(shù)據(jù)在傳輸之前是安全的,但又不破壞原有的數(shù)據(jù)協(xié)議。應(yīng)用層協(xié)議(例如:HTTP、FTP、Telnet等等)能透明的創(chuàng)建于TLS 協(xié)議之上。

我們經(jīng)常聽到的 HTTPS, 這個(gè) S 指的就是 secure (安全),同時(shí)分為 SSL 和 TLS 協(xié)議。它被 Netscape 公司在 1994 年推出。

SSL: (Secure Socket Layer,1994 年推出, 第一版作者: 塔希爾·蓋莫爾)。
SSL通過互相認(rèn)證、使用數(shù)字簽名確保完整性、使用加密確保私密性,以實(shí)現(xiàn)客戶端和服務(wù)器之間的安全通訊。

TLS: (Transport Layer Security, 1999 年推出)
它建立在SSL 3.0協(xié)議規(guī)范之上,作用同于 SSL, 與 SSL 3.0 差別極小,可以理解為SSL 3.1。

無論是 SSL 還是 TLS 都分為兩層:? 握手協(xié)議與記錄協(xié)議

SSL/TLS Protocol

* SSL 因?yàn)楸粓?bào)有各種安全問題,所以基本上現(xiàn)在所使用的都是 TLS。

以下是建立連接的過程:

SSL/TLS authentication

它必須建立在可靠的數(shù)據(jù)傳輸基礎(chǔ)上,所以一般是在TCP之上。

同時(shí),如果一但使用了 SSL/TLS 做安全驗(yàn)證,建立連接的時(shí)間實(shí)際上是會(huì)變長(zhǎng)的,如圖:

SSL/TLS Handshake Issue


1.4 SPDY

SPDY(發(fā)音如英語(yǔ):speedy),2010 年 9 月 一種開放的網(wǎng)絡(luò)傳輸協(xié)議,由 Google 開發(fā),用來發(fā)送網(wǎng)頁(yè)內(nèi)容的協(xié)議誕生,用以最小化網(wǎng)絡(luò)延遲,提升網(wǎng)絡(luò)速度,優(yōu)化用戶的網(wǎng)絡(luò)使用體驗(yàn)。它基于 TCP 的應(yīng)用層協(xié)議,也是 HTTP/2 的前身。它最早被應(yīng)用在 Chrome 6 。

設(shè)計(jì) SPDY 的目的在于降低網(wǎng)頁(yè)加載時(shí)間。通過優(yōu)先級(jí)和多路復(fù)用,SPDY使得只需要?jiǎng)?chuàng)建一個(gè)TCP連接即可傳送網(wǎng)頁(yè)內(nèi)容及圖片等資源。SPDY 中廣泛應(yīng)用了 TLS 加密,傳輸內(nèi)容也均以 gzip 或 DEFLATE 格式壓縮(與 HTTP 不同,HTTP的頭部并不會(huì)被壓縮)。另外,除了像 HTTP 的網(wǎng)頁(yè)服務(wù)器被動(dòng)的等待瀏覽器發(fā)起請(qǐng)求外,SPDY 的網(wǎng)頁(yè)服務(wù)器還可以主動(dòng)推送內(nèi)容。


SPDY

SPDY 并不用于取代 HTTP,它只是修改了 HTTP 的請(qǐng)求與應(yīng)答在網(wǎng)絡(luò)上傳輸?shù)姆绞?;這意味著只需增加一個(gè) SPDY 傳輸層,現(xiàn)有的所有服務(wù)端應(yīng)用均不用做任何修改。 當(dāng)使用 SPDY 的方式傳輸,HTTP 請(qǐng)求會(huì)被處理、標(biāo)記簡(jiǎn)化和壓縮。比如,每一個(gè) SPDY 端點(diǎn)會(huì)持續(xù)跟蹤每一個(gè)在之前的請(qǐng)求中已經(jīng)發(fā)送的 HTTP 報(bào)文頭部,從而避免重復(fù)發(fā)送還未改變的頭部。而還未發(fā)送的報(bào)文的數(shù)據(jù)部分將在被壓縮后被發(fā)送。

Google 之所以改動(dòng) HTTP 協(xié)議而不是 TCP/IP,是因?yàn)楦?HTTP 只需更新 Browser 和 web server 就行了,而改動(dòng) TCP/IP 牽扯面太廣,需要更新所有的路由器,服務(wù)器和客戶端的操作系統(tǒng)。


SPDY Connections over the Mobile Web


1.3 TCP

無論應(yīng)用層的協(xié)議如何定義、使用,都要基于一條已經(jīng)連接的通路去發(fā)送與接收數(shù)據(jù),我們可以試著從我們最熟悉的數(shù)據(jù)傳輸層開始,來了解連接的建立與傳輸。

這一層有兩個(gè)重要的協(xié)議,TCP 與 UDP。

TCP 協(xié)議的運(yùn)行可分為三個(gè)階段:連接創(chuàng)建(connection establishment)、數(shù)據(jù)傳送(data transfer)和連接終止(connection termination)

連接創(chuàng)建

TCP 用三次握手(three-way handshake)過程創(chuàng)建一個(gè)連接。在連接創(chuàng)建過程中,很多參數(shù)要被初始化,例如序號(hào)被初始化以保證按序傳輸和連接的強(qiáng)壯性。

一對(duì)終端同時(shí)初始化一個(gè)它們之間的連接是可能的。但通常是由一端打開一個(gè)套接字(socket)然后監(jiān)聽來自另一方的連接,這就是通常所指的被動(dòng)打開(passive open)。服務(wù)器端被被動(dòng)打開以后,用戶端就能開始創(chuàng)建主動(dòng)打開(active open)。

1. 客戶端通過向服務(wù)器端發(fā)送一個(gè) SYN 來創(chuàng)建一個(gè)主動(dòng)打開,作為三路握手的一部分??蛻舳税堰@段連接的序號(hào)設(shè)定為隨機(jī)數(shù)A。

2. 服務(wù)器端應(yīng)當(dāng)為一個(gè)合法的 SYN 回送一個(gè) SYN/ACK。ACK 的確認(rèn)碼應(yīng)為 A+1,SYN/ACK 包本身又有一個(gè)隨機(jī)產(chǎn)生的序號(hào)B。

3. 最后,客戶端再發(fā)送一個(gè) ACK。當(dāng)服務(wù)端受到這個(gè) ACK 的時(shí)候,就完成了三路握手,并進(jìn)入了連接創(chuàng)建狀態(tài)。此時(shí)包的序號(hào)被設(shè)定為收到的確認(rèn)號(hào) A+1,而響應(yīng)號(hào)則為 B+1。


TCP 的三次握手

連接重試

如果服務(wù)器端接到了客戶端發(fā)的SYN后回了SYN-ACK后客戶端掉線了,服務(wù)器端沒有收到客戶端回來的ACK,那么,這個(gè)連接處于一個(gè)中間狀態(tài),即沒成功,也沒失敗。于是,服務(wù)器端如果在一定時(shí)間內(nèi)沒有收到的TCP會(huì)重發(fā)SYN-ACK。在Linux下,默認(rèn)重試次數(shù)為5次,重試的間隔時(shí)間從1s開始每次都翻倍,5次的重試時(shí)間間隔為1s, 2s, 4s, 8s, 16s,總共31s,第5次發(fā)出后還要等32s才知道第5次也超時(shí)了,所以,總共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 63s,TCP才會(huì)斷開這個(gè)連接。

數(shù)據(jù)傳輸

主機(jī)收到一個(gè) TCP 包時(shí),用兩端的IP地址與端口號(hào)來標(biāo)識(shí)這個(gè) TCP 包屬于哪個(gè)session。

TCP 或 UDP 使用了端口號(hào)(Port number)的概念來標(biāo)識(shí)發(fā)送方和接收方的應(yīng)用層,通常也稱為 Internet sockets。對(duì)每個(gè) TCP 連接的一端都有一個(gè)相關(guān)的16位的無符號(hào)端口號(hào)分配給它們。端口被分為三類:眾所周知的、注冊(cè)的和動(dòng)態(tài)/私有的。眾所周知的端口號(hào)是由因特網(wǎng)賦號(hào)管理局(IANA)來分配的,并且通常被用于系統(tǒng)一級(jí)或根進(jìn)程。眾所周知的應(yīng)用程序作為服務(wù)器程序來運(yùn)行,并被動(dòng)地偵聽經(jīng)常使用這些端口的連接。例如:FTP (20 and 21), SSH (22), TELNET (23), SMTP (25), HTTP over SSL/TLS (443), and HTTP (80)等。注冊(cè)的端口號(hào)通常被用來作為終端用戶連接服務(wù)器時(shí)短暫地使用的源端口號(hào),但它們也可以用來標(biāo)識(shí)已被第三方注冊(cè)了的、被命名的服務(wù)。動(dòng)態(tài)/私有的端口號(hào)在任何特定的TCP連接外不具有任何意義??赡艿?、被正式承認(rèn)的端口號(hào)有65535個(gè)。

超時(shí)重傳

另外,對(duì)于 TCP 數(shù)據(jù)傳輸 ,有一個(gè)重要的概念提到的就是 超時(shí)重傳。這個(gè)機(jī)制是進(jìn)一步來證明為何 TCP 是一種可靠的傳輸。

發(fā)送方使用一個(gè)保守估計(jì)的時(shí)間作為收到數(shù)據(jù)包的確認(rèn)的超時(shí)上限。如果超過這個(gè)上限仍未收到確認(rèn)包,發(fā)送方將重傳這個(gè)數(shù)據(jù)包。每當(dāng)發(fā)送方收到確認(rèn)包后,會(huì)重置這個(gè)重傳定時(shí)器。

這個(gè)超時(shí)定義就是 RTT (來回通訊延遲(Round-trip delay time)) 在的定義。

連接終止

使用了四次握手 (four-way handshake) ,終止一個(gè) TCP 連接


TCP 四次握手終止連接

更詳細(xì)的資料可以參考 Wikipedia

1.4 UDP

除了可靠的 TCP 連接,還有一種稱為不可靠的連接機(jī)制: 用戶數(shù)據(jù)包協(xié)議(User Datagram Protocol,縮寫為UDP),是一個(gè)簡(jiǎn)單的面向數(shù)據(jù)報(bào)的傳輸層協(xié)議。此協(xié)議由 David P. Reed 在 1980 年設(shè)計(jì)出來,并納入 RFC 768 成為正式的規(guī)范。

兩者各有利弊,UDP 無需建立連接,不保證傳輸?shù)目煽啃?,也沒有重試機(jī)制,所以它的效率更高,當(dāng)然數(shù)據(jù)傳輸?shù)馁|(zhì)量也不保證。

在TCP/IP模型中,UDP為網(wǎng)絡(luò)層以上和應(yīng)用層以下提供了一個(gè)簡(jiǎn)單的接口。UDP只提供數(shù)據(jù)的不可靠傳遞,它一旦把應(yīng)用程序發(fā)給網(wǎng)絡(luò)層的數(shù)據(jù)發(fā)送出去,就不保留數(shù)據(jù)備份(所以UDP有時(shí)候也被認(rèn)為是不可靠的數(shù)據(jù)報(bào)協(xié)議)。UDP在IP數(shù)據(jù)報(bào)的頭部?jī)H僅加入了復(fù)用和數(shù)據(jù)校驗(yàn)(字段)。

網(wǎng)絡(luò)上的眾多使用UDP協(xié)議的關(guān)鍵應(yīng)用一定程度上是相似的。這些應(yīng)用包括域名系統(tǒng)(DNS)、簡(jiǎn)單網(wǎng)絡(luò)管理協(xié)議(SNMP)、動(dòng)態(tài)主機(jī)配置協(xié)議(DHCP)、路由信息協(xié)議(RIP)和某些影音流服務(wù)等等。

1.5 Socket

上面我們提到了 Socket ?按字面的意思是插座的意思,也就是建立一個(gè)通道,進(jìn)行通信或連接。


Socket 工作流

根據(jù) OSI 模型,它是基于傳輸層 (TCP/UDP) 上的一種具體實(shí)現(xiàn)。有了 TCP/UDP 協(xié)議,雙方可以按照協(xié)議的規(guī)定,搭建起連接,一但連接搭建起來,我們就稱它為 Socket 連接已建立,相當(dāng)于插到插座上了。

在計(jì)算機(jī)科學(xué)中

它通常代表網(wǎng)絡(luò)套接字(Network socket),又譯網(wǎng)絡(luò)插槽,是電腦網(wǎng)絡(luò)中進(jìn)程間互相通信的一種機(jī)制。使用互聯(lián)網(wǎng)協(xié)議(Internet Protocol)為通信基礎(chǔ)的網(wǎng)絡(luò)套接字,稱為 Internet socket。因?yàn)榛ヂ?lián)網(wǎng)協(xié)議的流行,現(xiàn)代絕大多數(shù)的網(wǎng)絡(luò)套接字,都是屬于 Internet socket。

在操作系統(tǒng)中

它是一種提供進(jìn)程間通信的機(jī)制。通常會(huì)為應(yīng)用程序提供一組應(yīng)用程序接口(API),稱為套接字接口(socket API)。應(yīng)用程序可以通過套接字接口,來使用網(wǎng)絡(luò)套接字,以進(jìn)行數(shù)據(jù)交換。最早的套接字接口來自于4.2 BSD,因此現(xiàn)代常見的套接字接口大多源自Berkeley套接字(Berkeley sockets)標(biāo)準(zhǔn)。在套接字接口中,以IP地址及通信端口組成套接字地址(socket address)。遠(yuǎn)程的套接字地址,以及本地的套接字地址完成連接后,再加上使用的協(xié)議(protocol),這個(gè)五元組(five-element tuple),作為套接字對(duì)(socket pairs),之后就可以彼此交換數(shù)據(jù)。

例如,再同一臺(tái)計(jì)算機(jī)上,TCP 協(xié)議與 UDP 協(xié)議可以同時(shí)使用相同的port而互不干擾。 操作系統(tǒng)根據(jù)套接字地址,可以決定應(yīng)該將數(shù)據(jù)送達(dá)特定的進(jìn)程或線程。這就像是電話系統(tǒng)中,以電話號(hào)碼加上分機(jī)號(hào)碼,來決定通話對(duì)象一般。

所以也可以理解為 socket = IP + Port

這里有 C 寫的 Socket Demo 大家可以參考。其中 accept 函數(shù)也就是實(shí)現(xiàn)了三次了握手的過程。

2. 應(yīng)用層

2.1 HTTP

應(yīng)用層里最常用的協(xié)議之一,Hypertext Transfer Protocol (HTTP) 超文本傳輸協(xié)議。

HTTP 歷史

- 1965 年,一個(gè)叫 Ted Nelson 的 26 歲年輕人,提出了超文本與超媒體的概念。(真是英雄出少年)

- 1989 年,時(shí)隔多年,一個(gè)叫 Tim Berners-Lee 和他的團(tuán)隊(duì)在 CERN(歐洲核子研究組織)基于超文本概念,開始了 WorldWideWeb 項(xiàng)目。也就是我們現(xiàn)在耳熟能詳?shù)?WWW (萬(wàn)維網(wǎng)),將超文本系統(tǒng)與互聯(lián)網(wǎng)結(jié)合在一起,將超文本數(shù)據(jù)發(fā)送出去。第一個(gè)版本只有一個(gè)方法,叫 GET ,它可以從服務(wù)器請(qǐng)求一個(gè)頁(yè)面到客戶端,這個(gè)頁(yè)面就是 HTML 頁(yè)。

- 1991 年,第一個(gè) HTTP 的文檔 HTTP 0.9 定義出來。世界上第一個(gè)網(wǎng)站在 CERN 搭建。

- 1996 年,HTTP 1.0 標(biāo)準(zhǔn)發(fā)布。Dave Raggett 領(lǐng)導(dǎo)的 HTTP Working Group (HTTP WG) 擴(kuò)充了 HTTP 的協(xié)議,增加了富媒體信息,安全協(xié)議,header 域等。

- 1997 年,HTTP 1.1 標(biāo)準(zhǔn)被制定。

- 2015 年,HTTP 2.0 發(fā)布

關(guān)于 HTTP Session

一個(gè) HTTP session 是一個(gè)網(wǎng)絡(luò)的 request-response 序列。一個(gè) HTTP 客戶端初始時(shí)請(qǐng)求建立一個(gè) TCP 連接到服務(wù)器的指定端口(通常為 80)。一個(gè) HTTP 服務(wù)端一直監(jiān)聽來自客戶端的 request 信息。基于接收的 request, 服務(wù)器返回狀態(tài)行,如 "HTTP/1.1 200 OK"。

2.1 HTTP 0.9 ~ 2.0 進(jìn)化之路


HTTP 0.9 :

只有 GET 一只方法,不支持請(qǐng)求頭

HTTP 1.0 :

增加了請(qǐng)求頭,除了 GET 外,多了很多方法,如 POST,? HEAD, PUT 等。

HTTP 1.1 :

由于 HTTP 1.0 只保持短暫的連接,每次請(qǐng)求后,TCP 連接都會(huì)被關(guān)閉,導(dǎo)致大量的時(shí)間耗費(fèi)在了建立連接上。另一個(gè)問題是, HTTP 1.0 的請(qǐng)求像一個(gè)隊(duì)列,遵循 FIFO (先進(jìn)先出)的原則,當(dāng)?shù)谝粋€(gè)請(qǐng)求的 Response 返回后,第二個(gè) Request 才能發(fā)出,這就是所說的 head of line blocking (HOL blocking)。

所以 HTTP 1.1 對(duì)這兩個(gè)主要問題進(jìn)行了改進(jìn)

a. 支持了持久連接,在一個(gè)TCP連接上可以傳送多個(gè)HTTP請(qǐng)求和響應(yīng),減少了建立和關(guān)閉連接的消耗和延遲。

b.允許客戶端不用等待上一次請(qǐng)求結(jié)果返回,就可以發(fā)出下一次請(qǐng)求,但服務(wù)器端必須按照接收到客戶端請(qǐng)求的先后順序依次回送響應(yīng)結(jié)果,以保證客戶端能夠區(qū)分出每次請(qǐng)求的響應(yīng)內(nèi)容,這樣也顯著地減少了整個(gè)下載過程所需要的時(shí)間。

此外,1.1 協(xié)議中還支持了身份認(rèn)證、狀態(tài)管理和Cache緩存等機(jī)制,可以很方便的實(shí)現(xiàn)如斷點(diǎn)續(xù)傳等場(chǎng)景。

HTTP 1.0 與 HTTP 1.1 的主要區(qū)別可以看這里:Key Differences between HTTP/1.0 and HTTP/1.1


HTTP 1.1 / 1.0 區(qū)別

HTTP Pipelining

它是將多個(gè)HTTP 請(qǐng)求整批提交的技術(shù),而在發(fā)送過程中不需先等待服務(wù)端的回應(yīng)。

請(qǐng)求結(jié)果管線化使得 HTML 網(wǎng)頁(yè)加載時(shí)間動(dòng)態(tài)提升,特別是在具有高延遲的連接環(huán)境下。在寬帶連接中,加速不是那么顯著的,因?yàn)樾枰?wù)器端應(yīng)用 HTTP/1.1 協(xié)議:服務(wù)器端必須按照客戶端的請(qǐng)求順序恢復(fù)請(qǐng)求,這樣整個(gè)連接還是先進(jìn)先出的,對(duì)頭阻塞(HOL blocking)可能會(huì)發(fā)生,造成延遲。

Pipelining

HTTP 2.0:

實(shí)際上 HTTP 1.1 使用了很長(zhǎng)時(shí)間后,一直沒有經(jīng)過大的改進(jìn),基本上也就是在原來的基礎(chǔ)上進(jìn)行小范圍的協(xié)議優(yōu)化與擴(kuò)充。直到 Google 推出了 SPDY 后,HTTP 2.0 基于 SPDY 的基礎(chǔ)上,被正式提出。

它主要解決了 HTTP 1.0 或 1.1 中始終存在的 HOL blocking 問題。


HTTP 2.0 二進(jìn)制分幀

它并沒有破壞原有的 HTTP 結(jié)構(gòu),僅僅是將數(shù)據(jù)采用了二進(jìn)制傳輸,比起以前的文本傳輸,更緊湊與高效。在二進(jìn)制分幀層上,HTTP2.0 會(huì)將所有傳輸?shù)男畔⒎指顬楦〉南⒑蛶?,并?duì)它們采用二進(jìn)制格式的編碼,其中 HTTP1.x 的首部信息會(huì)被封裝到 Headers 幀,而我們的 request body 則封裝到 Data 幀里面。


HTTP 2.0 連接

新的二進(jìn)制分幀機(jī)制改變了客戶端與服務(wù)器之間交換數(shù)據(jù)的方式。 為了說明這個(gè)過程,我們需要了解 HTTP/2 的三個(gè)概念:

數(shù)據(jù)流:已建立的連接內(nèi)的雙向字節(jié)流,可以承載一條或多條消息。

消息:與邏輯請(qǐng)求或響應(yīng)消息對(duì)應(yīng)的完整的一系列幀。

:HTTP/2 通信的最小單位,每個(gè)幀都包含幀頭,至少也會(huì)標(biāo)識(shí)出當(dāng)前幀所屬的數(shù)據(jù)流。

這些概念的關(guān)系總結(jié)如下:

1. 所有通信都在一個(gè) TCP 連接上完成,此連接可以承載任意數(shù)量的雙向數(shù)據(jù)流。

2. 每個(gè)數(shù)據(jù)流都有一個(gè)唯一的標(biāo)識(shí)符和可選的優(yōu)先級(jí)信息,用于承載雙向消息。

3. 每條消息都是一條邏輯 HTTP 消息(例如請(qǐng)求或響應(yīng)),包含一個(gè)或多個(gè)幀。

4. 幀是最小的通信單位,承載著特定類型的數(shù)據(jù),例如 HTTP 標(biāo)頭、消息負(fù)載,等等。 來自不同數(shù)據(jù)流的幀可以交錯(cuò)發(fā)送,然后再根據(jù)每個(gè)幀頭的數(shù)據(jù)流標(biāo)識(shí)符重新組裝。

這里的關(guān)鍵是數(shù)據(jù)流有了優(yōu)先級(jí),而不必像以前按順序處理,服務(wù)端可以根據(jù)自定義的優(yōu)先級(jí)處理 request。

還有一個(gè)大的改進(jìn)是服務(wù)器推送,HTTP 2.0 不必像以前一樣,必須依賴 request 才發(fā)送 response ,打破了嚴(yán)格的請(qǐng)求-響應(yīng)語(yǔ)義。即使客戶端沒有 Request 請(qǐng)求,服務(wù)端也可以發(fā)送 Response 給客戶端。

* tips: 大家可以在命令行下,輸入以下命令,看看兩者有何不同。
telnet www.google.com 80
GET / HTTP/1.0

GET / HTTP/1.1

2.2. HTTPS

關(guān)于 HTTPS 中的 S ,即安全傳輸,之前已經(jīng)講到了,它是在介于傳輸層與應(yīng)用層之間的一層安全協(xié)議,基于可靠傳輸(如 TCP )之后,對(duì)信息的一層加密封裝。

相信大家可以在很多地方搜到 HTTPS 的詳細(xì)解釋。這里就不逐一展開了。我們只要記住以下幾點(diǎn)即可。

首先是,對(duì)稱加密與非對(duì)稱加密,兩種加密方式最大的區(qū)別在于,對(duì)稱加密沒有數(shù)據(jù)長(zhǎng)度限制,非對(duì)稱有長(zhǎng)度限制,所以要使用非對(duì)稱加密傳輸對(duì)稱加密的密鑰。

其次,非對(duì)稱加密中的公鑰,不能直接發(fā)送給對(duì)方,否則會(huì)產(chǎn)生中間人攻擊的場(chǎng)景。必須有一個(gè)可靠的第三方做中間人。這就是我們大家所熟知的 CA (數(shù)字證書的頒發(fā)機(jī)構(gòu))。

這個(gè) CA 通常會(huì)根據(jù)域名來做服務(wù)器端的認(rèn)證,而且 CA 的公鑰是被內(nèi)置在瀏覽器或操作系統(tǒng)中的,所以 CA 的公鑰是不用傳輸?shù)摹_@樣就避免了中間人的證書偽造。

之前有人已經(jīng)寫過一篇 非常通俗易懂的文章 ,大家可以做參考。

2.3. WebSocket

提到應(yīng)用層協(xié)議,其實(shí)還有一個(gè)比較流行的協(xié)議就是 WebSocket ,它在 2011 年被被IETF 定為標(biāo)準(zhǔn) RFC 6455。

WebSocket使得客戶端和服務(wù)器之間的數(shù)據(jù)交換變得更加簡(jiǎn)單,允許服務(wù)端主動(dòng)向客戶端推送數(shù)據(jù)。在 WebSocket API 中,瀏覽器和服務(wù)器只需要完成一次握手,兩者之間就直接可以創(chuàng)建持久性的連接,并進(jìn)行雙向數(shù)據(jù)傳輸。

為什么叫 WebSocket 呢?它和 Socket 什么關(guān)系?

首先 WebSocket 和 Socket 沒有半毛錢關(guān)系,它之所以這么叫,完全是為了利于理解。之所以強(qiáng)調(diào) Web,是因?yàn)樗梢曰?HTTP 連接進(jìn)行協(xié)議切換。還記得之前 HTTP /1.1 里的 request header 嗎?我們可以定義 Upgrade: websocket Connection: Upgrade。然后服務(wù)器的 response 會(huì)返回:? HTTP/1.1 101 Switching Protocols。即可切換到 WebSocket 協(xié)議。


WebSocket communication

web socket 使用 ws 或 wss 做為統(tǒng)一的標(biāo)識(shí)符。如:ws://www.abc.com

實(shí)踐:基于 node JS 的 WebSocket 客戶端與服務(wù)端開源項(xiàng)目

3. 總結(jié)

回答開始所提出的問題

1. 當(dāng)我們打開瀏覽器訪問一個(gè)網(wǎng)頁(yè)時(shí),它是如何將數(shù)據(jù)安全的發(fā)送給我們的?

如果有域名的先通過 DNS 解析域名,如果是 IP 直接訪問的就不用了。然后排開底層網(wǎng)絡(luò)協(xié)議不看,從傳輸層開始,先進(jìn)行三次握手,有 S 的進(jìn)行加密通道的建立,拿到傳輸密鑰。然后基于應(yīng)用層的協(xié)議,比如 HTTP ,進(jìn)行 Request 與 Response 的數(shù)據(jù)傳輸。根據(jù)使用的 HTTP 協(xié)議不同,建立的連接有可能是持續(xù)的,也有可能是一次性的。

2. Http 2.0 為何時(shí)隔10年才出現(xiàn),它解決了什么問題?

HTTP 1.1 出來后,基本上在上面做補(bǔ)充與小調(diào)整,沒有實(shí)質(zhì)的變化。直到十年后,憑借 Google 強(qiáng)大的技術(shù)研發(fā)能力,加上現(xiàn)代的網(wǎng)絡(luò)基礎(chǔ)設(shè)施越來越好,提出了二進(jìn)制流傳輸方式,解決了 HOL blocking 問題。并最終成為了 HTTP /2.0 的標(biāo)準(zhǔn)。目前,在應(yīng)用層上,可優(yōu)化的空間越來越小,接下來的瓶頸更多是傳輸層了,但傳輸?shù)膶拥淖兓瑫?huì)牽扯所有現(xiàn)有的瀏覽器與操作系統(tǒng),所以這一塊的演化沒有想像的那么快。也許將來有一天,會(huì)有更新的技術(shù)出現(xiàn)。

3. Socket 和 Http 什么關(guān)系?

Socket 是通道,在網(wǎng)絡(luò)領(lǐng)域,它是一個(gè) Network Socket ,建立兩個(gè)端之間的一條管道,進(jìn)行數(shù)據(jù)的傳輸。HTTP 是基于這個(gè)管理,進(jìn)行超文本的傳輸。簡(jiǎn)單的講, Socket 一但建立,你可以傳輸任何東西,HTTP 也好, FTP 也好。取決于你的應(yīng)用協(xié)議是什么。

4. Web socket 又是什么?它是工作在哪一層的?

Web Socket 只是一個(gè)雙工通信概念,它為了解決 HTTP 只能通過 Request 與 Response 的形式發(fā)送信息的模式,無論是客戶端還是服務(wù)端都可以主動(dòng)的發(fā)送數(shù)據(jù)。HTTP /2.0 也加入了此概念。但 WebSocket 發(fā)明的比它早,所以它是前輩。

它工作在傳輸之上,應(yīng)用層的一種,可以理解為 HTTP 的升級(jí)版。因?yàn)樗梢岳?HTTP 的協(xié)議,進(jìn)行升級(jí)使用,所以稱為 Web Socket.

5. 想要更輕量,更有效率的傳輸如何做?

你可以直接面向 Socket 編程,傳輸層之上進(jìn)行開發(fā),自己發(fā)明更輕量,更高效的應(yīng)用層協(xié)議?,F(xiàn)有的操作系統(tǒng),對(duì) TCP 接口有非常標(biāo)準(zhǔn),完善的編程接口,開發(fā)也不是難事了。所以你可根據(jù)應(yīng)用的場(chǎng)景,定制更合適的應(yīng)用層協(xié)議。

推薦買一本 Socket 網(wǎng)絡(luò)編程開始學(xué)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容