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新增加的一种通信协议,目前流行的浏览器都支持这个协议,例 ...
随机推荐
- WGS84坐标系下,经纬度如何换算成米
参考博客:显示瓦片地图 http://www.cnblogs.com/rhinoxy/p/4995731.html 注意:这里的计算方法精度相差比较大,不满足精确计算的需要. 需要理解的GIS概念: ...
- Python之类型转换
函数 描述 int(x [,base]) 将x转换为一个整数 long(x [,base] ) 将x转换为一个长整数 float(x) 将x转换到一个浮点数 complex(real [,imag]) ...
- EasyPusher推流服务接口的.NET导出
本文是在使用由 EasyDarwin 团队开发的EasyPusher时导出的C++接口的.NET实现 public class EasyPushSDK { public EasyPushSDK() { ...
- backbone.Router History源码笔记
Backbone.History和Backbone.Router history和router都是控制路由的,做一个单页应用,要控制前进后退,就可以用到他们了. History类用于监听URL的变化, ...
- Cryptography - JavaScript 加密算法库
Example 1: The following example uses aes function. <script type="text/javascript" src= ...
- (转载)一步一步学Linq to sql系列文章
现在Linq to sql的资料还不是很多,本人水平有限,如果有错或者误导请指出,谢谢. 一步一步学Linq to sql(一):预备知识 一步一步学Linq to sql(二):DataContex ...
- JavaScript之返回顶部
为了弄这个Hexo,今天又是坐在电脑面前待了一天( ⊙ o ⊙ ),老是出问题,在百度上也试验了很多方法,还是没弄好,诶...身心疲惫甚是乏累啊~~~ 算了,这个Hexo先不弄,还是安分点吧,在Hex ...
- File.Create创建文件后,需要释放资源
if (!File.Exists(SavePath)) { File.Create(SavePath).Close(); }
- (转)Yale CAS + .net Client 实现 SSO(6)
第一部分:安装配置 Tomcat 第二部分:安装配置 CAS 第三部分:实现 ASP.NET WebForm Client 第四部分:实现基于数据库的身份验证 第五部分:扩展基于数据库的身份验证 第六 ...
- Silverlight引用WebService时取消对ServiceReferences.ClientConfig文件的依赖
做过Silverlight项目的朋友都知道一般来说我们在Silverlight项目中都需要引用WebService或是WCF,引用的方式是在Visual Studio窗口中通过“添加服务引用”来添加引 ...