一、連接過程時序圖
二、wireshark 分析
上圖是一個完整的進行 websocket 連接時產生的數據包。
根據時序圖可知,前 3 行是 tcp/ip 握手過程,因爲可以通過標誌來看到,前 3 個標誌(Flags)分別爲 SYN、SYN ACK、ACK。這是建立 http 請求的需要,和 websocket 沒有關係。
第 4 條就是 client 主動發給 server 的握手協議了,如下圖所示:
細心的小夥伴可以發現,這套代碼是基於 C++ 版的 websocketpp 實現的,大家可以參考下。
大家可以發現,websocket 的握手協議實際上是基於 http 協議實現的,client 告訴 server,我要升級爲 websocket 了,不使用老土的 http 了。實現的方法就是 “Connection” 和 “Upgrade” 這兩個字段,
我要升級(Connection : upgrade),
升級爲 websocket (Upgrade : websocket),
websocket 的版本得是 v13 的!(Sec-WebSocket-Version 13)。
第 5 條是 server 回覆 client 的協議了。
狀態爲 101,意味着協議切換成功。
這裏 Sec-WebSocket-Accept 和 Sec-WebSocket-Key 是配套的,主要作用在於提供基礎的防護,減少惡意連接、意外連接。
Sec-WebSocket-Accept 的計算方法是:
計算公式爲:
將 Sec-WebSocket-Key 跟 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 拼接。
通過 SHA1 計算出摘要,並轉成 base64 字符串。
僞代碼如下:
toBase64( sha1( Sec-WebSocket-Key + 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 ) )
參考鏈接:
(SAW:Game Over!)