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.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 |
服务端接收请求后主要是成针对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 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= |
经过服务器的返回处理后连接握手成功,后面就可以进行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协议的理解,难免会出现纰漏或者不完整,当然也有可能很肤浅,希望大 ...
随机推荐
- webSocket错误收集
关于 使用WebSocket报如下错误, Uncaught InvalidStateError: Failed to execute 'send' on 'WebSocket': already in ...
- POI-处理大Excel文件(xls)
最近需要处理一个比较大的excel文件,但是poi在处理文件时会抛出OOM导致程序崩溃,查看官方文档看到可以以流式的方式读取excel避免读取大文件时的OOM.本文主要记述xls的处理. 环境模拟 先 ...
- Hadoop权威指南:HDFS-写入数据
Hadoop权威指南:HDFS-写入数据 FileSystem类有一系列的新建文件的方法.最简单的方法是给准备建的文件指定一个Path对象,然后返回一个用于写入数据的输出流: public FSDat ...
- C#剪贴板对文件的复制、粘贴操作
1.把文件加到剪贴板: System.Collections.Specialied.StringCollection files=new System.Collections.Specialied.S ...
- 根据dba_hist_osstat统计CPU占用情况
在11g里面,视图dba_hist_osstat用来记录OS级别的time时间指标.视图dba_hist_osstat_name显示了相关的指标名称. SYS@/dzgddb> select * ...
- 64位win2003 IIS6运行32位的.NET程序
做web服务迁移,从32位win2003迁移到64位win2003,数据库是32位Oracle在另外一台服务器上. 迁移之后数据库各种连不上,oracle的客户端32位的装完装64位的,odp.net ...
- 游戏UI框架设计(二) : 最简版本设计
游戏UI框架设计(二) --最简版本设计 为降低难度决定先讲解一个最简版本,阐述UI框架的核心设计理念.这里先定义三个核心功能: 1:UI窗体的自动加载功能. 2:缓存UI窗体. 3:窗体生命周期(状 ...
- 从源码解析LinkedList集合
上篇文章我们介绍了ArrayList类的基本的使用及其内部的一些方法的实现原理,但是这种集合类型虽然可以随机访问数据,但是如果需要删除中间的元素就需要移动一半的元素的位置,效率低下.并且它内 ...
- Dijkstra算法——单源最短路径问题
学习一个点到其余各个顶点的最短路径--单源最短路径 Dijkstra算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向 ...
- VS2012 百度云下载 开发工具
百度云下载地址:链接: http://pan.baidu.com/s/1qWDIDPi密码: 5nr0 ASP.NET MVC4.0+ WebAPI+EasyUI+KnockOutJS快速开发框架 通 ...