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新增加的一种通信协议,目前流行的浏览器都支持这个协议,例 ...
随机推荐
- GAN
GAN(Generative Adversarial Nets),产生式对抗网络 存在问题: 1.无法表示数据分布 2.速度 3.resolution太小,大了无语义信息 4.无reference 5 ...
- C++之vector用法
1.插入配对 std::vector<pair<int,int> > w; w.push_back(make_pair<int,int>(f,s) ); cout ...
- css+js 控制幻灯片效果
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- C#中winform窗体如何嵌入cmd命令窗口
解决方法一: 自己放一个文本框,改成黑色,然后输入命令,执行时,你Process.Start cmd ,此时CMD窗口不显示,然后,将CMD的返回值,再取出来,设回文本框. 如何用这种方法实时获取cm ...
- IE8 textarea 滚动条定位不准解决方法
工作中遇到一个bug: IE8 下textarea 如果带滚动条(height:100px;overflow:scroll-y;),内容高度超过可视区域之后,输入文字,滚动条位置会乱跳. 开始以为是j ...
- (转)RabbitMQ消息队列(七):适用于云计算集群的远程调用(RPC)
在云计算环境中,很多时候需要用它其他机器的计算资源,我们有可能会在接收到Message进行处理时,会把一部分计算任务分配到其他节点来完成.那么,RabbitMQ如何使用RPC呢?在本篇文章中,我们将会 ...
- Codevs 2898 卢斯的进位制
时间限制: 1 s 空间限制: 32000 KB 题目等级 : 青铜 Bronze 题目描述 Description 著名科学家卢斯为了检查学生对进位制的理解,他给出了如下的一张加法表,表中的字母 ...
- python中文json串创建与解析
下面代码,举例说明了json如何创建和解析含有中文的json串: #coding=gbk import os import sys reload(sys) sys.setdefaultencoding ...
- Vim保存文件命令 ":wq" 与 ":x" 的区别
CSDN转载 [1] Vim是Unix/Linux系统最常用的编辑器之一,在保存文件时,我通常选择":wq",因为最开始学习vim的时候,就只记住了几个常用的命令:也没有细究命令的 ...
- struts2中constant参数设置
序号 方法 说明 1 <constant name="struts.i18n.encoding" value="UTF-8"/> 指定web应用默认 ...