一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

原來(lái)你是這樣的Websocket

 獵狐肥 2019-11-26

之前自己一個(gè)人負(fù)責(zé)完成了公司的消息推送服務(wù),和移動(dòng)端配合完成了掃碼登錄、訂單消息推送、活動(dòng)消息廣播等功能。為了加深自己對(duì)Websocket協(xié)議的理解,自己通過(guò)進(jìn)行抓包的方式學(xué)習(xí)了一番?,F(xiàn)在分享出來(lái),希望對(duì)大家能有所幫助。

Chrome控制臺(tái)

(1)F12進(jìn)入控制臺(tái),點(diǎn)擊Network,選中ws欄,注意選中Filter。

(2)刷新頁(yè)面會(huì)得到一個(gè)ws鏈接。

(3)點(diǎn)擊鏈接可以查看鏈接詳情

注意紅框標(biāo)出的信息,后面會(huì)詳細(xì)說(shuō)明。
(4)當(dāng)然也可以切換到Frames查看發(fā)出和接收的消息,但是非常的簡(jiǎn)陋,只能看到消息內(nèi)容,數(shù)據(jù)長(zhǎng)度和時(shí)間

Fiddler:抓包調(diào)試?yán)?/h2>

(1)打開(kāi)Fiddler,點(diǎn)開(kāi)菜單欄的Rules,選擇Customize Rules...

(2)這時(shí)會(huì)打開(kāi)CustomRules.js文件,在class Handlers中加入以下代碼

static function OnWebSocketMessage(oMsg: WebSocketMessage) {
        // Log Message to the LOG tab
        FiddlerApplication.Log.LogString(oMsg.ToString());
    }

(3)保存后就可以在Fiddler右邊欄的Log標(biāo)簽里,看到WebSocket的數(shù)據(jù)包
下列圖中紅框標(biāo)出的Client.1代表客戶端發(fā)出的第一條消息;對(duì)應(yīng)的Server.1代表服務(wù)端發(fā)出的第一條消息。MessageType:Text代表正常的通話消息;Close代表會(huì)話關(guān)閉。
客戶端發(fā)出的消息:

服務(wù)端發(fā)出的消息:

然后我們會(huì)發(fā)現(xiàn)每次會(huì)話關(guān)閉都是由客戶端發(fā)起的:

相對(duì)于Chrome控制臺(tái)來(lái)說(shuō)Fiddler抓包更加詳細(xì)一些,能知道會(huì)話消息是由客戶端還是服務(wù)端發(fā)出并且能知道消息類型。但是這仍然滿足不了深入理解學(xué)習(xí)Websocket協(xié)議的目的。如果是處理HTTP、HTTPS,還是用Fiddler。其他協(xié)議比如TCP,UDP 就用WireShark。TPC/IP協(xié)議是傳輸層協(xié)議,主要解決數(shù)據(jù)如何在網(wǎng)絡(luò)中傳輸,而HTTP、Websocket是應(yīng)用層協(xié)議,主要解決如何包裝數(shù)據(jù)。因?yàn)閼?yīng)用層是在傳輸層的基礎(chǔ)上包裝數(shù)據(jù),所以我們還是從底層開(kāi)始了解Websocket到底是個(gè)啥?是如何工作的?

WireShark

WireShark(前稱Ethereal)是一個(gè)網(wǎng)絡(luò)封包分析軟件。網(wǎng)絡(luò)封包分析軟件的功能是擷取網(wǎng)絡(luò)封包,并盡可能顯示出最為詳細(xì)的網(wǎng)絡(luò)封包資料。WireShark抓包是根據(jù)TCP/IP五層協(xié)議來(lái)的,也就是物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層、應(yīng)用層。我們主要關(guān)注傳輸層和應(yīng)用層。

TCP三次握手

我們都知道,TCP建立連接時(shí),會(huì)有三次握手過(guò)程。下圖是WireShark截獲到的三次握手的三個(gè)數(shù)據(jù)包(雖然叫數(shù)據(jù)包,但是三次握手包是沒(méi)有數(shù)據(jù)的)。

點(diǎn)擊上圖中的數(shù)據(jù)包就可以查看每個(gè)數(shù)據(jù)包的詳情,這里我們需要明確幾個(gè)概念才能看懂每個(gè)數(shù)據(jù)包代表啥意義:
SYN:同步比特,建立連接。
ACK:確認(rèn)比特,置1表示這是一個(gè)確認(rèn)的TCP包,0則不是。
PSH:推送比特,當(dāng)發(fā)送端PSH=1時(shí),接收端應(yīng)盡快交付給應(yīng)用進(jìn)程。

  • 第一次握手

可以看到我們打開(kāi)的Transmission Control Protocol即為傳輸層(Tcp)
SYN置為1,客戶端向服務(wù)端發(fā)送連接請(qǐng)求包。

  • 第二次握手

服務(wù)器收到客戶端發(fā)過(guò)來(lái)的TCP報(bào)文,由SYN=1知道客戶端要求建立聯(lián)機(jī),向客戶端發(fā)送一個(gè)SYN=1,ACK=1的TCP報(bào)文,將確認(rèn)序號(hào)設(shè)置為客戶端的序列號(hào)加1。

  • 第三次握手

客戶端接收到服務(wù)器發(fā)過(guò)來(lái)的包后檢查確認(rèn)序列號(hào)是否正確,即第一次發(fā)送的序號(hào)+1,以及標(biāo)志位ACK是否為1。若正確則再次發(fā)送確認(rèn)包,ACK標(biāo)志為1。鏈接建立成功,可以發(fā)送數(shù)據(jù)了。

一次特殊的HTTP請(qǐng)求

緊接著是一次Http請(qǐng)求(第四個(gè)包),說(shuō)明Http的確是使用Tcp建立連接的。

先來(lái)看傳輸層(Tcp): PSH(推送比特)置1,ACK置1,PSH置1說(shuō)明開(kāi)始發(fā)送數(shù)據(jù),同時(shí)發(fā)送數(shù)據(jù)ACK要置1,因?yàn)樾枰邮盏竭@個(gè)數(shù)據(jù)包的端給予確認(rèn)。PSH為1的情況,一般只出現(xiàn)在 DATA內(nèi)容不為0的包中,也就是說(shuō)PSH為1表示的是有真正的TCP數(shù)據(jù)包內(nèi)容被傳遞。

再來(lái)看應(yīng)用層(Http):這是一次特殊的Http請(qǐng)求,為什么是一次特殊的Http請(qǐng)求呢?Http請(qǐng)求頭中Connection:Upgrade Upgrade:websocket,Upgrade代表升級(jí)到較新的Http協(xié)議或者切換到不同的協(xié)議。很明顯WebSocket使用此機(jī)制以兼容的方式與HTTP服務(wù)器建立連接。WebSocket協(xié)議有兩個(gè)部分:握手建立升級(jí)后的連接,然后進(jìn)行實(shí)際的數(shù)據(jù)傳輸。首先,客戶端通過(guò)使用Upgrade: WebSocket和Connection: Upgrade頭部以及一些特定于協(xié)議的頭來(lái)請(qǐng)求WebSocket連接,以建立正在使用的版本并設(shè)置握手。服務(wù)器,如果它支持協(xié)議,回復(fù)與相同Upgrade: WebSocket和Connection: Upgrade標(biāo)題,并完成握手。握手完成后,數(shù)據(jù)傳輸開(kāi)始。這些信息在前面的Chrome控制臺(tái)中也可以看到。

請(qǐng)求:

響應(yīng):
響應(yīng)狀態(tài)碼 101 表示服務(wù)器已經(jīng)理解了客戶端的請(qǐng)求,在發(fā)送完這個(gè)響應(yīng)后,服務(wù)器將會(huì)切換到在Upgrade請(qǐng)求頭中定義的那些協(xié)議。

由此我們可以總結(jié)出:
Websocket協(xié)議本質(zhì)上是一個(gè)基于TCP的協(xié)議。建立連接需要握手,客戶端(瀏覽器)首先向服務(wù)器(web server)發(fā)起一條特殊的http請(qǐng)求,web server解析后生成應(yīng)答到瀏覽器,這樣子一個(gè)websocket連接就建立了,直到某一方關(guān)閉連接。

Websocket的世界

通信協(xié)議格式是WebSocket格式,服務(wù)器端采用Tcp Socket方式接收數(shù)據(jù),進(jìn)行解析,協(xié)議格式如下:

首先我們需要知道數(shù)據(jù)在物理層,數(shù)據(jù)鏈路層是以二進(jìn)制進(jìn)行傳遞的,而在應(yīng)用層是以16進(jìn)制字節(jié)流進(jìn)行傳輸?shù)摹?/p>

第一個(gè)字節(jié):

FIN:1位,用于描述消息是否結(jié)束,如果為1則該消息為消息尾部,如果為零則還有后續(xù)數(shù)據(jù)包;
RSV1,RSV2,RSV3:各1位,用于擴(kuò)展定義的,如果沒(méi)有擴(kuò)展約定的情況則必須為0
OPCODE:4位,用于表示消息接收類型,如果接收到未知的opcode,接收端必須關(guān)閉連接。

Webdocket數(shù)據(jù)幀中OPCODE定義:
0x0表示附加數(shù)據(jù)幀
0x1表示文本數(shù)據(jù)幀
0x2表示二進(jìn)制數(shù)據(jù)幀
0x3-7暫時(shí)無(wú)定義,為以后的非控制幀保留
0x8表示連接關(guān)閉
0x9表示ping
0xA表示pong
0xB-F暫時(shí)無(wú)定義,為以后的控制幀保留

第二個(gè)字節(jié):

MASK:1位,用于標(biāo)識(shí)PayloadData是否經(jīng)過(guò)掩碼處理,客戶端發(fā)出的數(shù)據(jù)幀需要進(jìn)行掩碼處理,所以此位是1。數(shù)據(jù)需要解碼。
PayloadData的長(zhǎng)度:7位,7+16位,7+64位
如果其值在0-125,則是payload的真實(shí)長(zhǎng)度。
如果值是126,則后面2個(gè)字節(jié)形成的16位無(wú)符號(hào)整型數(shù)的值是payload的真實(shí)長(zhǎng)度。
如果值是127,則后面8個(gè)字節(jié)形成的64位無(wú)符號(hào)整型數(shù)的值是payload的真實(shí)長(zhǎng)度。

上圖是客戶端發(fā)送給服務(wù)端的數(shù)據(jù)包,其中PayloadData的長(zhǎng)度為二進(jìn)制:01111110——>十進(jìn)制:126;如果值是126,則后面2個(gè)字節(jié)形成的16位無(wú)符號(hào)整型數(shù)的值是payload的真實(shí)長(zhǎng)度。也就是圈紅的十六進(jìn)制:00C1——>十進(jìn)制:193 byte。所以PayloadData的真實(shí)數(shù)據(jù)長(zhǎng)度是193 bytes;

根據(jù)我們的分析,客戶端到服務(wù)端數(shù)據(jù)包的websocket幀圖應(yīng)該為:

我們?cè)賮?lái)抓包分析一下服務(wù)器到客戶端的數(shù)據(jù)包:

可以發(fā)現(xiàn)服務(wù)器發(fā)送給客戶端的數(shù)據(jù)包中第二個(gè)字節(jié)中MASK位為0,這說(shuō)明服務(wù)器發(fā)送的數(shù)據(jù)幀未經(jīng)過(guò)掩碼處理,這個(gè)我們從客戶端和服務(wù)端的數(shù)據(jù)包截圖中也可以發(fā)現(xiàn),客戶端的數(shù)據(jù)被加密處理,而服務(wù)端的數(shù)據(jù)則沒(méi)有。(如果服務(wù)器收到客戶端發(fā)送的未經(jīng)掩碼處理的數(shù)據(jù)包,則會(huì)自動(dòng)斷開(kāi)連接;反之,如果客戶端收到了服務(wù)端發(fā)送的經(jīng)過(guò)掩碼處理的數(shù)據(jù)包,也會(huì)自動(dòng)斷開(kāi)連接)。

掩碼處理:

未掩碼處理:

根據(jù)我們的分析,服務(wù)端到客戶端數(shù)據(jù)包的websocket幀圖應(yīng)該為:

TCP KeepAlive

如上圖所示,TCP?;顖?bào)文總是成對(duì)出現(xiàn),包括TCP保活探測(cè)報(bào)文和TCP?;钐綔y(cè)確認(rèn)報(bào)文。
TCP?;钐綔y(cè)報(bào)文是將之前TCP報(bào)文的確認(rèn)序列號(hào)減1,并設(shè)置1個(gè)字節(jié),內(nèi)容為“00”的應(yīng)用層數(shù)據(jù),如下圖所示:

TCP?;钐綔y(cè)確認(rèn)報(bào)文就是對(duì)保活探測(cè)報(bào)文的確認(rèn),其報(bào)文格式如下:

因?yàn)閃ebsocket通過(guò)Tcp Socket方式工作,現(xiàn)在考慮一個(gè)問(wèn)題,在一次長(zhǎng)連接中,服務(wù)器怎么知道消息的順序呢?這就涉及到tcp的序列號(hào)(Sequence Number)和確認(rèn)號(hào)(Acknowledgment Number)。我的理解是序列號(hào)是發(fā)送的數(shù)據(jù)長(zhǎng)度;確認(rèn)號(hào)是接收的數(shù)據(jù)長(zhǎng)度。這樣講比較抽象,我們從TCP三次握手開(kāi)始(結(jié)合下圖)詳細(xì)分析一下。

包1
TCP會(huì)話的每一端的序列號(hào)都從0開(kāi)始,同樣的,確認(rèn)號(hào)也從0開(kāi)始,因?yàn)榇藭r(shí)通話還未開(kāi)始,沒(méi)有通話的另一端需要確認(rèn)
包2
服務(wù)端響應(yīng)客戶端的請(qǐng)求,響應(yīng)中附帶序列號(hào)0(由于這是服務(wù)端在該次TCP會(huì)話中發(fā)送的第一個(gè)包,所以序列號(hào)為0)和相對(duì)確認(rèn)號(hào)1(表明服務(wù)端收到了客戶端發(fā)送的包1中的SYN)。需要注意的是,盡管客戶端沒(méi)有發(fā)送任何有效數(shù)據(jù),確認(rèn)號(hào)還是被加1,這是因?yàn)榻邮盏陌邪琒YN或FIN標(biāo)志位。
包3
和包2中一樣,客戶端使用確認(rèn)號(hào)1響應(yīng)服務(wù)端的序列號(hào)0,同時(shí)響應(yīng)中也包含了客戶端自己的序列號(hào)(由于服務(wù)端發(fā)送的包中確認(rèn)收到了客戶端發(fā)送的SYN,故客戶端的序列號(hào)由0變?yōu)?)此時(shí),通信的兩端的序列號(hào)都為1。
包4:客戶端——>服務(wù)器
這是流中第一個(gè)攜帶有效數(shù)據(jù)的包(確切的說(shuō),是客戶端發(fā)送的HTTP請(qǐng)求),序列號(hào)依然為1,因?yàn)榈缴蟼€(gè)包為止,還沒(méi)有發(fā)送任何數(shù)據(jù),確認(rèn)號(hào)也保持1不變,因?yàn)榭蛻舳藳](méi)有從服務(wù)端接收到任何數(shù)據(jù)。需要注意的是,包中有效數(shù)據(jù)的長(zhǎng)度為505字節(jié)
包5:服務(wù)器——>客戶端
當(dāng)上層處理HTTP請(qǐng)求時(shí),服務(wù)端發(fā)送該包來(lái)確認(rèn)客戶端在包4中發(fā)來(lái)的數(shù)據(jù),需要注意的是,確認(rèn)號(hào)的值增加了505(505是包4中有效數(shù)據(jù)長(zhǎng)度),變?yōu)?06,簡(jiǎn)單來(lái)說(shuō),服務(wù)端以此來(lái)告知客戶端端,目前為止,我總共收到了506字節(jié)的數(shù)據(jù),服務(wù)端的序列號(hào)保持為1不變。
包6:服務(wù)器——>客戶端
這個(gè)包標(biāo)志著服務(wù)端返回HTTP響應(yīng)的開(kāi)始,序列號(hào)依然為1,因?yàn)榉?wù)端在該包之前返回的包中都不帶有有效數(shù)據(jù),該包帶有129字節(jié)的有效數(shù)據(jù)。
包7
由于上個(gè)數(shù)據(jù)包的發(fā)送,TCP客戶端的確認(rèn)序列號(hào)增長(zhǎng)至130,從服務(wù)端接收了129字節(jié)的數(shù)據(jù),客戶端的確認(rèn)號(hào)由1增長(zhǎng)至130
理解了序列號(hào)和確認(rèn)序列號(hào)是怎么工作的之后,我們也就知道“TCP?;钐綔y(cè)報(bào)文是將之前TCP報(bào)文的確認(rèn)序列號(hào)減1,并設(shè)置1個(gè)字節(jié)”為什么要這么搞了。減一再加一,是為了保證一次連接中keep alive不影響序列號(hào)和確認(rèn)序列號(hào)。Keep alive 中的1byte 00的數(shù)據(jù)并不是真正要傳遞的數(shù)據(jù),而是tcp keep alive約定俗稱的規(guī)則。

總結(jié):
WebSocket 是一個(gè)獨(dú)立的基于 TCP 的協(xié)議,它與 HTTP 之間的唯一關(guān)系就是它的握手請(qǐng)求可以作為一個(gè)升級(jí)請(qǐng)求(Upgrade request)經(jīng)由 HTTP 服務(wù)器解釋。再嚴(yán)謹(jǐn)一點(diǎn):WebSocket是一個(gè)網(wǎng)絡(luò)通訊協(xié)議, 只要理解上面的數(shù)據(jù)幀格式和握手流程, 都可以完成基于websokect的即時(shí)通訊

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    日本亚洲精品在线观看| 日本三区不卡高清更新二区| 日本高清视频在线观看不卡| 精品久久综合日本欧美| 亚洲女同一区二区另类| 国产精品亚洲精品亚洲| 国自产拍偷拍福利精品图片| 亚洲欧美日韩国产成人| 夫妻性生活真人动作视频| 欧美整片精品日韩综合| 欧美日韩免费观看视频| 九九热在线视频观看最新| 亚洲中文在线男人的天堂| 大胆裸体写真一区二区| 两性色午夜天堂免费视频| 视频在线免费观看你懂的| 午夜福利激情性生活免费视频| 欧美一级黄片欧美精品| 精品国产丝袜一区二区| 色婷婷丁香激情五月天| 日本一品道在线免费观看| 98精品永久免费视频| 国产综合一区二区三区av| 91亚洲精品亚洲国产| 99国产高清不卡视频| 欧美一区二区口爆吞精| 国产精品欧美激情在线| 色丁香之五月婷婷开心| 伊人色综合久久伊人婷婷| 中文久久乱码一区二区| 日本在线 一区 二区| 国产一区二区熟女精品免费| 亚洲中文字幕视频一区二区| 欧美人禽色视频免费看| 中文文精品字幕一区二区| 自拍偷拍一区二区三区| 好骚国产99在线中文| 日本久久精品在线观看| 免费特黄一级一区二区三区| 黄色国产一区二区三区| 日本高清视频在线播放|