Qt websocket协议的实现
handshake(握手)
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
server回复:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
"dGhlIHNhbXBsZSBub25jZQ=="(Sec-WebSocket-Key)+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"(因定GUID)
先SHA-1哈希,再用base64编码,得到"s3pPLMBiTxaQ9kYGzzhZRbK+xOo="
Framing Protocol(数据帧协议)
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
| Extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
| |Masking-key, if MASK set to 1 |
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
opcode:
0x1 text frame
0x2 binary frame
0x8 connection close
Mask:是否有掩码(client to server必须, server to client可选)
Payload length:负载长度
<=125 直接7位表示长度
126,表示长充大于125并小于0xFFFF,长度放在2Byte
127,长度放在后8Byte
Masking-key:如果有Mask,4Byte
Payload Data:如果有Mask,需要和Making-key做异或来还原数据
QByteArray handShake(QString secWebSocketKey)
{
Q_ASSERT(!secWebSocketKey.isEmpty());
secWebSocketKey += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
QString s= QCryptographicHash::hash(secWebSocketKey.toAscii(),
QCryptographicHash::Sha1).toBase64();
QString respone = QString("HTTP/1.1 101 Switching Protocols\r\n"
"Upgrade: websocket\r\n"
"Connection: Upgrade\r\n"
"Access-Control-Allow-Credentials:true\r\n"
"Access-Control-Allow-Headers:content-type\r\n"
"Sec-WebSocket-Accept: %1\r\n"
"\r\n").arg(s);
return respone.toAscii();
}
void unmask (int pos, int len, unsigned char *buf)
{
int i = pos; //The position of payload data
int n = pos - 4; //The position of masking-key
for (; i<len; i++,n++)
{
if (n == pos) n = pos - 4; //back to the first masking-key
buf[i] ^= buf[n]; //unmask: payload data XOR masking-key
}
}
QByteArray parserData(QByteArray input)
{
unsigned char *buf=(unsigned char *)input.data();
QByteArray out;
int len = input.length();
if (buf[0] == 0x88)
{
qDebug()<<"Received a Close frame";
out = "close";
return out;
}
buf[1] &= 0x7F;
int payloadBegin = 0;
if (buf[1] < 126)
{
payloadBegin = 6;
}
else if (buf[1] == 126)
{
payloadBegin = 8; //6+2
}
else if (buf[1] == 127)
{
payloadBegin = 14;//6+8
}
unmask(payloadBegin, len, buf);
out = QByteArray::fromRawData((const char *)(input.data()+payloadBegin), input.size()-payloadBegin);
return out;
}
void writeData(QTcpSocket *socket, const QByteArray &data)
{
QByteArray head(2, 0);
if (data.length()<=125)
{
quint8 len = data.length();
head[1] = len;
}
else if (data.length()<=0xffff)
{
head[1] = 126;
quint16 len = data.length();
head.resize(4);
for (int i=3; i>1; i--)
{
head[i] = (byte)(len & 0xff);
len = len >> 8;
}
}
else{
head[1] = 127;
quint64 len = data.length();
head.resize(10);
for (int i=9; i>1; i--)
{
head[i] = (byte)(len & 0xff);
len = len >> 8;
}
}
socket->write(head);
socket->write(data);
socket->flush();
}
Qt websocket协议的实现的更多相关文章
- Websocket 协议解析
WebSocket protocol 是HTML5一种新的协议.它是实现了浏览器与服务器全双工通信(full-duplex). 现 很多网站为了实现即时通讯,所用的技术都是轮询(po ...
- WebSocket协议开发
一直以来,网络在很大程度上都是围绕着HTTP的请求/响应模式而构建的.客户端加载一个网页,然后直到用户点击下一页之前,什么都不会发生.在2005年左右,Ajax开始让网络变得更加动态了.但所有的HTT ...
- 初识WebSocket协议
1.什么是WebSocket协议 RFC6455文档的表述如下: The WebSocket Protocol enables two-way communication between a clie ...
- Websocket协议的学习、调研和实现
本文章同时发在 cpper.info. 1. websocket是什么 Websocket是html5提出的一个协议规范,参考rfc6455. websocket约定了一个通信的规范,通过一个握手的机 ...
- python测试基于websocket协议的即时通讯接口
随着html5的广泛应用,基于websocket协议的即时通讯有了越来越多的使用场景,本文使用python中的websocket-client模块来做相关的接口测试 import webclient ...
- Websocket协议之php实现
前面学习了HTML5中websocket的握手协议.打开和关闭连接等基础内容,最近用php实现了与浏览器websocket的双向通信.在学习概念的时候觉得看懂了的内容,真正在实践过程中还是会遇到各种问 ...
- Websocket协议数据帧传输和关闭连接
之前总结了关于Websocket协议的握手连接方式等其他细节,现在对socket连接建立后的数据帧传输和关闭细节总结. 一.数据帧格式 数据传输使用的是一系列数据帧,出于安全考虑和避免网络截获,客户端 ...
- Websocket协议之握手连接
Websocket协议是为了解决web即时应用中服务器与客户端浏览器全双工通信的问题而设计的,是完全意义上的Web应用端的双向通信技术,可以取代之前使用半双工HTTP协议而模拟全双工通信,同时克服了带 ...
- WebSocket协议
websocket 简介 (2013-04-09 15:39:28) 转载▼ 分类: websocket 一 WebSocket是html5新增加的一种通信协议,目前流行的浏览器都支持这个协议,例 ...
随机推荐
- Table of Contents - 设计模式
设计原则 OCP - 开闭原则 SRP - 单一职责原则 DIP - 依赖倒置原则 ISP - 接口隔离原则 LSP - 里氏替换原则 LoD - 迪米特法则 创建型模式 工厂方法模式 抽象工厂模式 ...
- 根据不同的浏览器对不同元素进行css调整
<!if firefox> .element { top:4px; } <![endif]> <!if chrome> .element { top:6px; } ...
- 【转】C# 中访问修饰符
用通过代码: 类内部 using System;class Mod{ void defaultMethod() { Console.WriteLine("this ...
- IntentFilterDemo
intent-filter示例: <activity android:name=".CustomActivity" android:label="@string/t ...
- PAT1015—— 德才论
宋代史学家司马光在<资治通鉴>中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人.凡取人之术,苟不得圣人,君子而与之,与其得小人,不若得愚人 ...
- javaScript之 变量、作用域和内存问题
<javaScript高级程序设计>第四章 读书笔记 4.1 基本类型 和 引用类型 的值 1. 基本类型值 包括:Undefined.Null.Boolean.Number 和 St ...
- 10款很酷的HTML5动画和实用的HTML5应用
1.HTML5的画布花朵生成器可生成多种样式的花朵 HTML5非常流行,利用HTML5制作动画也非常方便,今天要分享一款利用HTML5 Canvas制作的花朵生成器,我们只需要在Canvas画布上点击 ...
- Android实现Http协议案例
在Android开发中,使用Http协议实现网络之间的通信是随处可见的,使用http方式主要采用2中请求方式即get和post两种方式. 一.使用get方式: HttpGet httpGet = ne ...
- MFC控件随窗口大小变化原理及实现
本文主要针对MFC的dialog,实现控件随窗口大小变化. 原理:首先获取dialog的初始大小,当窗口发送变动时,调用OnSize事件和方法,计算缩放比例,然后对界面中的所有控件进行缩放和布局. 实 ...
- 《RPM源码包的制作》RHEL6
一下rpm包的创建不含编译部分: 首先写个脚本,这个脚本是你想干的事..useradd.sh是我写的脚本,批量添加20个用户.我们创建一个目录,将脚本放进去: 将此目录压缩: 我们将校验的key导出: ...