Websocket认识

想要实现websocket服务器,需要注意两部分,一次握手确认以及数据传输。

关于握手:

类似HTTP协议,在客户端(用户浏览器发起)发来握手请求:

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

服务器接收到请求后返回确认:

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= 

观察这两段报文的交互,最主要的地方在于客户端请求中的Sec-WebSocket-Key字段,以及服务端返回的Sec-WebSocket-Accept字段。

关于客户浏览器如何生成Sec-WebSocket-Key字段这里无需考虑,已经实现在浏览器里了,而对于需要服务端返回的Sec-WebSocket-Accept字段,其生产过程也并不复杂。服务端通过分析请求头后得到Sec-WebSocket-Key字段的值,然后与“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”这段魔幻字符串连接,接着使用SHA-1加密,之后进行BASE-64编码即可作为服务端需要返回的Sec-WebSocket-Accept字段的值了。

以上就是报文确认阶段,这之后就可以进行数据交换了。


数据交互

数据交互过程中,浏览器与服务器之间以帧的形式传递数据

以下两点在实现websocket服务器时需要注意:

  1. 客户端向服务器传输的数据帧必须经过掩码处理,一旦服务器收到未经掩码处理的数据帧,应该立即断开连接
  2. 服务器想客户端传输的数据帧一定不能经过掩码处理。客户端若接收到经掩码处理的数据帧,会断开连接

以下是数据帧的表示图:

             

整个数据帧大致可以分为四个部分,这里按字节来解释上图的大意:

第1字节:

    此字节的最高位FIN表示消息是否结束,一个消息可以由一个或多个数据帧组成(分片目的是发送长度未知的消息。如果不分片发送,即一帧,就需要缓存整个消息,计算其长度,构建frame并发送;使用分片的话,可使用一个大小合适的buffer,用消息内容填充buffer,填满即发送出去),若FIN为1则表示此数据帧为消息尾部,即结束帧,为0则表示此消息还未结束。

    接下来的3位RSV这里不作介绍。

    余下的opcode四位用于描述消息类型,若值为0x0表示附加数据帧, 若值为0x1表示文本数据帧,若值为0x2表示二进制数据帧,若值为0x8表示连接关闭,以及0x9表示ping,0xA表示pong,未提及的表示暂未定义的。

第2字节

    此字节的最高位MASK即表示是否设置了掩码,数据是否经过了掩码处理。所以在客户端发往服务器的数据帧中此位必须为1,可以在之后的Masking-key域中得到掩码的值,用于得到真正传输的数据。

    接下来的7位需要分开仔细分析,用于表示传输的数据的长度(字节为单位):

  1. 如果这7位的值在0~125之间,那么传输的数据的真正长度就是这7位的值
  2. 如果值为126,那么传输的数据的真正长度用后面的2个字节(16位)来表示
  3. 如果只为127,那么传输的数据的真正长度用后面的8个字节(64位)来表示

获取掩码

    如果设置了掩码,那么掩码的值即为数据长度的后4个字节(32位),即可能是msg[2 : 6] ,或是msg[4:8],或是msg[10 : 14]

掩码之后,即为真正的数据部分了。


参考:

  1. 源码参考                                                            
  2. websocket认识            
  3. websocket认识2 
  4. python struct模块认识              
  5. websocket协议中文版  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值