websocket协议详解及报文分析


       Webscoket是Web浏览器和服务器之间的一种全双工通信协议。一旦Web客户端与服务器建立起连接,之后的全部数据通信都通过这个连接进行。通信过程中,可互相发送JSON、XML、HTML或图片等任意格式的数据。

  WS(WebSocket)与HTTP协议比较:

都是基于TCP的应用层协议;
都使用Request/Response模型进行连接的建立;
在连接的建立过程中对错误的处理方式相同,在这个阶段WS可能返回和HTTP相同的返回码;
都可以在网络中传输数据。

  不同之处

WS使用HTTP来建立连接,但是定义了一系列新的header域,这些域在HTTP中并不会使用;
WS的连接不能通过中间人来转发,它必须是一个直接连接;
WS连接建立之后,通信双方都可以在任何时刻向另一方发送数据;
WS连接建立之后,数据的传输使用帧来传递,不再需要Request消息;
WS的数据帧有序。

  WS整个通信过程如下图所示:

 

 

   websocket是基于TCP的一个应用协议,与HTTP协议的关联之处在于websocket的握手数据被HTTP服务器当作HTTP包来处理,主要通过Update request HTTP包建立起连接,之后的通信全部使用websocket自己的协议。

  **请求:**TCP连接建立后,客户端发送websocket的握手请求,请求报文头部如下:

GET /uin=xxxxxxxx&app=xxxxxxxxx&token=XXXXXXXXXXXX HTTP/1.1
Host: server.example.cn:443
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36
Upgrade: websocket
Sec-WebSocket-Version: 13
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: user_id=XXXXX
Sec-WebSocket-Key: 1/2hTi/+eNURiekpNI4k5Q==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Protocol: binary, base64

  第一行为为请求的方法,类型必须为GET,协议版本号必须大于1.1

  Upgrade字段必须包含,值为websocket
  Connection字段必须包含,值为Upgrade
  Sec-WebSocket-Key字段必须包含 ,记录着握手过程中必不可少的键值。
  Sec-WebSocket-Protocol字段必须包含 ,记录着使用的子协议
  Origin(请求头):Origin用来指明请求的来源,Origin头部主要用于保护Websocket服务器免受非授权的跨域脚本调用Websocket API的请求。也就是不想没被授权的跨域访问与服务器建立连接,服务器可以通过这个字段来判断来源的域并有选择的拒绝。
  **响应:**服务器接收到请求后,返回状态码为101 Switching Protocols 的响应。

HTTP/1.1 101 Switching Protocols
Server: WebSockify Python/2.6.6
Date: Wed, 27 May 2020 03:03:21 GMT
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: hXXXXXXXXXXXXXXxGmM=
Sec-WebSocket-Protocol: binary

  Sec-WebSocket-Accept字段是由握手请求中的Sec-WebSocket-Key字段生层的。

  握手成功后,通信不再使用HTTP协议,而采用WebSocket独立的数据帧。如下图所示,为协议帧格式:

  

FIN,指明Frame是否是一个Message里最后Frame(之前说过一个Message可能又多个Frame组成);1bit,是否为信息的最后一帧
RSV1-3,默认是0 (必须是0),除非有扩展定义了非零值的意义。
Opcode,这个比较重要,有如下取值是被协议定义的
                0x00 denotes a continuation frame
                0x01 表示一个text frame
                0x02 表示一个binary frame
                0x03 ~~ 0x07 are reserved for further non-control frames,为将来的非控制消息片段保留测操作码
                0x08 表示连接关闭
                0x09 表示 ping (心跳检测相关)
                0x0a 表示 pong (心跳检测相关)
                0x0b ~~ 0x0f are reserved for further control frames,为将来的控制消息片段保留的操作码
Mask,这个是指明“payload data”是否被计算掩码。这个和后面的Masking-key有关,如果设置为1,掩码键必须放在masking-key区域,客户端发送给服务端的所有消息,此位的值都是1;
Payload len,数据的长度,
Masking-key,0或者4bit,只有当MASK设置为1时才有效。,给一个Websocket中掩码的意义
Payload data,帧真正要发送的数据,可以是任意长度,但尽管理论上帧的大小没有限制,但发送的数据不能太大,否则会导致无法高效利用网络带宽,正如上面所说Websocket提供分片。
Extension data:扩展数据,如果客户端和服务端没有特殊的约定,那么扩展数据长度始终为0
Application data:应用数据,

 

 

 

  


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM