網路協議 - TCP/IP、HTTP、HTTPS、HTTP2.0

水中花world發表於2018-05-31

HTTP,全稱超文字傳輸協議(HTTP,HyperText Transfer Protocol),是一個客戶端和伺服器端請求和應答的標準(TCP),網際網路上應用最為廣泛的一種網路協議。客戶端是終端使用者,伺服器端是網站。通過使用Web瀏覽器、網路爬蟲或者其它的工具,客戶端發起一個到伺服器上指定埠(預設埠為80)的HTTP請求。*

HTTPS,即加密後的HTTP。HTTP協議傳輸的資料都是未加密的,也就是明文的,因此使用HTTP協議傳輸隱私資訊非常不安全。HTTPS都是用的TLS協議,但是由於SSL出現的時間比較早,並且依舊被現在瀏覽器所支援,因此SSL依然是HTTPS的代名詞,但無論是TLS還是SSL都是上個世紀的事情,SSL最後一個版本是3.0,今後TLS將會繼承SSL優良血統繼續為我們進行加密服務。目前TLS的版本是1.2,定義在RFC 5246中,暫時還沒有被廣泛的使用。

HTTP2.0,下一代的HTTP協議。相比於HTTP1.x,大幅度的提升了web效能,進一步減少了網路延時和擁塞。

這裡寫圖片描述
各自的RFC相關文件自己去搜吧,https://www.rfc-editor.org/

一、TCP/IP
為了瞭解HTTP,有必要先理解一下TCP/IP。目前,存在兩種劃分模型的方法,OSI七層模型和TCP/IP模型,具體的區別不在闡述。HTTP是建立在TCP協議之上,所以HTTP協議的瓶頸及其優化技巧都是基於TCP協議本身的特性,例如tcp建立連線的3次握手和斷開連線的4次揮手以及每次建立連線帶來的RTT延遲時間。
這裡寫圖片描述

TCP三次握手四次揮手的原理,由於篇幅關係,具體請看TCP協議的三次握手和四次揮手,

二、HTTP
超文字傳輸協議(HyperText Transfer Protocol) 是伴隨著計算機網路和瀏覽器而誕生,在瀏覽器出現之前,人們是怎麼使用網路的?,不管怎麼說,那個時代對於現在的我們,有點難以想象。。。之後,網景釋出了Netscape Navigator瀏覽器,才慢慢開啟了網際網路的幕布。如果根據OSI來劃分的話,HTML屬於表示層,而HTTP屬於應用層。HTTP發展至今,經過了HTTP0.9、HTTP1.0、HTTP1.1、HTTP2.0的時代,雖然2.0很久之前就正式提出標準,大多瀏覽器也支援了,但是網路支援HTTP2.0的卻很少。

2.1 HTTP報文分析
報文,是網路中交換和傳輸的基本單元,即一次性傳送的資料塊。HTTP的報文是由一行一行組成的,純文字,而且是明文,即:如果能監聽你的網路,那麼你傳送的所有賬號密碼都是可以看見的,為了保障資料隱祕性,HTTPS隨之而生。

2.1.1 請求報文:
為了形象點,我們把報文標準和實際的結合起來看。

這裡寫圖片描述

下面是實際報文,以訪問自己的網站(http://www.wenzhihuai.com)中的一個連結為例。

這裡寫圖片描述

請求行
請求行由方法欄位、URL 欄位 和HTTP 協議版本欄位 3 個部分組成,他們之間使用空格隔開。常用的 HTTP 請求方法有 GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT,這裡我們使用的是GET方法,訪問的是/biaoqianyun.do,協議使用的是HTTP/1.1。
GET:當客戶端要從伺服器中讀取某個資源時,使用GET 方法。如果需要加傳引數的話,需要在URL之後加個”?”,然後把引數名字和值用=連線起來,傳遞引數長度受限制,通常IE8的為4076,Chrome的為7675。例如,/index.jsp?id=100&op=bind。
POST:當客戶端給伺服器提供資訊較多時可以使用POST 方法,POST 方法向伺服器提交資料,比如完成表單資料的提交,將資料提交給伺服器處理。GET 一般用於獲取/查詢資源資訊,POST 會附帶使用者資料,一般用於更新資源資訊。POST 方法將請求引數封裝在HTTP 請求資料中,以名稱/值的形式出現,可以傳輸大量資料;

請求頭部
請求頭部由關鍵字/值對組成,每行一對,關鍵字和值用英文冒號“:”分隔。請求頭部通知伺服器有關於客戶端請求的資訊,典型的請求頭有:
User-Agent:產生請求的瀏覽器型別;
Accept:客戶端可識別的響應內容型別列表;星號 “ * ” 用於按範圍將型別分組,用 “ / ” 指示可接受全部型別,用“ type/* ”指示可接受 type 型別的所有子型別;
Accept-Language:客戶端可接受的自然語言;
Accept-Encoding:客戶端可接受的編碼壓縮格式;
Accept-Charset:可接受的應答的字符集;
Host:請求的主機名,允許多個域名同處一個IP 地址,即虛擬主機;
connection:連線方式(close 或 keepalive),如果是close的話就需要進行TCP四次揮手關閉連線,如果是keepalive,表明還能繼續使用,這是HTTP1.1對1.0的新增,加快了網路傳輸,預設是keepalive;
Cookie:儲存於客戶端擴充套件欄位,向同一域名的服務端傳送屬於該域的cookie;

空行
最後一個請求頭之後是一個空行,傳送回車符和換行符,通知伺服器以下不再有請求頭;

請求包體
請求包體不在 GET 方法中使用,而是在POST 方法中使用。POST 方法適用於需要客戶填寫表單的場合。與請求包體相關的最常使用的是包體型別 Content-Type 和包體長度 Content-Length;

2.1.2 響應報文
同樣,先貼上報文標準。

這裡寫圖片描述

抓包,以訪問(http://www.wenzhihuai.com)為例。

這裡寫圖片描述

狀態行
狀態行由 HTTP 協議版本欄位、狀態碼和狀態碼的描述文字 3 個部分組成,他們之間使用空格隔開,描述文字一般不顯示;
狀態碼:由三位數字組成,第一位數字表示響應的型別,常用的狀態碼有五大類如下所示:
1xx:伺服器已接收,但客戶端可能仍要繼續傳送;
2xx:成功;
3xx:重定向;
4xx:請求非法,或者請求不可達;
5xx:伺服器內部錯誤;

響應頭部:響應頭可能包括:
Location:Location響應報頭域用於重定向接受者到一個新的位置。例如:客戶端所請求的頁面已不存在原先的位置,為了讓客戶端重定向到這個頁面新的位置,伺服器端可以發回Location響應報頭後使用重定向語句,讓客戶端去訪問新的域名所對應的伺服器上的資源;
Server:Server 響應報頭域包含了伺服器用來處理請求的軟體資訊及其版本。它和 User-Agent 請求報頭域是相對應的,前者傳送伺服器端軟體的資訊,後者傳送客戶端軟體(瀏覽器)和作業系統的資訊。
Vary:指示不可快取的請求頭列表;
Connection:連線方式,這個跟rquest的類似。
空行:最後一個響應頭部之後是一個空行,傳送回車符和換行符,通知伺服器以下不再有響應頭部。
響應包體:伺服器返回給客戶端的文字資訊;

2.2 HTTP特性
HTTP的主要特點主要能概括如下:

2.2.1 無狀態性
即,當客戶端訪問完一次伺服器再次訪問的時候,伺服器是無法知道這個客戶端之前是否已經訪問過了。優點是不需要先前的資訊,能夠更快的應答,缺點是每次連線傳送的資料量增大。這種做法不利於資訊的互動,隨後,Cookie和Session就應運而生,至於它倆有什麼區別,可以看看COOKIE和SESSION有什麼區別?。

2.2.2 持久連線
HTTP1.1 使用持久連線keepalive,所謂持久連線,就是伺服器在傳送響應後仍然在一段時間內保持這條連線,允許在同一個連線中存在多次資料請求和響應,即在持久連線情況下,伺服器在傳送完響應後並不關閉TCP連線,客戶端可以通過這個連線繼續請求其他物件。

2.2.3 其他
支援客戶/伺服器模式、簡單快速(請求方法簡單Get和POST)、靈活(資料物件任意)

2.3 影響HTTP的因素
影響HTTP請求的因素:

1、頻寬
好像只要上網這個因素是一直都有的。。。即使再快的網路,也會有偶爾網路慢的時候。。。
2、延遲
(1) 瀏覽器阻塞
一個瀏覽器對於同一個域名,同時只能有4個連結(根據不同瀏覽器),如果超了後面的會被阻塞。
常用瀏覽器阻塞數量看下圖。

這裡寫圖片描述

(2) DNS查詢
瀏覽器建立連線是需要知道伺服器的IP的,DNS用來將域名解析為IP地址,這個可以通過重新整理DNS快取來加快速度。
(3) 建立連線
由之前第一章的就可以看出,HTTP是基於TCP協議的,即使網路、瀏覽器再快也要進行TCP的三次握手,在高延遲的場景下影響比較明顯,慢啟動則對檔案請求影響較大。

2.4 缺陷
耗時:傳輸資料每次都要建立連線;
不安全:HTTP是明文傳輸的,只要在路由器或者交換機上擷取,所有東西(賬號密碼)都是可見的;
Header內容過大:通常,客戶端的請求header變化較小,但是每次都要攜帶大量的header資訊,導致傳輸成本增大;
keepalive壓力過大:持久連線雖然有一點的優點,但同時也會給伺服器造成大量的效能壓力,特別是傳輸圖片的時候。
BTW:明文傳輸有多危險,可以去試試,下面是某個政府網站,採用wireshark抓包,身份證、電話號碼、住址什麼的全暴露出來,所以,,,只要在路由器做點小動作,你的資訊是全部能拿得到的,畢竟政府。

這裡寫圖片描述

由於涉及的隱私太多,打了馬賽克

三、HTTPS
由於HTTP報文的不安全性,網景在1994年就建立了HTTPS,並用在瀏覽器中。最初HTTPS是和SSL一起使用,然後演化為TLS。SSL/TLS在OSI模型中都是表示層的協議。SSL使 用40 位關鍵字作為RC4流加密演算法,這對於商業資訊的加密是合適的。

3.1 SSL/TLS
SSL(Secure Sockets Layer),簡稱安全套接入層,最初由上世紀90年代由網景公司設計。開啟 SSL 會增加記憶體、CPU、網路頻寬的開銷,後二者跟你使用的 cipher suite 密切相關,其中引數很多,很難一概而論。開啟 SSL 的前提是你的 cert 和 key 必須放在 TCP endpoint,你是否信得過那臺裝置。
TLS(Transport Layer Security),簡稱安全傳輸層協議,該協議由兩層組成: TLS 記錄協議(TLS Record)和 TLS 握手協議(TLS Handshake)。較低的層為 TLS 記錄協議,位於某個可靠的傳輸協議(例如 TCP)上面,與具體的應用無關,所以,一般把TLS協議歸為傳輸層安全協議。
由於本人在加密演算法上面知識匱乏,就不誤人子弟了,有興趣可以看看百度百科裡的資料,SSL,TLS

3.2 SPDY
2012年google提出了SPDY的方案,大家才開始從正面看待和解決老版本HTTP協議本身的問題,SPDY可以說是綜合了HTTPS和HTTP兩者有點於一體的傳輸協議,主要解決:
降低延遲,針對HTTP高延遲的問題,SPDY優雅的採取了多路複用(multiplexing)。多路複用通過多個請求stream共享一個tcp連線的方式,解決了HOL blocking的問題,降低了延遲同時提高了頻寬的利用率。
請求優先順序(request prioritization)。多路複用帶來一個新的問題是,在連線共享的基礎之上有可能會導致關鍵請求被阻塞。SPDY允許給每個request設定優先順序,這樣重要的請求就會優先得到響應。比如瀏覽器載入首頁,首頁的html內容應該優先展示,之後才是各種靜態資原始檔,指令碼檔案等載入,這樣可以保證使用者能第一時間看到網頁內容。
header壓縮。前面提到HTTP1.x的header很多時候都是重複多餘的。選擇合適的壓縮演算法可以減小包的大小和數量。
基於HTTPS的加密協議傳輸,大大提高了傳輸資料的可靠性。
服務端推送(server push),採用了SPDY的網頁,例如我的網頁有一個sytle.css的請求,在客戶端收到sytle.css資料的同時,服務端會將sytle.js的檔案推送給客戶端,當客戶端再次嘗試獲取sytle.js時就可以直接從快取中獲取到,不用再發請求了。SPDY構成圖。

這裡寫圖片描述

3.3 HTTPS報文分析
跟之前的報文分析一樣,我們使用wireshark來抓包分析,以在百度上搜尋點東西為例。

這裡寫圖片描述

192.168.1.103為本地電腦的ip地址,14.215.177.39為百度伺服器地址。下面是步驟:

客戶端通過傳送 Client Hello 報文開始 SSL 通訊。報文中包含客戶端支援的 SSL 的指定版本、加密元件(Cipher Suite)列表(所使用的加密演算法及金鑰長度等)。
伺服器可進行 SSL 通訊時,會以 Server Hello 報文作為應答。和客戶端一樣,在報文中包含 SSL 版本以及加密元件。伺服器的加密元件內容是從接收到的客戶端加密元件內篩選出來的。之後伺服器傳送 Certificate 報文。報文中包含公開金鑰證書。最後伺服器傳送 Server Hello Done 報文通知客戶端,最初階段的SSL握手協商部分結束。
SSL 第一次握手結束之後,客戶端以 Client Key Exchange 報文作為迴應。接著客戶端繼續傳送 Change Cipher Spec 報文。該報文會提示伺服器,在此報文之後的通訊會採用 Pre-master secret 金鑰加密。客戶端傳送 Finished 報文。該報文包含連線至今全部報文的整體校驗值。
伺服器同樣傳送 Change Cipher Spec 報文。 伺服器同樣傳送 Finished 報文。
伺服器和客戶端的 Finished 報文交換完畢之後,SSL 連線就算建立完成。當然,通訊會受到 SSL 的保護。從此處開始進行應用層協議的通訊,即傳送 HTTP請求。 應用層協議通訊,即傳送 HTTP 響應。
當然,用一張圖更容易解釋
簡單地說就是下面。

這裡寫圖片描述

當我們追蹤流的資料的時候,可以看到,基本上都是亂碼,經過加密,資料是看不到,如果需要在wireshark上看到,則需要在wireshark中配置ssl。

這裡寫圖片描述

3.4 HTTPS全站化
現今,感覺只要和商業利益有關的,就不得不涉及到加密這類東西。淘寶、京東、唯品會這些電商可謂是最早推行全站https的,這類電商是離使用者金錢最近的企業。截止今年底,基本所有商業網站也基本實現了HTTPS。。。。至於小站點,比如個人網站,玩玩還是可以的。如果一個網站需要由HTTP全部變為HTTPS,那麼需要關注下面幾點:

CA證書,大部分證書都是需要收費的,當然,自己在伺服器上用openssl也可以,不過瀏覽器會提示當前私密連線不安全這個警告,普通人看到這種資訊是不會繼續瀏覽的,所以,想使用HTTPS,可以使用Let’s Encrypt,由谷歌等公司推行。
HTTPS效能優化,SSL握手,HTTPS 對速度會有一定程度的降低,但是隻要經過合理優化和部署,HTTPS 對速度的影響完全可以接受。
CPU計算壓力,HTTPS中大量的祕鑰演算法計算,對CPU的壓力可想而知。
至於我自己的個人網站,之前實現了https,用的免費證書,但是由於HTTPS下的網站,所有子鏈都要使用HTTPS,使用了七牛雲的CDN,如果要使用HTTPS加速,是要收費的,所以只能放棄。。。
四、HTTP2.0
HTTP2.0,相較於HTTP1.x,大幅度的提升了web效能。在與HTTP/1.1完全語義相容的基礎上,進一步減少了網路延遲和傳輸的安全性。HTTP2.0可以說是SPDY的升級版(基於SPDY設計的),但是依然存在一些不同點:HTTP2.0支援明文傳輸,而SPDY強制使用HTTPS;HTTP2.0訊息頭的壓縮演算法採用HPACK,而非SPDY採用的DEFLATE。

4.1 歷史
HTTP 2.0在2013年8月進行首次合作共事性測試。在開放網際網路上HTTP 2.0將只用於https://網址,而 http://網址將繼續使用HTTP/1,目的是在開放網際網路上增加使用加密技術,以提供強有力的保護去遏制主動攻擊。HTTP 2.0是在SPDY(An experimental protocol for a faster web, The Chromium Projects)基礎上形成的下一代網際網路通訊協議。HTTP/2 的目的是通過支援請求與響應的多路複用來較少延遲,通過壓縮HTTPS首部欄位將協議開銷降低,同時增加請求優先順序和伺服器端推送的支援。

4.2 HTTP2.0新特性
相較於HTTP1.1,HTTP2.0的主要優點有采用二進位制幀封裝,傳輸變成多路複用,流量控制演算法優化,伺服器端推送,首部壓縮,優先順序等特點。

4.2.1 二進位制幀
HTTP1.x的解析是基於文字的,基於文字協議的格式解析存在天然缺陷,文字的表現形式有多樣性,要做到健壯性考慮的場景必然很多。而HTTP/2會將所有傳輸的資訊分割為更小的訊息和幀,然後採用二進位制的格式進行編碼,HTTP1.x的頭部資訊會被封裝到HEADER frame,而相應的Request Body則封裝到DATA frame裡面。不改動HTTP的語義,使用二進位制編碼,實現方便且健壯。

這裡寫圖片描述

4.2.2 多路複用
所有的請求都是通過一個 TCP 連線併發完成。HTTP/1.x 雖然通過 pipeline 也能併發請求,但是多個請求之間的響應會被阻塞的,所以 pipeline 至今也沒有被普及應用,而 HTTP/2 做到了真正的併發請求。同時,流還支援優先順序和流量控制。當流併發時,就會涉及到流的優先順序和依賴。即:HTTP2.0對於同一域名下所有請求都是基於流的,不管對於同一域名訪問多少檔案,也只建立一路連線。優先順序高的流會被優先傳送。圖片請求的優先順序要低於 CSS 和 SCRIPT,這個設計可以確保重要的東西可以被優先載入完。

4.2.3 流量控制
TCP協議通過sliding window的演算法來做流量控制。傳送方有個sending window,接收方有receive window。http2.0的flow control是類似receive window的做法,資料的接收方通過告知對方自己的flow window大小表明自己還能接收多少資料。只有Data型別的frame才有flow control的功能。對於flow control,如果接收方在flow window為零的情況下依然更多的frame,則會返回block型別的frame,這張場景一般表明http2.0的部署出了問題。

4.2.4 伺服器端推送
伺服器端的推送,就是伺服器可以對一個客戶端請求傳送多個響應。除了對最初請求的響應外,伺服器還可以額外向客戶端推送資源,而無需客戶端明確地請求。當瀏覽器請求一個html,伺服器其實大概知道你是接下來要請求資源了,而不需要等待瀏覽器得到html後解析頁面再傳送資源請求。

這裡寫圖片描述

4.2.5 首部壓縮
HTTP 2.0 在客戶端和伺服器端使用“首部表”來跟蹤和儲存之前傳送的鍵-值對,對於相同的資料,不再通過每次請求和響應傳送;通訊期間幾乎不會改變的通用鍵-值對(使用者代理、可接受的媒體型別,等等)只 需傳送一次。事實上,如果請求中不包含首部(例如對同一資源的輪詢請求),那麼 首部開銷就是零位元組。此時所有首部都自動使用之前請求傳送的首部。
如果首部發生變化了,那麼只需要傳送變化了資料在Headers幀裡面,新增或修改的首部幀會被追加到“首部表”。首部表在 HTTP 2.0 的連線存續期內始終存在,由客戶端和伺服器共同漸進地更新 。本質上,當然是為了減少請求啦,通過多個js或css合併成一個檔案,多張小圖片拼合成Sprite圖,可以讓多個HTTP請求減少為一個,減少額外的協議開銷,而提升效能。當然,一個HTTP的請求的body太大也是不合理的,有個度。檔案的合併也會犧牲模組化和快取粒度,可以把“穩定”的程式碼or 小圖 合併為一個檔案or一張Sprite,讓其充分地快取起來,從而區分開迭代快的檔案。

4.3 HTTP1.1與HTTP2.0的對比
以訪問https://http2.akamai.com/demo為例。

4.4 報文
訪問https://http2.akamai.com/demo,谷歌瀏覽器的報文沒有顯示出協議,此處使用火狐瀏覽器。
響應頭部分如下。

這裡寫圖片描述

請求頭如下。

這裡寫圖片描述

採用淘寶網站為例,淘寶目前採用主站使用HTTP1.1,資源使用HTTP2.0,少些使用SPDY協議。目前也是業界比較流行的做法。

這裡寫圖片描述

附上參考連結:chttps://www.cnblogs.com/w1570631036/p/8119747.html

相關文章