WebSocket数据包协议详解
其实我一直想不明白HTML5包装个应用层办议作为Socket通过基础目的是为了什么,其实直接支持Socket tcp相对来说更加简单灵活.既然标准已经制定而浏览器也支持那对于我们开发者来说只能用的分.最新版本的WebSocket协议于2011-12其标准规范已经明确下来,所以现在可以根据这标准进行相应的开发.详细参考http://datatracker.ietf.org/doc/rfc6455/?include_text=1
WebSocket协议主要分为两部分,第一部分是连接许可验证和验证后的数据交互.连接许可验证比较简单,由Client发送一个类似于HTTP的请求,服务端获取请求后根据请求的KEY生成对应的值并返回.
连接请求内容:
|
1
2
3
4
5
6
7
8
|
GET / HTTP/1.1Connection:UpgradeHost:127.0.0.1:8088Origin:nullSec-WebSocket-Extensions:x-webkit-deflate-frameSec-WebSocket-Key:puVOuWb7rel6z2AVZBKnfw==Sec-WebSocket-Version:13Upgrade:websocket |
服务端接收请求后主要是成针对Sec-WebSocket-Key生成对就Sec-WebSocket-Accept 的key,生成Sec-WebSocket-Accept 值比较简单就是Sha1(Sec-WebSocket-Key+258EAFA5-E914-47DA-95CA-C5AB0DC85B11)即可,C#代码如下:
|
1
2
3
4
5
|
SHA1 sha1 = new SHA1CryptoServiceProvider();byte[] bytes_sha1_in = Encoding.UTF8.GetBytes(request.SecWebSocketKey+ "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");byte[] bytes_sha1_out = sha1.ComputeHash(bytes_sha1_in);string str_sha1_out = Convert.ToBase64String(bytes_sha1_out);response.SecWebSocketAccept = str_sha1_out; |
服务端返回内容:
|
1
2
3
4
5
6
7
8
|
HTTP/1.1 101 Switching ProtocolsConnection:UpgradeServer:beetle websocket serverUpgrade:WebSocketDate:Mon, 26 Nov 2012 23:42:44 GMTAccess-Control-Allow-Credentials:trueAccess-Control-Allow-Headers:content-typeSec-WebSocket-Accept:FCKgUr8c7OsDsLFeJTWrJw6WO8Q= |
经过服务器的返回处理后连接握手成功,后面就可以进行TCP通讯.WebSocket在握手后发送数据并象下层TCP协议那样由用户自定义,还是需要遵循对应的应用协议规范...这也是在文章之说没有直接基于Socket tcp方便的原因.
数据交互协议:
这图有点难看懂...里面包括几种情况有掩码,数据长度小于126,小于UINT16和小于UINT64等几种情况.后面会慢慢详细说明.整个协议头大概分三部分组成,第一部分是描述消息结束情况和类型,第二部分是描述是否存在掩码长度,第三部分是扩展长度描述和掩码值.
从图中可以看到WebSocket协议数据主要通过头两个字节来描述数据包的情况
第一个字节
最高位用于描述消息是否结束,如果为1则该消息为消息尾部,如果为零则还有后续数据包;后面3位是用于扩展定义的,如果没有扩展约定的情况则必须为0.可以通过以下c#代码方式得到相应值
|
1
|
mDataPackage.IsEof = (data[start] >> 7) > 0; |
最低4位用于描述消息类型,消息类型暂定有15种,其中有几种是预留设置.c#代码可以这样得到消息类型:
|
1
2
|
int type = data[start] & 0xF;mDataPackage.Type = (PackageType)type; |
第二个字节
消息的第二个字节主要用一描述掩码和消息长度,最高位用0或1来描述是否有掩码处理,可以通过以下c#代码方式得到相应值
|
1
|
bool hasMask = (data[start] >>7) > 0; |
剩下的后面7位用来描述消息长度,由于7位最多只能描述127所以这个值会代表三种情况,一种是消息内容少于126存储消息长度,如果消息长度少于UINT16的情况此值为126,当消息长度大于UINT16的情况下此值为127;这两种情况的消息长度存储到紧随后面的byte[],分别是UINT16(2位byte)和UINT64(4位byte).可以通过以下c#代码方式得到相应值
|
1
2
3
4
5
6
7
8
9
10
11
12
|
mPackageLength = (uint)(data[start] & 0x7F);start++;if (mPackageLength == 126){ mPackageLength = BitConverter.ToUInt16(data, start); start = start + 2;}else if (mPackageLength == 127){ mPackageLength = BitConverter.ToUInt64(data, start); start = start + 8;} |
如果存在掩码的情况下获取4位掩码值:
|
1
2
3
4
5
6
7
8
|
if (hasMask){ mDataPackage.Masking_key = new byte[4]; Buffer.BlockCopy(data, start, mDataPackage.Masking_key, 0, 4); start = start + 4; count = count - 4;} |
获取消息体
当得到消息体长度后就可以获取对应长度的byte[],有些消息类型是没有长度的如%x8 denotes a connection close.对于Text类型的消息对应的byte[]是相应字符的UTF8编码.获取消息体还有一个需要注意的地方就是掩码,如果存在掩码的情况下接收的byte[]要做如下转换处理:
|
1
2
3
4
5
6
|
if (mDataPackage.Masking_key != null) { int length = mDataPackage.Data.Count; for (var i = 0; i < length; i++) mDataPackage.Data.Array[i] = (byte)(mDataPackage.Data.Array[i] ^ mDataPackage.Masking_key[i % 4]); } |
WebSocket数据包协议详解的更多相关文章
- IP数据包格式详解(转)
摘自:http://blog.163.com/hlz_2599/blog/static/1423784742011112195857956/</> TCP/IP协议定义了一个在因特网上传输 ...
- TCP/IP数据包结构详解
一般来说,网络编程我们只需要调用一些封装好的函数或者组件就能完成大部分的工作,但是一些特殊的情况下,就需要深入的理解网络数据包的结构,以及协议分析.如:网络监控,故障排查等…… IP包是不安全的,但是 ...
- WebSocket协议详解及应用
WebSocket协议详解及应用(七)-WebSocket协议关闭帧 本篇介绍WebSocket协议的关闭帧,包括客户端及服务器如何发送并处理关闭帧.关闭帧错误码及错误处理方法.本篇内容主要翻译自RF ...
- TCP协议粘包问题详解
TCP协议粘包问题详解 前言 在本章节中,我们将探讨TCP协议基于流式传输的最大一个问题,即粘包问题.本章主要介绍TCP粘包的原理与其三种解决粘包的方案.并且还会介绍为什么UDP协议不会产生粘包. 基 ...
- Web协议详解与抓包实战,高效解决网络难题
无论你是前后端工程师,还是运维测试,如果想面试更高的职位,或者要站在更高的角度去理解技术业务架构,并能在问题出现时快速.高效地解决问题,Web 协议一定是你绕不过去的一道坎. 旨在帮助你对各种常用 W ...
- 接口测试之HTTP协议详解
引言 HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/1. ...
- OSPF协议详解
CCNP OSPF协议详解 2010-02-24 20:30:22 标签:CCNP 职场 OSPF 休闲 OSPF(Open Shortest Path Fitst,ospf)开放最短路径优先协议,是 ...
- RTMP协议详解(转)
转自<RTMP协议详解(一) (二) (三) > Real Time Messaging Protocol(实时消息传送协议协议)是Adobe Systems公司为Flash播放器和服务器 ...
- TCP/IP协议详解概述
TCP/IP协议详解卷1--第一章概述--读书笔记 作者:vpoet 日期:2015/06/25 注:本系列的文章只是作者对TCP/IP协议的理解,难免会出现纰漏或者不完整,当然也有可能很肤浅,希望大 ...
随机推荐
- HDU1556(树状数组)
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- IOS控件布局之Masonry布局框架
前言: 回想起2013年做iOS开发的时候,那时候并没有采用手写布局代码的方式,而是采用xib文件来编写,如果使用纯代码方式是基于window的size(320,480)计算出一个相对位置进行布局,那 ...
- windows下搭建GO开发环境
1. Go下载 由于某些原因golang.org不能访问,可以使用下面的镜像地址进行下 http://fossies.org/windows/misc/ 我的环境是win8 64位,所以选择go1.7 ...
- C++编程练习(3)----“实现简单的栈的顺序存储结构“
栈(stack)是限定仅在表尾进行插入和删除操作的线性表. 允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom). 栈又称为后进先出(Last In First Out)的线性表,简 ...
- removeAll
问题:无法移除2个集合中相同元素 方法:移除所包含的其所有元素. 在执行removeAll方法时,会先对集合元素进行比较,如果元素相等才执行移除操作,说到这,相信很多人都已经明白是怎么回事了,因为不相 ...
- Jenkins在windows上的安装配置
今天是2月14号,所谓西方情人节,下班回来发现,2月14过的比七夕还火热.于是上网百度百科查询了"情人节". 毕竟是中国的百度啊.是这么解释的.我感到很欣慰.过得每一个节日都应该 ...
- matlab和C语言的break及continue测试
break和continue语句 有两个附加语句可以控制while和for循环:break和continue语句.break语句可以中止循环的执行和跳到end后面的第一句执行,而continue只中止 ...
- 中国大学MOOC中的后台文件传输
早期版本的中国大学MOOC一旦被挂起后,应用在完成当前下载任务后无法继续添加新任务,当然也无法将缓存状态写入数据库.这个问题能否顺利解决直接关系到用户体验. 顺便吐槽下,凡是使用了后台文件传输还提示你 ...
- c++编程思想(二)--对象的创建和使用
1.解释器:将源码转换为动作(机器语言),并立即执行 编译器:编译器也会将源码转换为机器语言,但是中间会经过好多步骤,分段编译 ,然后链接,可以实现将代码模块化 2.c++不鼓励多使用预处理命令 3. ...
- Hadoop基本开发环境搭建(原创,已实践)
软件包: hadoop-2.7.2.tar.gz hadoop-eclipse-plugin-2.7.2.jar hadoop-common-2.7.1-bin.zip eclipse jdk1.8 ...