你真的弄懂 HTTP 了嗎?(四)

這是我參與8月更文挑戰的第10天,活動詳情查看:8月更文挑戰git

相關文章:

1、說說TCP爲何須要三次握手和四次揮手?

1.1 三次握手

三次握手(Three-way Handshake)其實就是指創建一個TCP鏈接時,須要客戶端和服務器總共發送3個包github

主要做用就是爲了確認雙方的接收能力和發送能力是否正常、指定本身的初始化序列號爲後面的可靠性傳送作準備web

過程以下:服務器

  • 第一次握手:客戶端給服務端發一個 SYN 報文,並指明客戶端的初始化序列號 ISN(c),此時客戶端處於 SYN_SENT 狀態
  • 第二次握手:服務器收到客戶端的 SYN 報文以後,會以本身的 SYN 報文做爲應答,爲了確認客戶端的 SYN,將客戶端的 ISN+1做爲ACK的值,此時服務器處於 SYN_RCVD 的狀態
  • 第三次握手:客戶端收到 SYN 報文以後,會發送一個 ACK 報文,值爲服務器的ISN+1。此時客戶端處於 ESTABLISHED 狀態。服務器收到 ACK 報文以後,也處於 ESTABLISHED 狀態,此時,雙方已創建起了鏈接

上述每一次握手的做用以下:websocket

  • 第一次握手:客戶端發送網絡包,服務端收到了
    這樣服務端就能得出結論:客戶端的發送能力、服務端的接收能力是正常的。
  • 第二次握手:服務端發包,客戶端收到了
    這樣客戶端就能得出結論:服務端的接收、發送能力,客戶端的接收、發送能力是正常的。不過此時服務器並不能確認客戶端的接收能力是否正常
  • 第三次握手:客戶端發包,服務端收到了。
    這樣服務端就能得出結論:客戶端的接收、發送能力正常,服務器本身的發送、接收能力也正常

經過三次握手,就能肯定雙方的接收和發送能力是正常的。以後就能夠正常通訊了markdown

爲何不是兩次握手?

若是是兩次握手,發送端能夠肯定本身發送的信息能對方能收到,也能肯定對方發的包本身能收到,但接收端只能肯定對方發的包本身能收到 沒法肯定本身發的包對方能收到網絡

而且兩次握手的話, 客戶端有可能由於網絡阻塞等緣由會發送多個請求報文,延時到達的請求又會與服務器創建鏈接,浪費掉許多服務器的資源socket

1.2 四次揮手

tcp終止一個鏈接,須要通過四次揮手tcp

過程以下:oop

  • 第一次揮手:客戶端發送一個 FIN 報文,報文中會指定一個序列號。此時客戶端處於 FIN_WAIT1 狀態,中止發送數據,等待服務端的確認
  • 第二次揮手:服務端收到 FIN 以後,會發送 ACK 報文,且把客戶端的序列號值 +1 做爲 ACK 報文的序列號值,代表已經收到客戶端的報文了,此時服務端處於 CLOSE_WAIT狀態
  • 第三次揮手:若是服務端也想斷開鏈接了,和客戶端的第一次揮手同樣,發給 FIN 報文,且指定一個序列號。此時服務端處於 LAST_ACK 的狀態
  • 第四次揮手:客戶端收到 FIN 以後,同樣發送一個 ACK 報文做爲應答,且把服務端的序列號值 +1 做爲本身 ACK 報文的序列號值,此時客戶端處於 TIME_WAIT狀態。須要過一陣子以確保服務端收到本身的 ACK 報文以後纔會進入 CLOSED 狀態,服務端收到 ACK 報文以後,就處於關閉鏈接了,處於 CLOSED 狀態

四次揮手緣由

服務端在收到客戶端斷開鏈接Fin報文後,並不會當即關閉鏈接,而是先發送一個ACK包先告訴客戶端收到關閉鏈接的請求,只有當服務器的全部報文發送完畢以後,才發送FIN報文斷開鏈接,所以須要四次揮手

1.3 總結

一個完整的三次握手四次揮手以下圖所示:

2、說說對WebSocket的理解?應用場景?

2.1 是什麼

WebSocket,是一種網絡傳輸協議,位於OSI模型的應用層。可在單個TCP鏈接上進行全雙工通訊,能更好的節省服務器資源和帶寬並達到實時通迅

客戶端和服務器只須要完成一次握手,二者之間就能夠建立持久性的鏈接,並進行雙向數據傳輸

從上圖可見,websocket服務器與客戶端經過握手鍊接,鏈接成功後,二者都能主動的向對方發送或接受數據

而在websocket出現以前,開發實時web應用的方式爲輪詢

不停地向服務器發送 HTTP 請求,問有沒有數據,有數據的話服務器就用響應報文迴應。若是輪詢的頻率比較高,那麼就能夠近似地實現「實時通訊」的效果

輪詢的缺點也很明顯,反覆發送無效查詢請求耗費了大量的帶寬和 CPU 資源

2.2 特色

全雙工

通訊容許數據在兩個方向上同時傳輸,它在能力上至關於兩個單工通訊方式的結合

例如指 A→B 的同時 B→A ,是瞬時同步的

二進制幀

採用了二進制幀結構,語法、語義與 HTTP 徹底不兼容,相比http/2WebSocket 更側重於「實時通訊」,而HTTP/2 更側重於提升傳輸效率,因此二者的幀結構也有很大的區別

不像 HTTP/2 那樣定義流,也就不存在多路複用、優先級等特性

自身就是全雙工,也不須要服務器推送

協議名

引入wswss分別表明明文和密文的websocket協議,且默認端口使用80或443,幾乎與http一致

ws://www.chrono.com
ws://www.chrono.com:8080/srv
wss://www.chrono.com:445/im?user_id=xxx
複製代碼

握手

WebSocket 也要有一個握手過程,而後才能正式收發數據

客戶端發送數據格式以下:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
複製代碼
  • Connection:必須設置Upgrade,表示客戶端但願鏈接升級
  • Upgrade:必須設置Websocket,表示但願升級到Websocket協議
  • Sec-WebSocket-Key:客戶端發送的一個 base64 編碼的密文,用於簡單的認證祕鑰。要求服務端必須返回一個對應加密的「Sec-WebSocket-Accept應答,不然客戶端會拋出錯誤,並關閉鏈接
  • Sec-WebSocket-Version :表示支持的Websocket版本

服務端返回的數據格式:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=Sec-WebSocket-Protocol: chat
複製代碼
  • HTTP/1.1 101 Switching Protocols:表示服務端接受 WebSocket 協議的客戶端鏈接
  • Sec-WebSocket-Accep:驗證客戶端請求報文,一樣也是爲了防止誤鏈接。具體作法是把請求頭裏「Sec-WebSocket-Key」的值,加上一個專用的 UUID,再計算摘要

優勢

  • 較少的控制開銷:數據包頭部協議較小,不一樣於http每次請求須要攜帶完整的頭部
  • 更強的實時性:相對於HTTP請求須要等待客戶端發起請求服務端才能響應,延遲明顯更少
  • 保持創鏈接狀態:建立通訊後,可省略狀態信息,不一樣於HTTP每次請求須要攜帶身份驗證
  • 更好的二進制支持:定義了二進制幀,更好處理二進制內容
  • 支持擴展:用戶能夠擴展websocket協議、實現部分自定義的子協議
  • 更好的壓縮效果:Websocket在適當的擴展支持下,能夠沿用以前內容的上下文,在傳遞相似的數據時,能夠顯著地提升壓縮率

2.3 應用場景

基於websocket的事實通訊的特色,其存在的應用場景大概有:

  • 彈幕
  • 媒體聊天
  • 協同編輯
  • 基於位置的應用
  • 體育實況更新
  • 股票基金報價實時更新
相關文章
相關標籤/搜索