摘要:協(xié)議,幾乎是每個(gè)人上網(wǎng)用的第一個(gè)協(xié)議,同時(shí)也是很容易被人忽略的協(xié)議。稱為協(xié)議,是一個(gè)域名,表示互聯(lián)網(wǎng)的一個(gè)位置。請(qǐng)求的發(fā)送協(xié)議是基于協(xié)議的,所以它是以面向連接的方式發(fā)送請(qǐng)求,通過二進(jìn)制流的方式傳給對(duì)方。狀態(tài)碼反應(yīng)請(qǐng)求的結(jié)果。
系列文章傳送門:
網(wǎng)絡(luò)協(xié)議 1 - 概述
網(wǎng)絡(luò)協(xié)議 2 - IP 是怎么來,又是怎么沒的?
網(wǎng)絡(luò)協(xié)議 3 - 從物理層到 MAC 層
網(wǎng)絡(luò)協(xié)議 4 - 交換機(jī)與 VLAN:辦公室太復(fù)雜,我要回學(xué)校
網(wǎng)絡(luò)協(xié)議 5 - ICMP 與 ping:投石問路的偵察兵
網(wǎng)絡(luò)協(xié)議 6 - 路由協(xié)議:敢問路在何方?
網(wǎng)絡(luò)協(xié)議 7 - UDP 協(xié)議:性善碰到城會(huì)玩
網(wǎng)絡(luò)協(xié)議 8 - TCP 協(xié)議(上):性惡就要套路深
網(wǎng)絡(luò)協(xié)議 9 - TCP協(xié)議(下):聰明反被聰明誤
網(wǎng)絡(luò)協(xié)議 10 - Socket 編程(上):實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn)
網(wǎng)絡(luò)協(xié)議 11 - Socket 編程(下):眼見為實(shí)耳聽為虛
????網(wǎng)絡(luò)協(xié)議五層通天路,咱們從物理層、到鏈路層、網(wǎng)絡(luò)層、再到傳輸層,現(xiàn)在又進(jìn)一步,來到了應(yīng)用層。這也是我們五層協(xié)議里最上面的一層,關(guān)于應(yīng)用層,有太多協(xié)議要了解。但要說最有名的,那肯定就是 HTTP 了。
????HTTP 協(xié)議,幾乎是每個(gè)人上網(wǎng)用的第一個(gè)協(xié)議,同時(shí)也是很容易被人忽略的協(xié)議。
????就像 http://blog.muzixizao.com/,是個(gè) URL,叫作統(tǒng)一資源定位符。之所以叫統(tǒng)一,是因?yàn)樗怯幸?guī)定格式的。HTTP 稱為協(xié)議,blog.muzixizao.com 是一個(gè)域名,表示互聯(lián)網(wǎng)的一個(gè)位置。有的 URL 會(huì)有更詳細(xì)的位置標(biāo)識(shí),例如
http://blog.muzixizao.com/?p=140
????正是因?yàn)楦袷绞墙y(tǒng)一的,所以當(dāng)你把這樣一個(gè)字符串輸入到瀏覽器的框里的時(shí)候,瀏覽器才知道如何進(jìn)行統(tǒng)一處理。
HTTP 請(qǐng)求的準(zhǔn)備????瀏覽器會(huì)將 blog.muzixizao.com 這個(gè)域名發(fā)送給 DNS 服務(wù)器,讓它解析為 IP 地址。關(guān)于 DNS 解析的過程,較為復(fù)雜,后面會(huì)專門介紹。
????域名解析成 IP 后,下一步是干嘛呢?
????還記得嗎?HTTP 是基于 TCP 協(xié)議的,所以接下來就是建立 TCP 連接了。具體的連接過程可點(diǎn)擊這里查看。
????目前使用的 HTTP 協(xié)議大部分都是 1.1.在 1.1 協(xié)議里面,默認(rèn)開啟了 Keep-Alive 的,這樣建立的 TCP 連接,就可以在多次請(qǐng)求中復(fù)用。雖然 HTTP 用了各種方式來解決它存在的問題,但基于TCP 的它,每次建立連接的三次握手以及斷開連接的四次揮手,這個(gè)過程還是挺費(fèi)時(shí)的。如果好不容易建立了連接,然后做一點(diǎn)兒事情就結(jié)束了,未免太浪費(fèi)了。
HTTP 請(qǐng)求的構(gòu)建????建立了連接以后,瀏覽器就要發(fā)送 HTTP 的請(qǐng)求。請(qǐng)求的格式如下圖:
????如圖,HTTP 的報(bào)文大概分為請(qǐng)求行、首部、正文實(shí)體三部分。接下來,咱們就來一一認(rèn)識(shí)。
請(qǐng)求行????在請(qǐng)求行中,URL 就是 http://blog.muzixizao.com,版本為 HTTP 1.1。這里要說一下的,就是對(duì)應(yīng)的請(qǐng)求方法。有以下幾種類型:
1)GET 請(qǐng)求
????對(duì)于訪問網(wǎng)頁來講,最常用的類型就是 GET。顧名思義,GET 就是去服務(wù)器獲取一些資源。對(duì)于訪問網(wǎng)頁來講,要獲取的資源往往是一個(gè)頁面。其實(shí)也有很多其他的格式,比如返回一個(gè) JSON 字符串。當(dāng)然,具體要返回什么,是由服務(wù)端決定的。
????例如,在云計(jì)算中,如果我們的服務(wù)端要提供一個(gè)基于 HTTP 協(xié)議的 API,獲取所有云主機(jī)的列表,就會(huì)使用 GET 方法請(qǐng)求,返回的可能是一個(gè) JSON 字符串,字符串里面是一個(gè)列表,列表里面會(huì)有各個(gè)云主機(jī)的信息。
2)POST 請(qǐng)求
????另一種類型叫做 POST。它需要主動(dòng)告訴服務(wù)端一些信息,而非獲取。而要告訴服務(wù)端的信息,一般都放在正文里面。正文里有各種各樣的格式,最常見的的就是 JSON了。
????例如,我們平時(shí)的支付場(chǎng)景,客戶端就需要把 “我是誰?我要支付多少?我要買什么?” 這樣信息告訴服務(wù)器,這就需要 POST 方法。
????再如,在云計(jì)算里,如果我們的服務(wù)器,要提供一個(gè)基于 HTTP 協(xié)議的創(chuàng)建云主機(jī)的 API,也會(huì)用到 POST 方法。這個(gè)時(shí)候往往需要將 “我要?jiǎng)?chuàng)建多大的云主機(jī)?多少 CPU 和多少內(nèi)存?多大硬盤?” 這些信息放在 JSON 字符串里面,通過 POST 的方法告訴服務(wù)器。
????除了上面常見的兩種類型,還有一種 PUT 類型,這種類型就是向指定資源位置上傳最新內(nèi)容。但是 HTTP 的服務(wù)區(qū)往往是不允許上傳文件的,所以 PUT 和 POST 就都變成了要傳給服務(wù)器東西的方法。
????在我們的實(shí)際使用過程中,PUT 和 POST 還是有區(qū)別的。POST 往往是用來創(chuàng)建一個(gè)資源,而 PUT 往往是用來更新一個(gè)資源。
????例如,云主機(jī)已經(jīng)創(chuàng)建好了,想對(duì)云主機(jī)打一個(gè)標(biāo)簽,說明這個(gè)云主機(jī)是生產(chǎn)環(huán)境的,另外一個(gè)云主機(jī)是測(cè)試環(huán)境的。我們修改標(biāo)簽的請(qǐng)求往往就是用 PUT 方法。
????還有 DELETE 方法。這個(gè)是用來刪除資源的。
首部字段????請(qǐng)求行下面就是首部字段。首部是 key-value 格式,通過冒號(hào)分割。這里面,往往保存了一些非常重要的字段。
Accpet-Charset:客戶端可以接受的字符集。防止傳過來的字符串客戶端不支持,從而出現(xiàn)亂碼;
Content-Type:正文格式。我們進(jìn)行 POST 請(qǐng)求時(shí),如果正文是 JSON,我們就應(yīng)該將這個(gè)值設(shè)置為 application/json;
緩存字段 Cache-Control、If-Modified-Since。
????這里重點(diǎn)認(rèn)識(shí)下緩存字段。為什么要使用緩存呢?這是因?yàn)橐粋€(gè)非常大的頁面有很多東西。
????例如,我們?yōu)g覽一個(gè)商品的詳情,里面有商品的價(jià)格、庫存、展示圖片、使用手冊(cè)等待。
????商品的展示圖片會(huì)保持較長(zhǎng)時(shí)間不變,而庫存胡一根筋用戶購買情況經(jīng)常改變。如果圖片非常大,而庫存數(shù)非常小,如果我們每次要更新數(shù)據(jù)的時(shí)候都要刷新整個(gè)頁面,對(duì)于服務(wù)器的壓力也會(huì)很大。
????對(duì)于這種高并發(fā)場(chǎng)景下的系統(tǒng),在真正的業(yè)務(wù)邏輯之前,都需要有個(gè)接入層,將這些靜態(tài)資源的請(qǐng)求攔在最外面。架構(gòu)就像下圖:
????其中 DNS、CDN 會(huì)在后面的章節(jié)詳細(xì)說明。這里咱們就先來了解下 Nginx 這一層。它是如果處理 HTTP 協(xié)議呢?對(duì)于靜態(tài)資源,有 Vanish 緩存層,當(dāng)緩存過期的時(shí)候,才會(huì)訪問真正的 Tomcat 應(yīng)用集群。
????在 HTTP 頭里面,Cache-Control 是用來控制緩存的。當(dāng)客戶端發(fā)送的請(qǐng)求中包含 max-age 指令時(shí),如果判定緩存層中,資源的緩存時(shí)間數(shù)值比指定時(shí)間的數(shù)值校,那么客戶端可以接受緩存的資源;當(dāng)指定 max-age 值為 0,那么緩存層通常需要將請(qǐng)求轉(zhuǎn)發(fā)給應(yīng)用集群。
????另外,If-Modified-Since 也是關(guān)于緩存的字段,這個(gè)字段是說,如果服務(wù)器的資源在某個(gè)時(shí)間之后更新了,那么客戶端就應(yīng)該下載最新的資源;如果沒有更新,服務(wù)端會(huì)返回“304 Not Modified” 的響應(yīng),那客戶端就不用下載了,也會(huì)節(jié)省帶寬。
????到此,我們拼湊起了 HTTP 請(qǐng)求的報(bào)文格式,接下來,瀏覽器會(huì)把它交給傳輸層。
HTTP 請(qǐng)求的發(fā)送????HTTP 協(xié)議是基于 TCP 協(xié)議的,所以它是以面向連接的方式發(fā)送請(qǐng)求,通過 stream 二進(jìn)制流的方式傳給對(duì)方。當(dāng)然,到了 TCP 層,它會(huì)把二進(jìn)制流變成一個(gè)個(gè)的報(bào)文段發(fā)送給服務(wù)器。
????在發(fā)送給每個(gè)報(bào)文段的時(shí)候,都需要對(duì)方有一個(gè)回應(yīng) ACK,來保證報(bào)文可靠地到達(dá)了地方。如果沒有回應(yīng),那么 TCP 這一層會(huì)重新傳輸,直到可以到達(dá)。同一個(gè)包有可能被傳了好多次,但是 HTTP 這一層不需要知道這一點(diǎn),因?yàn)槭?TCP 這一層在埋頭苦干。
而后續(xù)傳輸過程如下:
TCP 層封裝目標(biāo)地址和源地址。TCP 層發(fā)送每一個(gè)報(bào)文的時(shí)候,都需要加上自己的地址和它想要去的地址,將這兩個(gè)信息放到 IP 頭里面,交給 IP 層進(jìn)行傳輸。
IP 層獲取 MAC 頭。IP 層需要查看目標(biāo)地址和自己是否在同一個(gè)局域網(wǎng)。如果是,就發(fā)送 ARP 協(xié)議來請(qǐng)求這個(gè)目標(biāo)地址對(duì)應(yīng)的 MAC 地址,然后將源 MAC 和目標(biāo) MAC 放入 MAC 頭,發(fā)送出去;如果不在同一個(gè)局域網(wǎng),就需要發(fā)送到網(wǎng)關(guān),這里也要通過 ARP 協(xié)議來獲取網(wǎng)關(guān)的 MAC 地址,然后將源 MAC 和網(wǎng)關(guān) MAC 放入 MAC 頭,發(fā)送出去。
網(wǎng)關(guān)轉(zhuǎn)發(fā)。網(wǎng)關(guān)收到包發(fā)現(xiàn) MAC 符合,取出目標(biāo) IP 地址,根據(jù)路由協(xié)議找到下一跳的路由器,獲取下一跳路由器的 MAC 地址,將包發(fā)給下一跳路由器。
數(shù)據(jù)包到達(dá)目標(biāo)地址的局域網(wǎng)。通過 ARP 協(xié)議獲取目標(biāo)地址的 MAC 地址,將包發(fā)出去。
目標(biāo)地址檢查信息,返回 ACK。目標(biāo)機(jī)器發(fā)現(xiàn)數(shù)據(jù)包中的 MAC 地址及 IP 地址都和本機(jī)匹配,就根據(jù) IP 頭中的協(xié)議類型,知道是 TCP 協(xié)議,解析 TCP 的頭,獲取序列號(hào)。判斷序列號(hào)是否是本機(jī)需要的,如果是,就放入緩存中然后返回一個(gè) ACK,如果不是就丟棄。
根據(jù)端口號(hào)將數(shù)據(jù)包發(fā)送到指定應(yīng)用。TCP 頭里面還有端口號(hào),HTTP 的服務(wù)器正在監(jiān)聽這個(gè)端口號(hào)。于是,目標(biāo)機(jī)器自然指定是 HTTP 服務(wù)器這個(gè)進(jìn)程想要這個(gè)包,就把數(shù)據(jù)包發(fā)給 HTTP 服務(wù)器。
HTTP 服務(wù)器處理請(qǐng)求。HTTP 服務(wù)器根據(jù)請(qǐng)求信息進(jìn)行處理,并返回?cái)?shù)據(jù)給客戶端。
HTTP 返回的構(gòu)建????HTTP 的返回報(bào)文也是有一定格式的,如下圖:
狀態(tài)行包含狀態(tài)碼和短語。狀態(tài)碼反應(yīng) HTTP 請(qǐng)求的結(jié)果。200 是大吉大利;404 則是我們最不想見到的,也就是服務(wù)端無法響應(yīng)這個(gè)請(qǐng)求。短語中會(huì)說明出錯(cuò)原因。
首部 key-value。這里常用的有以下字段:
Retry-After:客戶端應(yīng)該在多長(zhǎng)時(shí)間后再次嘗試連接;
Content-Type:返回?cái)?shù)據(jù)格式
????構(gòu)造好了返回的 HTTP 報(bào)文,接下來就是把這個(gè)報(bào)文發(fā)送出去。當(dāng)然,還是交給 Socket 去發(fā)送,交給 TCP,讓 TCP 返回的 HTML 分成一個(gè)個(gè)小的數(shù)據(jù)段,并且保證每一段都安全到達(dá)。這些小的數(shù)據(jù)段會(huì)加上 TCP 頭,然后交給 IP 層,沿著來時(shí)的路反向走一遍。雖然不一定是完全相同的路徑,但是邏輯過程是一樣的,一直到達(dá)客戶端。
????客戶端取出數(shù)據(jù)后 ,會(huì)根據(jù)端口號(hào)交給指定的程序,這時(shí)候就是我們的瀏覽器出馬的時(shí)候。
????瀏覽器拿到了 HTTP 報(bào)文,發(fā)現(xiàn)返回 200,一切正常,就從正文中將 HTML 拿出來,展示出一個(gè)炫酷吊炸天的網(wǎng)頁。
????以上就是正常的 HTTP 請(qǐng)求與返回的完整過程。
HTTP 2.0????上面提到了,現(xiàn)在用到 HTTP 大多是 1.1 版本,而 HTTP 2.0 在 1.1 的基礎(chǔ)上進(jìn)行了一些優(yōu)化,以期解決一些問題。
????HTTP 1.1 在應(yīng)用層以純文本的形式進(jìn)行通信。每次通信都要帶完整的 HTTP 頭,而且不考慮 pipeline 模式的話,每次的過程都要像上面描述的那樣一去一回。顯然,在效率上會(huì)存在問題。
????為了解決這些問題,HTTP 2.0 會(huì)對(duì) HTTP 頭進(jìn)行一定的壓縮,將原來每次都要攜帶的大量 key-value 對(duì)在兩端建立一個(gè)索引表,對(duì)相同的頭只發(fā)送索引表中的索引。
????另外,HTTP 2.0 協(xié)議將一個(gè) TCP 連接切分成多個(gè)流,每個(gè)流都有自己的 ID,而且流可以是客戶端發(fā)給服務(wù)端,也可以是服務(wù)端發(fā)給客戶端,它其實(shí)只是個(gè)虛擬的通道,除此之外,它還有優(yōu)先級(jí)。
????HTTP 2.0 將所有的傳輸信息分割成更小的消息和幀,并對(duì)它們采用二進(jìn)制格式編碼。常見的幀有 Header 幀,用于傳輸 Header 內(nèi)容,并且會(huì)開啟一個(gè)新的流。還有 Data 幀,用來傳輸正文實(shí)體,并且多個(gè) Data 幀屬于同個(gè)流。
????通過這兩種機(jī)制,HTTP 2.0 的客戶端可以將多個(gè)請(qǐng)求分到不同的流中, 然后將請(qǐng)求內(nèi)容拆分成幀,進(jìn)行二進(jìn)制傳輸。這些幀可以打散亂序發(fā)送,然后根據(jù)幀首部的流標(biāo)識(shí)符重新組裝,并且可以根據(jù)優(yōu)先級(jí),決定先處理哪個(gè)流的數(shù)據(jù)。
????針對(duì) HTTP 2.0,我們來看一個(gè)例子。
????假設(shè)我們有一個(gè)頁面要發(fā)送三個(gè)獨(dú)立的請(qǐng)求,一個(gè)獲取 CSS、一個(gè)獲取 JS、一個(gè)獲取圖片 jsg。如果使用 HTTP 1.1,這三個(gè)請(qǐng)求就是串行的,但是如果使用 HTTP 2.0,就可以在一個(gè)連接里,客戶端和服務(wù)端同時(shí)反思多個(gè)請(qǐng)求和回應(yīng),而且不用按照順序一對(duì)一對(duì)應(yīng)。
????如上圖。HTTP 2.0 其實(shí)是將三個(gè)請(qǐng)求變成三個(gè)流,將數(shù)據(jù)分成幀,亂序發(fā)送到一個(gè) TCP 連接中。
????HTTP 2.0 成功解決了 HTTP 1.1 的隊(duì)首阻塞問題。同時(shí),也不需要通過 HTTP 1.x 的 pipeline 機(jī)制用多條 TCP 連接來實(shí)現(xiàn)并行請(qǐng)求與響應(yīng),減少了 TCP 連接數(shù)對(duì)服務(wù)器性能的影響,加快頁面組件的傳輸速度。
????HTTP 2.0 雖然大大增加了并發(fā)性,但由于 TCP 協(xié)議的按序處理的特性,還是會(huì)出現(xiàn)阻塞的問題。
????還記得咱們之前說過的 QUIC 協(xié)議嗎?這時(shí)候就是它登場(chǎng)的時(shí)候了。
????它用以下四個(gè)機(jī)制,解決了 TCP 存在的一些問題。
QUIC 協(xié)議機(jī)制一:自定義連接機(jī)制
????我們知道,一條 TCP 連接是由四元組標(biāo)識(shí)的。一旦一個(gè)元素發(fā)生變化,就需要端口重連。這在移動(dòng)互聯(lián)網(wǎng)的情況下,當(dāng)我們切換網(wǎng)絡(luò)或者信號(hào)不穩(wěn)定時(shí),都會(huì)導(dǎo)致重連,從而增加時(shí)延。
????TCP 沒辦法解決上述問題,但是 QUCI 基于 UDP 協(xié)議,就可以在自己的邏輯里面維護(hù)連接的機(jī)制,不再以四元組標(biāo)識(shí),而是以一個(gè) 64 位的隨機(jī)數(shù)作為標(biāo)識(shí) ID,而且 UDP 是無連接的,只要 ID 不變,就不需要重新建立連接。
機(jī)制二:自定義重傳機(jī)制
????TCP 為了保證可靠性,通過使用序號(hào)和應(yīng)答機(jī)制,來解決順序問題和丟包問題。
????任何一個(gè)序號(hào)的包發(fā)出去,都要在一定時(shí)間內(nèi)得到應(yīng)答,否則就會(huì)超時(shí)重發(fā)。這個(gè)超時(shí)時(shí)間就是通過采樣往返時(shí)間 RTT 不斷調(diào)整的。其實(shí),這個(gè)超時(shí)時(shí)間的采樣是不太準(zhǔn)確的。
????如上圖。發(fā)送一個(gè)包,序號(hào)為 100,超時(shí)后,再發(fā)送一個(gè) 100。然后收到了一個(gè) ACK101。這個(gè)時(shí)候客戶端知道服務(wù)器已經(jīng)收到了 100,但是往返時(shí)間怎么計(jì)算呢?是 ACK 到達(dá)時(shí)間減去后一個(gè) 100 發(fā)送的時(shí)間,還是減去前一個(gè) 100 發(fā)送的時(shí)間呢?前者把時(shí)間算短了,后者把時(shí)間算長(zhǎng)了。
????QUIC 也有一個(gè)序列號(hào),是完全遞增的。任何一個(gè)包發(fā)送一次后,下一次序列號(hào)就要加一。像我們上面的例子,在 QUIC 協(xié)議中,100 的包沒有返回,再次發(fā)送時(shí),序號(hào)就是 101 了,如果返回是 ACK100,就是對(duì)第一個(gè)包的響應(yīng),如果返回 ACK101,就是對(duì)第二個(gè)包的響應(yīng),RTT 時(shí)間計(jì)算相對(duì)準(zhǔn)確,過程如下圖:
????上面的過程中,有的童鞋可能會(huì)問了,兩個(gè)序號(hào)不一樣的包,服務(wù)器怎么知道是同樣的內(nèi)容呢?沒錯(cuò),這確實(shí)是個(gè)問題。為了解決這個(gè)問題,QUIC 協(xié)議定義了一個(gè) Offset 的概念。
????QUIC 既然是面向連接的,也就像 TCP 一樣,是一個(gè)數(shù)據(jù)流。,發(fā)送的數(shù)據(jù)在這個(gè)流里面都有個(gè)偏移量 Offset,可以通過 Offset 查看數(shù)據(jù)發(fā)送到了那里,這樣只要這個(gè) Offset 的包沒有來,就要重發(fā)。如果來了,就按照 Offset 拼接成一個(gè)流。
機(jī)制三:無阻塞的多路復(fù)用
????有了自定義的連接和重傳機(jī)制,我們就可以解決上面 HTTP 2.0 的多路復(fù)用問題。
????同 HTTP 2.0 一樣,同一條 QUIC 連接上可以創(chuàng)建多個(gè) stream,來發(fā)送多個(gè) HTTP 請(qǐng)求。更棒的是,QUIC 是基于 UDP 的,一個(gè)連接上的多個(gè) stream 之間沒有依賴。這樣,假如 stream2 丟了一個(gè) UDP 包,后面跟著 stream3 的一個(gè) UDP 包,雖然 stream2 的那個(gè)包需要重傳,但是 stream3 的包無需等待,就可以發(fā)給用戶。
機(jī)制四:自定義流量控制
????TCP 的流量控制是通過滑動(dòng)窗口協(xié)議。QUIC 的流量控制也是通過 window_update,來告訴對(duì)端它可以接受的字節(jié)數(shù)。但是 QUIC 的窗口是適應(yīng)自己的多路復(fù)用機(jī)制的,不但在一個(gè)連接上控制窗口,還在一個(gè)連接中的每個(gè) stream 控制窗口。
????還記得嗎?在 TCP 協(xié)議中,接收端的窗口的起始點(diǎn)是下一個(gè)要接收并且 ACK 的包,即便后來的包都到了,放在緩存里面,窗口也不能右移,因?yàn)?TCP 的 ACK 機(jī)制是基于序列號(hào)的累計(jì)應(yīng)答,一旦 ACK 一個(gè)序列號(hào),就說明前面的都到了,所以只要前面的沒到,后面的即使到了也不能 ACK,就會(huì)導(dǎo)致后面的到了,也有可能超時(shí)重傳,浪費(fèi)帶寬。
????QUIC 的 ACK 是基于 offset 的,每個(gè) offset 的包來了,進(jìn)了緩存,就可以應(yīng)答,應(yīng)答后就不會(huì)重發(fā),中間的空檔會(huì)等待到來或者重發(fā)即可,而窗口的起始位置為當(dāng)前收到的最大 offset,從這個(gè) offset 到當(dāng)前的 stream 所能容納的最大緩存,是真正的窗口大小,顯然,這樣更加準(zhǔn)確。
????另外,還有整個(gè)連接的窗口,需要對(duì)于所有的 stream 的窗口做一個(gè)統(tǒng)計(jì)。
小結(jié)HTTP 協(xié)議雖然很常用,也很復(fù)雜,我們只需要重點(diǎn)記住 GET、POST、PUT、DELETE 這幾個(gè)方法,以及重要的首部字段;
HTTP 2.0 通過頭壓縮、分幀、二進(jìn)制編碼、多路復(fù)用等技術(shù)提升性能;
QUIC 協(xié)議通過基于 UDP 自定義的類似 TCP 的連接、重試、多路復(fù)用、流量控制技術(shù),進(jìn)一步提升性能。
參考:
The TCP/IP Guide;
百度百科 - HTTP 詞條;
劉超 - 趣談網(wǎng)絡(luò)協(xié)議系列課;
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/29785.html
摘要:協(xié)議,幾乎是每個(gè)人上網(wǎng)用的第一個(gè)協(xié)議,同時(shí)也是很容易被人忽略的協(xié)議。稱為協(xié)議,是一個(gè)域名,表示互聯(lián)網(wǎng)的一個(gè)位置。請(qǐng)求的發(fā)送協(xié)議是基于協(xié)議的,所以它是以面向連接的方式發(fā)送請(qǐng)求,通過二進(jìn)制流的方式傳給對(duì)方。狀態(tài)碼反應(yīng)請(qǐng)求的結(jié)果。 系列文章傳送門: 網(wǎng)絡(luò)協(xié)議 1 - 概述 網(wǎng)絡(luò)協(xié)議 2 - IP 是怎么來,又是怎么沒的? 網(wǎng)絡(luò)協(xié)議 3 - 從物理層到 MAC 層 網(wǎng)絡(luò)協(xié)議 4 - 交換機(jī)與...
閱讀 3774·2021-09-22 15:17
閱讀 1962·2021-09-22 14:59
閱讀 2361·2020-12-03 17:00
閱讀 3224·2019-08-30 15:55
閱讀 499·2019-08-30 11:23
閱讀 3498·2019-08-29 13:56
閱讀 530·2019-08-29 12:54
閱讀 2267·2019-08-29 12:49