其实我一直想不明白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数据包协议详解的更多相关文章

  1. IP数据包格式详解(转)

    摘自:http://blog.163.com/hlz_2599/blog/static/1423784742011112195857956/</> TCP/IP协议定义了一个在因特网上传输 ...

  2. TCP/IP数据包结构详解

    一般来说,网络编程我们只需要调用一些封装好的函数或者组件就能完成大部分的工作,但是一些特殊的情况下,就需要深入的理解网络数据包的结构,以及协议分析.如:网络监控,故障排查等…… IP包是不安全的,但是 ...

  3. WebSocket协议详解及应用

    WebSocket协议详解及应用(七)-WebSocket协议关闭帧 本篇介绍WebSocket协议的关闭帧,包括客户端及服务器如何发送并处理关闭帧.关闭帧错误码及错误处理方法.本篇内容主要翻译自RF ...

  4. TCP协议粘包问题详解

    TCP协议粘包问题详解 前言 在本章节中,我们将探讨TCP协议基于流式传输的最大一个问题,即粘包问题.本章主要介绍TCP粘包的原理与其三种解决粘包的方案.并且还会介绍为什么UDP协议不会产生粘包. 基 ...

  5. Web协议详解与抓包实战,高效解决网络难题

    无论你是前后端工程师,还是运维测试,如果想面试更高的职位,或者要站在更高的角度去理解技术业务架构,并能在问题出现时快速.高效地解决问题,Web 协议一定是你绕不过去的一道坎. 旨在帮助你对各种常用 W ...

  6. 接口测试之HTTP协议详解

    引言 HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/1. ...

  7. OSPF协议详解

    CCNP OSPF协议详解 2010-02-24 20:30:22 标签:CCNP 职场 OSPF 休闲 OSPF(Open Shortest Path Fitst,ospf)开放最短路径优先协议,是 ...

  8. RTMP协议详解(转)

    转自<RTMP协议详解(一) (二) (三) > Real Time Messaging Protocol(实时消息传送协议协议)是Adobe Systems公司为Flash播放器和服务器 ...

  9. TCP/IP协议详解概述

    TCP/IP协议详解卷1--第一章概述--读书笔记 作者:vpoet 日期:2015/06/25 注:本系列的文章只是作者对TCP/IP协议的理解,难免会出现纰漏或者不完整,当然也有可能很肤浅,希望大 ...

随机推荐

  1. C# MongoDB 查询,分组,聚合,排序,条件,分页

    先下载个C#的驱动.MongoDB提供各种主流与非主流预言的开发驱动. C# Driver 下载地址:这里 CSharp Driver Tutorial:这里 下载文件安装或者解压缩包 如果您是安装, ...

  2. Express与NodeJs创建服务器的两种方法

    NodeJs创建Web服务器 var http = require('http'); var server = http.createServer(function(req, res) { res.w ...

  3. EF6多线程与分库架构设计之Repository

    1.项目背景 这里简单介绍一下项目需求背景,之前公司的项目基于EF++Repository+UnitOfWork的框架设计的,其中涉及到的技术有RabbitMq消息队列,Autofac依赖注入等常用的 ...

  4. Bootstrap WPF Style(二)--Glyphicons 字体图标

    介绍 关于Glyphicons字体图标,首先给出友情链接 Glyphicons 这个项目是在Bootstrap WPF Style项目基础上做的,详见http://www.cnblogs.com/ts ...

  5. HTML5部分元素

    Document HTML4文档声明 : <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" &qu ...

  6. 细说Asp.Net Web API消息处理管道(二)

    在细说Asp.Net Web API消息处理管道这篇文章中,通过翻看源码和实例验证的方式,我们知道了Asp.Net Web API消息处理管道的组成类型以及Asp.Net Web API是如何创建消息 ...

  7. C# 多态理论基础

    一.概述 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性. 可以用不同的方式实现组件中的多态性: ● 接口多态性. ● 继承多态性. ● 通过抽象类实现的多态性. 二.实 ...

  8. ArcObjects与ArcEngine的联系与区别

    ArcObjects与ArcEngine的联系与区别 AO一般指的是桌面产品开发组件,需要在桌面环境中才能够使用,最典型的就是嵌入式VBA开发.但是这样带来的弊端和OFFICE等相关软件一样明显,就是 ...

  9. SQLite基础回顾

    SQLite基础回顾 SQLite iOS中的数据存储方式 Plist(NSArray\NSDictionary) Preference(偏好设置\NSUserDefaults) NSCoding(N ...

  10. 解读Java内部类

    一.基本概念: 顾名思义,内部类存在于外部类当中,依附于外部类.就像眼睛和脑袋的关系一样. 二.几点说明: 1.内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以 ...