WebSocket协议解析

WebSocket协议解析

一、协议简介

WebSocket protocol 是HTML5一种新的协议,它是实现了浏览器与服务器全双工通信,本文主要介绍WebSocket协议格式。

WebSocket通信过程分为两步:握手请求和数据传输。

二、握手请求

1、客户端在连接请求时候发送的内容

复制代码
GET / HTTP/1.1
Connection:Upgrade
Host:127.0.0.1:8088
Origin:null
Sec-WebSocket-Extensions:x-webkit-deflate-frame
Sec-WebSocket-Key:puVOuWb7rel6z2AVZBKnfw==
Sec-WebSocket-Version:13
Upgrade:websocket
复制代码

2、服务端接收请求后主要是成针对Sec-WebSocket-Key生成相应的加密key,采用的算法是sha1算法库,生成key后,和客户端握手成功,服务器端返回内容如下:

复制代码
HTTP/1.1 101 Switching Protocols
Connection:Upgrade
Server:beetle websocket server
Upgrade:WebSocket
Date:Mon, 26 Nov 2012 23:42:44 GMT
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:content-type
Sec-WebSocket-Accept:FCKgUr8c7OsDsLFeJTWrJw6WO8Q= 
复制代码

三、数据传输

客户端和服务器连接成功后,就可以进行通信了,通信协议格式是WebSocket格式,服务器端采用Tcp Socket方式接收数据,进行解析,协议格式如下:

 

第一个字节

FIN:1位,用于描述消息是否结束,如果为1则该消息为消息尾部,如果为零则还有后续数据包;

uint8_t fin = (uint8_t)msg[pos] >> 7;

RSV1,RSV2,RSV3,各1位,用于扩展定义的,如果没有扩展约定的情况则必须为0

OPCODE:4位,用于表示消息接收类型,如果接收到未知的opcode,接收端必须关闭连接。

 

uint8_t opcode = msg[pos] & 0x0f;

 

 

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

第二个字节

MASK:1位,用于标识PayloadData是否经过掩码处理,客户端发出的数据帧需要进行掩码处理,所以此位是1。数据需要解码

uint8_t mask = (uint8_t)msg[pos] >> 7;

PayloadData的长度:7位,7+16位,7+64位
如果其值在0-125,则是payload的真实长度。
如果值是126,则后面2个字节形成的16位无符号整型数的值是payload的真实长度。注意,网络字节序,需要转换。
如果值是127,则后面8个字节形成的64位无符号整型数的值是payload的真实长度。注意,网络字节序,需要转换。
长度表示遵循一个原则,用最少的字节表示长度(我理解是尽量减少不必要的传输)。举例说,payload真实长度是124,在0-125之间,必须用前7位表示;不允许长度1是126或127,然后长度2是124,这样违反原则。

复制代码
  uint64_t payload_length_ = msg[pos] & 0x7f;
   pos++;
   if(payload_length_ == 126){
       uint16_t length = 0;
       memcpy(&length, msg + pos, 2);
       pos += 2;
       payload_length_ = ntohs(length);
   }
   else if(payload_length_ == 127){
       uint32_t length = 0;
       memcpy(&length, msg + pos, 4);
       pos += 4;
       payload_length_ = ntohl(length);
   }
复制代码

后面的字节就是消息体,获取消息体内如如下:

复制代码
    char payload_[2048];
    memset(payload_, 0, sizeof(payload_));
    if(mask_ != 1){
        memcpy(payload_, msg + pos, payload_length_);
    }
    else {
        for(uint i = 0; i < payload_length_; i++){
            int j = i % 4;
            payload_[i] = msg[pos + i] ^ masking_key_[j];
        }
    }
    pos += payload_length_;
复制代码

到此为止,WebSocket协议解析,握手,取数据,完成。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值