<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Jack Jiang

    我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
    posts - 494, comments - 13, trackbacks - 0, articles - 1

    本文原作者阮一峰,作者博客:ruanyifeng.com。

    1、引言

    HTTP 協議是最重要的互聯網基礎協議之一,它從最初的僅為瀏覽網頁的目的進化到現在,已經是短連接通信的事實工業標準,最新版本 HTTP/2 更是讓它再次成為技術熱點。

    作為即時通訊開發者來說,深刻理解HTTP協議有助于在現今復雜移動網絡環境下的優化和最佳實踐的開展,本文將通俗易懂的地介紹 HTTP 協議的歷史演變和設計思路。


    學習交流:

    - 即時通訊開發交流3群:185926912[推薦]

    - 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM

    (本文同步發布于:http://www.52im.net/thread-1709-1-1.html

    2、相關文章

    網絡編程懶人入門(七):深入淺出,全面理解HTTP協議

    現代移動端網絡短連接的優化手段總結:請求速度、弱網適應、安全保障

    IM開發基礎知識補課(四):正確理解HTTP短連接中的Cookie、Session和Token

    IM開發基礎知識補課:正確理解前置HTTP SSO單點登陸接口的原理

    從HTTP到MQTT:一個基于位置服務的APP數據通信實踐概述

    技術掃盲:新一代基于UDP的低延時網絡傳輸層協議——QUIC詳解

    讓互聯網更快:新一代QUIC協議在騰訊的技術實踐分享

    3、HTTP/0.9

    HTTP 是基于 TCP/IP 協議的應用層協議(詳見《網絡編程懶人入門(一):快速理解網絡通信協議(上篇)》、《網絡編程懶人入門(二):快速理解網絡通信協議(下篇)》)。它不涉及數據包(packet)傳輸,主要規定了客戶端和服務器之間的通信格式,默認使用80端口。

    最早版本是1991年發布的0.9版。該版本極其簡單,只有一個命令GET:

    GET /index.html

    上面命令表示,TCP 連接(connection)建立后,客戶端向服務器請求(request)網頁index.html。

    協議規定,服務器只能回應HTML格式的字符串,不能回應別的格式:

    Hello World

    服務器發送完畢,就關閉TCP連接。

    4、HTTP/1.0

    4.1 簡介

    1996年5月,HTTP/1.0 版本發布,內容大大增加(詳見 RFC1945)。

    首先,任何格式的內容都可以發送。這使得互聯網不僅可以傳輸文字,還能傳輸圖像、視頻、二進制文件。這為互聯網的大發展奠定了基礎。

    其次,除了GET命令,還引入了POST命令和HEAD命令,豐富了瀏覽器與服務器的互動手段。

    再次,HTTP請求和回應的格式也變了。除了數據部分,每次通信都必須包括頭信息(HTTP header),用來描述一些元數據。

    其他的新增功能還包括狀態碼(status code)、多字符集支持、多部分發送(multi-part type)、權限(authorization)、緩存(cache)、內容編碼(content encoding)等。

    4.2 請求格式

    下面是一個1.0版的HTTP請求的例子:

    GET / HTTP/1.0

    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)

    Accept: */*

    可以看到,這個格式與0.9版有很大變化。

    第一行是請求命令,必須在尾部添加協議版本(HTTP/1.0)。后面就是多行頭信息,描述客戶端的情況。

    4.3 響應格式(Response)

    服務器的回應如下:

    HTTP/1.0 200 OK 

    Content-Type: text/plain

    Content-Length: 137582

    Expires: Thu, 05 Dec 1997 16:00:00 GMT

    Last-Modified: Wed, 5 August 1996 15:55:28 GMT

    Server: Apache 0.84

    Hello World

    回應的格式是"頭信息 + 一個空行(\r\n) + 數據"。其中,第一行是"協議版本 + 狀態碼(status code) + 狀態描述"。(詳見《網絡編程懶人入門(七):深入淺出,全面理解HTTP協議》)

    4.4 Content-Type 字段

    關于字符的編碼,1.0版規定,頭信息必須是 ASCII 碼,后面的數據可以是任何格式。因此,服務器回應的時候,必須告訴客戶端,數據是什么格式,這就是Content-Type字段的作用。

    下面是一些常見的Content-Type字段的值:

    text/plain

    text/html

    text/css

    image/jpeg

    image/png

    image/svg+xml

    audio/mp4

    video/mp4

    application/javascript

    application/pdf

    application/zip

    application/atom+xml

    這些數據類型總稱為MIME type,每個值包括一級類型和二級類型,之間用斜杠分隔。

    除了預定義的類型,廠商也可以自定義類型,就像下面這樣:

    application/vnd.debian.binary-package

    上面的類型表明,發送的是Debian系統的二進制數據包。

    MIME type還可以在尾部使用分號,添加參數:

    Content-Type: text/html; charset=utf-8

    上面的類型表明,發送的是網頁,而且編碼是UTF-8。

    客戶端請求的時候,可以使用Accept字段聲明自己可以接受哪些數據格式:

    Accept: */*

    上面代碼中,客戶端聲明自己可以接受任何格式的數據。

    MIME type不僅用在HTTP協議,還可以用在其他地方,比如HTML網頁:


    4.5 Content-Encoding 字段

    由于發送的數據可以是任何格式,因此可以把數據壓縮后再發送。

    Content-Encoding字段說明數據的壓縮方法:

    Content-Encoding: gzip

    Content-Encoding: compress

    Content-Encoding: deflate

    客戶端在請求時,用Accept-Encoding字段說明自己可以接受哪些壓縮方法:

    Accept-Encoding: gzip, deflate

    4.6 缺點

    HTTP/1.0 版的主要缺點是,每個TCP連接只能發送一個請求。發送數據完畢,連接就關閉,如果還要請求其他資源,就必須再新建一個連接。

    TCP連接的新建成本很高,因為需要客戶端和服務器三次握手,并且開始時發送速率較慢(slow start)。所以,HTTP 1.0版本的性能比較差。隨著網頁加載的外部資源越來越多,這個問題就愈發突出了。

    為了解決這個問題,有些瀏覽器在請求時,用了一個非標準的Connection字段:

    Connection: keep-alive

    這個字段要求服務器不要關閉TCP連接,以便其他請求復用。

    服務器同樣回應這個字段:

    Connection: keep-alive

    一個可以復用的TCP連接就建立了,直到客戶端或服務器主動關閉連接。但是,這不是標準字段,不同實現的行為可能不一致,因此不是根本的解決辦法。

    5、HTTP/1.1

    1997年1月,HTTP/1.1 版本發布,只比 1.0 版本晚了半年。HTTP/1.1進一步完善了 HTTP 協議,一直用到了20年后的今天,直到現在還是最流行的版本。

    5.1 持久連接

    1.1 版的最大變化,就是引入了持久連接(persistent connection),即TCP連接默認不關閉,可以被多個請求復用,不用聲明Connection: keep-alive。

    客戶端和服務器發現對方一段時間沒有活動,就可以主動關閉連接。

    不過,規范的做法是,客戶端在最后一個請求時,發送Connection: close,明確要求服務器關閉TCP連接:

    Connection: close

    目前,對于同一個域名,大多數瀏覽器允許同時建立6個持久連接。

    5.2 管道機制

    1.1 版還引入了管道機制(pipelining),即在同一個TCP連接里面,客戶端可以同時發送多個請求。這樣就進一步改進了HTTP協議的效率。

    舉例來說,客戶端需要請求兩個資源。以前的做法是,在同一個TCP連接里面,先發送A請求,然后等待服務器做出回應,收到后再發出B請求。管道機制則是允許瀏覽器同時發出A請求和B請求,但是服務器還是按照順序,先回應A請求,完成后再回應B請求。

    5.3 Content-Length 字段

    一個TCP連接現在可以傳送多個回應,勢必就要有一種機制,區分數據包是屬于哪一個回應的。

    這就是Content-length字段的作用,聲明本次回應的數據長度:

    Content-Length: 3495

    上面代碼告訴瀏覽器,本次回應的長度是3495個字節,后面的字節就屬于下一個回應了。

    在1.0版中,Content-Length字段不是必需的,因為瀏覽器發現服務器關閉了TCP連接,就表明收到的數據包已經全了。

    5.4 分塊傳輸編碼

    使用Content-Length字段的前提條件是,服務器發送回應之前,必須知道回應的數據長度。

    對于一些很耗時的動態操作來說,這意味著,服務器要等到所有操作完成,才能發送數據,顯然這樣的效率不高。更好的處理方法是,產生一塊數據,就發送一塊,采用"流模式"(stream)取代"緩存模式"(buffer)。

    因此,1.1版規定可以不使用Content-Length字段,而使用"分塊傳輸編碼"(chunked transfer encoding)。

    只要請求或回應的頭信息有Transfer-Encoding字段,就表明回應將由數量未定的數據塊組成:

    Transfer-Encoding: chunked

    每個非空的數據塊之前,會有一個16進制的數值,表示這個塊的長度。最后是一個大小為0的塊,就表示本次回應的數據發送完了。

    下面是一個例子:

    HTTP/1.1 200 OK

    Content-Type: text/plain

    Transfer-Encoding: chunked

    25

    This is the data in the first chunk

    1C

    and this is the second one

    3

    con

    8

    sequence

    0

    5.5 其他功能

    1.1版還新增了許多動詞方法:PUT、PATCH、HEAD、 OPTIONS、DELETE。

    另外,客戶端請求的頭信息新增了Host字段,用來指定服務器的域名:

    Host: example.com

    有了Host字段,就可以將請求發往同一臺服務器上的不同網站,為虛擬主機的興起打下了基礎。

    5.6 缺點

    雖然1.1版允許復用TCP連接,但是同一個TCP連接里面,所有的數據通信是按次序進行的。服務器只有處理完一個回應,才會進行下一個回應。要是前面的回應特別慢,后面就會有許多請求排隊等著。這稱為"隊頭堵塞"(Head-of-line blocking)。

    為了避免這個問題,只有兩種方法:一是減少請求數,二是同時多開持久連接。這導致了很多的網頁優化技巧,比如合并腳本和樣式表、將圖片嵌入CSS代碼、域名分片(domain sharding)等等。如果HTTP協議設計得更好一些,這些額外的工作是可以避免的。

    有關HTTP/1.1的詳細技術介紹,詳見《網絡編程懶人入門(七):深入淺出,全面理解HTTP協議》。

    6、SPDY 協議

    2009年,谷歌公開了自行研發的 SPDY 協議,主要解決 HTTP/1.1 效率不高的問題。

    這個協議在Chrome瀏覽器上證明可行以后,就被當作 HTTP/2 的基礎,主要特性都在 HTTP/2 之中得到繼承。

    7、HTTP/2

    2015年,HTTP/2 發布。它不叫 HTTP/2.0,是因為標準委員會不打算再發布子版本了,下一個新版本將是 HTTP/3。

    7.1 二進制協議

    HTTP/1.1 版的頭信息肯定是文本(ASCII編碼),數據體可以是文本,也可以是二進制。HTTP/2 則是一個徹底的二進制協議,頭信息和數據體都是二進制,并且統稱為"幀"(frame):頭信息幀和數據幀。

    二進制協議的一個好處是,可以定義額外的幀。HTTP/2 定義了近十種幀,為將來的高級應用打好了基礎。如果使用文本實現這種功能,解析數據將會變得非常麻煩,二進制解析則方便得多。

    7.2 多工

    HTTP/2 復用TCP連接,在一個連接里,客戶端和瀏覽器都可以同時發送多個請求或回應,而且不用按照順序一一對應,這樣就避免了"隊頭堵塞"。

    舉例來說,在一個TCP連接里面,服務器同時收到了A請求和B請求,于是先回應A請求,結果發現處理過程非常耗時,于是就發送A請求已經處理好的部分, 接著回應B請求,完成后,再發送A請求剩下的部分。

    這樣雙向的、實時的通信,就叫做多工(Multiplexing)。

    7.3 數據流

    因為 HTTP/2 的數據包是不按順序發送的,同一個連接里面連續的數據包,可能屬于不同的回應。因此,必須要對數據包做標記,指出它屬于哪個回應。

    HTTP/2 將每個請求或回應的所有數據包,稱為一個數據流(stream)。每個數據流都有一個獨一無二的編號。數據包發送的時候,都必須標記數據流ID,用來區分它屬于哪個數據流。另外還規定,客戶端發出的數據流,ID一律為奇數,服務器發出的,ID為偶數。

    數據流發送到一半的時候,客戶端和服務器都可以發送信號(RST_STREAM幀),取消這個數據流。1.1版取消數據流的唯一方法,就是關閉TCP連接。這就是說,HTTP/2 可以取消某一次請求,同時保證TCP連接還打開著,可以被其他請求使用。

    客戶端還可以指定數據流的優先級。優先級越高,服務器就會越早回應。

    7.4 頭信息壓縮

    HTTP 協議不帶有狀態,每次請求都必須附上所有信息。所以,請求的很多字段都是重復的,比如Cookie和User Agent,一模一樣的內容,每次請求都必須附帶,這會浪費很多帶寬,也影響速度。

    HTTP/2 對這一點做了優化,引入了頭信息壓縮機制(header compression)。一方面,頭信息使用gzip或compress壓縮后再發送;另一方面,客戶端和服務器同時維護一張頭信息表,所有字段都會存入這個表,生成一個索引號,以后就不發送同樣字段了,只發送索引號,這樣就提高速度了。

    7.5 服務器推送

    HTTP/2 允許服務器未經請求,主動向客戶端發送資源,這叫做服務器推送(server push)。

    常見場景是客戶端請求一個網頁,這個網頁里面包含很多靜態資源。正常情況下,客戶端必須收到網頁后,解析HTML源碼,發現有靜態資源,再發出靜態資源請求。其實,服務器可以預期到客戶端請求網頁后,很可能會再請求靜態資源,所以就主動把這些靜態資源隨著網頁一起發給客戶端了。

    附錄:更多網絡通信基礎資料

    TCP/IP詳解 - 第11章·UDP:用戶數據報協議

    TCP/IP詳解 - 第17章·TCP:傳輸控制協議

    TCP/IP詳解 - 第18章·TCP連接的建立與終止

    TCP/IP詳解 - 第21章·TCP的超時與重傳

    技術往事:改變世界的TCP/IP協議(珍貴多圖、手機慎點)

    通俗易懂-深入理解TCP協議(上):理論基礎

    通俗易懂-深入理解TCP協議(下):RTT、滑動窗口、擁塞處理

    理論經典:TCP協議的3次握手與4次揮手過程詳解

    理論聯系實際:Wireshark抓包分析TCP 3次握手、4次揮手過程

    計算機網絡通訊協議關系圖(中文珍藏版)

    UDP中一個包的大小最大能多大?

    P2P技術詳解(一):NAT詳解——詳細原理、P2P簡介

    P2P技術詳解(二):P2P中的NAT穿越(打洞)方案詳解

    P2P技術詳解(三):P2P技術之STUN、TURN、ICE詳解

    通俗易懂:快速理解P2P技術中的NAT穿透原理

    高性能網絡編程(一):單臺服務器并發TCP連接數到底可以有多少

    高性能網絡編程(二):上一個10年,著名的C10K并發連接問題

    高性能網絡編程(三):下一個10年,是時候考慮C10M并發問題了

    高性能網絡編程(四):從C10K到C10M高性能網絡應用的理論探索

    不為人知的網絡編程(一):淺析TCP協議中的疑難雜癥(上篇)

    不為人知的網絡編程(二):淺析TCP協議中的疑難雜癥(下篇)

    不為人知的網絡編程(三):關閉TCP連接時為什么會TIME_WAIT、CLOSE_WAIT

    不為人知的網絡編程(四):深入研究分析TCP的異常關閉

    不為人知的網絡編程(五):UDP的連接性和負載均衡

    不為人知的網絡編程(六):深入地理解UDP協議并用好它

    不為人知的網絡編程(七):如何讓不可靠的UDP變的可靠?

    網絡編程懶人入門(一):快速理解網絡通信協議(上篇)

    網絡編程懶人入門(二):快速理解網絡通信協議(下篇)

    網絡編程懶人入門(三):快速理解TCP協議一篇就夠

    網絡編程懶人入門(四):快速理解TCP和UDP的差異

    網絡編程懶人入門(五):快速理解為什么說UDP有時比TCP更有優勢

    網絡編程懶人入門(六):史上最通俗的集線器、交換機、路由器功能原理入門

    網絡編程懶人入門(七):深入淺出,全面理解HTTP協議

    技術掃盲:新一代基于UDP的低延時網絡傳輸層協議——QUIC詳解

    讓互聯網更快:新一代QUIC協議在騰訊的技術實踐分享

    現代移動端網絡短連接的優化手段總結:請求速度、弱網適應、安全保障

    聊聊iOS中網絡編程長連接的那些事

    移動端IM開發者必讀(一):通俗易懂,理解移動網絡的“弱”和“慢”

    移動端IM開發者必讀(二):史上最全移動弱網絡優化方法總結

    IPv6技術詳解:基本概念、應用現狀、技術實踐(上篇)

    IPv6技術詳解:基本概念、應用現狀、技術實踐(下篇)

    從HTTP/0.9到HTTP/2:一文讀懂HTTP協議的歷史演變和設計思路

    >> 更多同類文章 ……

    (本文同步發布于:http://www.52im.net/thread-1709-1-1.html



    作者:Jack Jiang (點擊作者姓名進入Github)
    出處:http://www.52im.net/space-uid-1.html
    交流:歡迎加入即時通訊開發交流群 215891622
    討論:http://www.52im.net/
    Jack Jiang同時是【原創Java Swing外觀工程BeautyEye】【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
    本博文 歡迎轉載,轉載請注明出處(也可前往 我的52im.net 找到我)。


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
    主站蜘蛛池模板: ww在线观视频免费观看| 日韩a级毛片免费视频| 宅男666在线永久免费观看| 国产专区一va亚洲v天堂| 亚洲免费网站在线观看| 成人午夜影视全部免费看| 亚洲精品视频在线观看免费| 免费va人成视频网站全| 7777久久亚洲中文字幕蜜桃| 国产午夜亚洲精品不卡免下载| 免费在线看污视频| 成人永久免费高清| 亚洲成人激情在线| 污网站在线观看免费| 91精品免费久久久久久久久| 亚洲欧洲日本在线| 亚洲人成7777影视在线观看| 91视频免费网站| 国产资源免费观看| 亚洲第一二三四区| 成人片黄网站色大片免费观看cn| 成人a视频片在线观看免费| 亚洲精品乱码久久久久久| 亚洲国产精品精华液| 91精品国产免费| 亚洲视频在线一区二区| 我要看免费的毛片| 亚洲精品自产拍在线观看| 狼人大香伊蕉国产WWW亚洲| 亚洲免费在线观看视频| 国产亚洲精品无码专区| 亚洲国产成人综合精品| 18禁黄网站禁片免费观看不卡 | 1000部羞羞禁止免费观看视频| 亚洲AV无码乱码在线观看| 亚洲av无码久久忘忧草| 无码av免费一区二区三区试看| 亚洲国产精品丝袜在线观看| 亚洲国产精品ⅴa在线观看| 4399好看日本在线电影免费| 亚洲va久久久噜噜噜久久男同|