转载自:https://www.cnblogs.com/songwenjie/p/8575579.html

Chrome控制台

(1)F12进入控制台,点击Network,选中ws栏,注意选中Filter。

(2)刷新页面会得到一个ws链接。

(3)点击链接可以查看链接详情

注意红框标出的信息,后面会详细说明。
(4)当然也可以切换到Frames查看发出和接收的消息,但是非常的简陋,只能看到消息内容,数据长度和时间

Fiddler:抓包调试利器

(1)打开Fiddler,点开菜单栏的Rules,选择Customize Rules...

(2)这时会打开CustomRules.js文件,在class Handlers中加入以下代码

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

(3)保存后就可以在Fiddler右边栏的Log标签里,看到WebSocket的数据包
下列图中红框标出的Client.1代表客户端发出的第一条消息;对应的Server.1代表服务端发出的第一条消息。MessageType:Text代表正常的通话消息;Close代表会话关闭。
客户端发出的消息:

服务端发出的消息:

然后我们会发现每次会话关闭都是由客户端发起的:

相对于Chrome控制台来说Fiddler抓包更加详细一些,能知道会话消息是由客户端还是服务端发出并且能知道消息类型。但是这仍然满足不了深入理解学习Websocket协议的目的。如果是处理HTTP、HTTPS,还是用Fiddler。其他协议比如TCP,UDP

就用WireShark。TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP、Websocket是应用层协议,主要解决如何包装数据。因为应用层是在传输层的基础上包装数据,所以我们还是从底层开始了解Websocket到底是个啥?是如何工作的?

WireShark

WireShark(前称Ethereal)是一个网络封包分析软件。网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包资料。WireShark抓包是根据TCP/IP五层协议来的,也就是物理层、数据链路层、网络层、传输层、应用层。我们主要关注传输层和应用层。

TCP三次握手

我们都知道,TCP建立连接时,会有三次握手过程。下图是WireShark截获到的三次握手的三个数据包(虽然叫数据包,但是三次握手包是没有数据的)。

点击上图中的数据包就可以查看每个数据包的详情,这里我们需要明确几个概念才能看懂每个数据包代表啥意义:
SYN:同步比特,建立连接。
ACK:确认比特,置1表示这是一个确认的TCP包,0则不是。
PSH:推送比特,当发送端PSH=1时,接收端应尽快交付给应用进程。

  • 第一次握手

可以看到我们打开的Transmission Control Protocol即为传输层(Tcp)
SYN置为1,客户端向服务端发送连接请求包。

  • 第二次握手

服务器收到客户端发过来的TCP报文,由SYN=1知道客户端要求建立联机,向客户端发送一个SYN=1,ACK=1的TCP报文,将确认序号设置为客户端的序列号加1。

  • 第三次握手

客户端接收到服务器发过来的包后检查确认序列号是否正确,即第一次发送的序号+1,以及标志位ACK是否为1。若正确则再次发送确认包,ACK标志为1。链接建立成功,可以发送数据了。

一次特殊的HTTP请求

紧接着是一次Http请求(第四个包),说明Http的确是使用Tcp建立连接的。

先来看传输层(Tcp):
PSH(推送比特)置1,ACK置1,PSH置1说明开始发送数据,同时发送数据ACK要置1,因为需要接收到这个数据包的端给予确认。PSH为1的情况,一般只出现在
DATA内容不为0的包中,也就是说PSH为1表示的是有真正的TCP数据包内容被传递。

再来看应用层(Http):这是一次特殊的Http请求,为什么是一次特殊的Http请求呢?Http请求头中Connection:Upgrade

Upgrade:websocket,Upgrade代表升级到较新的Http协议或者切换到不同的协议。很明显WebSocket使用此机制以兼容的方式与HTTP服务器建立连接。WebSocket协议有两个部分:握手建立升级后的连接,然后进行实际的数据传输。首先,客户端通过使用Upgrade:
WebSocket和Connection:
Upgrade头部以及一些特定于协议的头来请求WebSocket连接,以建立正在使用的版本并设置握手。服务器,如果它支持协议,回复与相同Upgrade:
WebSocket和Connection:
Upgrade标题,并完成握手。握手完成后,数据传输开始。这些信息在前面的Chrome控制台中也可以看到。

请求:

响应:
响应状态码 101 表示服务器已经理解了客户端的请求,在发送完这个响应后,服务器将会切换到在Upgrade请求头中定义的那些协议。

由此我们可以总结出:
Websocket协议本质上是一个基于TCP的协议。建立连接需要握手,客户端(浏览器)首先向服务器(web server)发起一条特殊的http请求,web server解析后生成应答到浏览器,这样子一个websocket连接就建立了,直到某一方关闭连接。

Websocket的世界

通信协议格式是WebSocket格式,服务器端采用Tcp Socket方式接收数据,进行解析,协议格式如下:

首先我们需要知道数据在物理层,数据链路层是以二进制进行传递的,而在应用层是以16进制字节流进行传输的。

第一个字节:

FIN:1位,用于描述消息是否结束,如果为1则该消息为消息尾部,如果为零则还有后续数据包;
RSV1,RSV2,RSV3:各1位,用于扩展定义的,如果没有扩展约定的情况则必须为0
OPCODE:4位,用于表示消息接收类型,如果接收到未知的opcode,接收端必须关闭连接。

Webdocket数据帧中OPCODE定义:
0x0表示附加数据帧
0x1表示文本数据帧
0x2表示二进制数据帧
0x3-7暂时无定义,为以后的非控制帧保留
0x8表示连接关闭
0x9表示ping
0xA表示pong
0xB-F暂时无定义,为以后的控制帧保留

第二个字节:

MASK:1位,用于标识PayloadData是否经过掩码处理,客户端发出的数据帧需要进行掩码处理,所以此位是1。数据需要解码。
PayloadData的长度:7位,7+16位,7+64位
如果其值在0-125,则是payload的真实长度。
如果值是126,则后面2个字节形成的16位无符号整型数的值是payload的真实长度。
如果值是127,则后面8个字节形成的64位无符号整型数的值是payload的真实长度。

上图是客户端发送给服务端的数据包,其中PayloadData的长度为二进制:01111110——>十进制:126;如果值是126,则后面2个字节形成的16位无符号整型数的值是payload的真实长度。也就是圈红的十六进制:00C1——>十进制:193
byte。所以PayloadData的真实数据长度是193 bytes;

根据我们的分析,客户端到服务端数据包的websocket帧图应该为:

我们再来抓包分析一下服务器到客户端的数据包:

可以发现服务器发送给客户端的数据包中第二个字节中MASK位为0,这说明服务器发送的数据帧未经过掩码处理,这个我们从客户端和服务端的数据包截图中也可以发现,客户端的数据被加密处理,而服务端的数据则没有。(如果服务器收到客户端发送的未经掩码处理的数据包,则会自动断开连接;反之,如果客户端收到了服务端发送的经过掩码处理的数据包,也会自动断开连接)。

掩码处理:

未掩码处理:

根据我们的分析,服务端到客户端数据包的websocket帧图应该为:

TCP KeepAlive

如上图所示,TCP保活报文总是成对出现,包括TCP保活探测报文和TCP保活探测确认报文。
TCP保活探测报文是将之前TCP报文的确认序列号减1,并设置1个字节,内容为“00”的应用层数据,如下图所示:

TCP保活探测确认报文就是对保活探测报文的确认,其报文格式如下:

因为Websocket通过Tcp Socket方式工作,现在考虑一个问题,在一次长连接中,服务器怎么知道消息的顺序呢?这就涉及到tcp的序列号(Sequence Number)和确认号(Acknowledgment Number)。我的理解是序列号是发送的数据长度;确认号是接收的数据长度。这样讲比较抽象,我们从TCP三次握手开始(结合下图)详细分析一下。

包1
TCP会话的每一端的序列号都从0开始,同样的,确认号也从0开始,因为此时通话还未开始,没有通话的另一端需要确认
包2
服务端响应客户端的请求,响应中附带序列号0(由于这是服务端在该次TCP会话中发送的第一个包,所以序列号为0)和相对确认号1(表明服务端收到了客户端发送的包1中的SYN)。需要注意的是,尽管客户端没有发送任何有效数据,确认号还是被加1,这是因为接收的包中包含SYN或FIN标志位。
包3
和包2中一样,客户端使用确认号1响应服务端的序列号0,同时响应中也包含了客户端自己的序列号(由于服务端发送的包中确认收到了客户端发送的SYN,故客户端的序列号由0变为1)此时,通信的两端的序列号都为1。
包4:客户端——>服务器
这是流中第一个携带有效数据的包(确切的说,是客户端发送的HTTP请求),序列号依然为1,因为到上个包为止,还没有发送任何数据,确认号也保持1不变,因为客户端没有从服务端接收到任何数据。需要注意的是,包中有效数据的长度为505字节
包5:服务器——>客户端
当上层处理HTTP请求时,服务端发送该包来确认客户端在包4中发来的数据,需要注意的是,确认号的值增加了505(505是包4中有效数据长度),变为506,简单来说,服务端以此来告知客户端端,目前为止,我总共收到了506字节的数据,服务端的序列号保持为1不变。
包6:服务器——>客户端
这个包标志着服务端返回HTTP响应的开始,序列号依然为1,因为服务端在该包之前返回的包中都不带有有效数据,该包带有129字节的有效数据。
包7
由于上个数据包的发送,TCP客户端的确认序列号增长至130,从服务端接收了129字节的数据,客户端的确认号由1增长至130
理解了序列号和确认序列号是怎么工作的之后,我们也就知道“TCP保活探测报文是将之前TCP报文的确认序列号减1,并设置1个字节”为什么要这么搞了。减一再加一,是为了保证一次连接中keep
alive不影响序列号和确认序列号。Keep alive 中的1byte 00的数据并不是真正要传递的数据,而是tcp keep
alive约定俗称的规则。

总结:
WebSocket 是一个独立的基于 TCP 的协议,它与 HTTP 之间的唯一关系就是它的握手请求可以作为一个升级请求(Upgrade request)经由 HTTP 服务器解释。再严谨一点:WebSocket是一个网络通讯协议, 只要理解上面的数据帧格式和握手流程, 都可以完成基于websokect的即时通讯

WebSocket抓包分析的更多相关文章

  1. http2 技术整理 nginx 搭建 http2 wireshark 抓包分析 server push 服务端推送

    使用 nginx 搭建一个 http2 的站点,准备所需: 1,域名 .com .net 均可(国内域名需要 icp 备案) 2,云主机一个,可以自由的安装配置软件的服务器 3,https 证书 ht ...

  2. Http实战之Wireshark抓包分析

    Http实战之Wireshark抓包分析 Http相关的文章网上一搜一大把,所以笔者这一系列的文章不会只陈述一些概念,更多的是通过实战(抓包+代码实现)的方式来跟大家讨论Http协议中的各种细节,帮助 ...

  3. Wireshark抓包分析/TCP/Http/Https及代理IP的识别

    前言 坦白讲,没想好怎样的开头.辗转三年过去了.一切已经变化了许多,一切似乎从没有改变. 前段时间调研了一次代理相关的知识,简单整理一下分享之.如有错误,欢迎指正. 涉及 Proxy IP应用 原理/ ...

  4. HTTP2特性预览和抓包分析

    背景 近年来,http网络请求量日益添加,以下是httparchive统计,从2012-11-01到2016-09-01的请求数量和传输大小的趋势图: 当前大部份客户端&服务端架构的应用程序, ...

  5. 抓包分析SSL/TLS连接建立过程【总结】

    1.前言 最近在倒腾SSL方面的项目,之前只是虽然对SSL了解过,但是不够深入,正好有机会,认真学习一下.开始了解SSL的是从https开始的,自从百度支持https以后,如今全站https的趋势越来 ...

  6. 实战录 | 基于openflow协议的抓包分析

    <实战录>导语 云端卫士<实战录>栏目定期会向粉丝朋友们分享一些在开发运维中的经验和技巧,希望对于关注我们的朋友有所裨益.本期分享人为云端卫士安全SDN工程师宋飞虎,将带来基于 ...

  7. 在Hdsi2.0 SQL的注入部分抓包分析语句

    在Hdsi2.0 SQL的注入部分抓包分析语句 恢复cmd ;insert tb1 exec master..xp_cmdshell''net user ''-- ;exec master.dbo.s ...

  8. [转] Android实时抓包分析 : 善用adb调试桥

    Android实时抓包分析 : 善用adb调试桥   谈到android网络抓包,很多人都能想到牛逼轰轰的神器tcpdump.方法就是在android机器上面安装tcpdump,然后通过-w参数把抓包 ...

  9. 云计算之路-阿里云上:Wireshark抓包分析一个耗时20秒的请求

    这篇博文分享的是我们针对一个耗时20秒的请求,用Wireshark进行抓包分析的过程. 请求的流程是这样的:客户端浏览器 -> SLB(负载均衡) -> ECS(云服务器) -> S ...

随机推荐

  1. mysql数据类型和使用方法

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u011729265/article/details/25086957         MySQL支持 ...

  2. Spark系列-核心概念

    Spark系列-初体验(数据准备篇) Spark系列-核心概念 一. Spark核心概念 Master,也就是架构图中的Cluster Manager.Spark的Master和Workder节点分别 ...

  3. Zookeeper ZAB 协议分析[转]

    写在开始:这是我找到一篇比较好的博客,转载到这来进行备份原文参考: Zookeeper ZAB 协议分析 前言 ZAB 协议是为分布式协调服务 ZooKeeper 专门设计的一种支持崩溃恢复的原子广播 ...

  4. 记录一个python公式罗列的方法 join()方法和map()方法的妙用

    题干: 怎样将一个列表中的元素读出,并列出计算式子 比如:[,,,] 输出:+++ = 列表中的元素个数不定 小白和大神的方法: #小白的 numlist=[,,,] sum1='' cal='+' ...

  5. leetcode566. Reshape the Matrix

    https://leetcode.com/problems/reshape-the-matrix/description/ public int[][] matrixReshape(int[][] n ...

  6. Spring源码分析(二十四)初始化非延迟加载单例

    摘要: 本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 完成BeanFactory的初始化工作,其中包括ConversionS ...

  7. Carthage 的使用

    第一步,当然是安装 Carthage,网上找吧 第二步,找到你要用的那个仓库,eg:https://github.com/jiutianhuanpei/SHBPlayer 第三步,cd 到工程根目录下 ...

  8. 拥抱.NET Core系列:MemoryCache 缓存过期 (转载)

    阅读目录 MSCache项目 MSCache提供的过期方式 绝对时间到期 滑动时间到期 自定义过期策略 过期策略组合拳 缓存过期回调 写在最后 在上一篇”拥抱.NET Core系列:MemoryCac ...

  9. Ubuntu18.04编译S3的Linux SDK(Zeta)

    按照S3官方Wiki(http://www.sochip.com.cn/s3)的陈述,推荐使用Ubuntu16.04作为Host端系统,笔者是一名乐于并热衷于尝鲜的搬砖工,于是,尝试在最新的18.04 ...

  10. python 第一课作用

    1.使用while循环输入 1 2 3 4 5 6     8 9 10 x=0while x<10: x=x+1 if x==7: print(' ') continue print(x)#学 ...