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新增加的一种通信协议,目前流行的浏览器都支持这个协议,例 ...
随机推荐
- C#导出数据至excel模板
开源分享最近一个客户要做一个将数据直接输出到指定格式的Excel模板中,略施小计,搞定 其中包含了对Excel的增行和删行,打印预览,表头,表体,表尾的控制 using System; using S ...
- 用Chrome在电脑上模拟微信浏览器
1.先了解安卓微信和Ios微信的UA(User agent:用户代理) 安卓微信UA: mozilla/5.0 (linux; u; android 4.1.2; zh-cn; mi-one plus ...
- Linux学习笔记---【1】
什么是POSIX? 为何说Linux使用POSIX对于开发有很好的影响? POSIX是可携式操作系统接口(Portable Operating System Interface)的缩写,重点在于规范内 ...
- VHDL MOD和REM(转)
mod(取模)and rem(取余) VHDL has mod and rem. They return the same value if both arguments are positive. ...
- php数组编码转换函数的示例
场景说明/问题描述: Ajax提交页面编码为gb2312,数据库编码为utf8,在不更改页面及数据库编码的情况下插入数据. 自定义函数: 代码如下 复制代码 function array_iconv ...
- 集合框架学习之排序Comparable&Comoarator
1.内置引用数据类型比较(常用) 1.1 Comparable 1.整数.小数Integer Float Double 直接比较基本数据类型的大小 2.字符:比较的Unicode码只差 3.字符串: ...
- Codevs 1083 Cantor表
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 白银 Silver 题目描述 Description 现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的 ...
- DataGrid3
a标签,DataGrid的数据绑定 1.function aa(id, url) { //alert(id); window.open(url + '&am ...
- IPC with pipes, demo of 'popen'
#include <stdio.h> #include <unistd.h> int main() { FILE* stream = popen ("sort&quo ...
- builder-设计模式
package com.wp.java.builder; import org.junit.Test; public class DoDoContactDemo { @Test public void ...