Sword websocket分析二
//websocket发送数据
int send(uint8_t* message, uint64_t message_size)
{
//掩码
const uint8_t masking_key[] = { 0x12, 0x34, 0x56, 0x78 };
//协议最基本的两个字节标志
//如果data长度在126~65535之间,则此处playload的值为126
//(message_size >= 126 ? 2 : 0) --如果playload == 126,增加额外两个字节表示data的长度
//如果数据的长度大于65535,则此处playload的值为127
//需要增加8个字节来表示数据的长度
//MASK 掩码标识位,用来表明负载是否经过掩码处理,浏览器发送的数据都是经过掩码处理(浏览器自动处理,
//无需开发者编码),服务器发送的帧必须不经过掩码处理。所以此处浏览器发送的帧必为1,服务器发送的帧必为0,否则应断开WebSocket连接
//payload length 后面4个字节可能是掩码的key(如果掩码位是1则有这4个字节的key,否则没有)
const int headlen = + (message_size >= ? : ) + (message_size >= ? : ) + (_useMask ? : ); uint8_t* header = new uint8_t[headlen];
uint8_t* txbuf = NULL;
uint64_t i = ; memset(header, , sizeof(uint8_t)*headlen);
//0x80(1000 0000) 表示一帧之内将所有的数据全部发过去
header[] = 0x80 | type; if (message_size < ) {
header[] = (message_size & 0xff) | (_useMask ? 0x80 : );
if (_useMask) {
//payload length 后面4个字节是掩码的key
header[] = masking_key[];
header[] = masking_key[];
header[] = masking_key[];
header[] = masking_key[];
}
}
else if (message_size < ) {
header[] = | (_useMask ? 0x80 : );
header[] = (message_size >> ) & 0xff;
header[] = (message_size >> ) & 0xff;
if (_useMask) {
header[] = masking_key[];
header[] = masking_key[];
header[] = masking_key[];
header[] = masking_key[];
}
}
else { // TODO: run coverage testing here
header[] = | (_useMask ? 0x80 : );
header[] = (message_size >> ) & 0xff;
header[] = (message_size >> ) & 0xff;
header[] = (message_size >> ) & 0xff;
header[] = (message_size >> ) & 0xff;
header[] = (message_size >> ) & 0xff;
header[] = (message_size >> ) & 0xff;
header[] = (message_size >> ) & 0xff;
header[] = (message_size >> ) & 0xff;
if (_useMask) {
header[] = masking_key[];
header[] = masking_key[];
header[] = masking_key[];
header[] = masking_key[];
}
} }
//服务器响应客户端websocket升级请求
int response()
{
strcat(resData, "HTTP/1.1 101 Switching Protocols\r\n");
strcat(resData, "Upgrade:websocket\r\n");
strcat(resData, "Connection: upgrade\r\n");
strcat(resData, "Sec-WebSocket-Version:13\r\n"); snprintf(serverkey, , "%s258EAFA5-E914-47DA-95CA-C5AB0DC85B11", stHeader.websocketKey); /*
把Sec-WebSocket-Key加上一个魔幻字符串258EAFA5-E914-47DA-95CA-C5AB0DC85B11。
使用 SHA-1 加密,之后进行 BASE-64编码,将结果作为 Sec-WebSocket-Accept 头的值
此处注意,网上的sha1加密都已经字符串化了,并非实际得到的sha1密文,sha1的密文不完全是由[0-9a-z]组成的
*/
result = sha_encode(SHA_1, (unsigned char *)serverkey, strlen(serverkey), (unsigned char **)&shaTmp, &shalen);
if (result)
{
return -;
}
result = base64_encode(shaTmp, shalen, &pcOut, &outlen);
if (result)
{
return -;
}
strcat(resData, "Sec-WebSocket-Accept:");
strcat(resData, pcOut);
strcat(resData, "\r\n");
}
Sword websocket分析二的更多相关文章
- Sword websocket分析一
什么是WebSocket WebSocket是一个允许Web应用程序(通常指浏览器)与服务器进行双向通信的协议. HTML5的WebSocket API主要是为浏览器端提供了一个基于TCP协议实现全双 ...
- SNMP报文抓取与分析(二)
SNMP报文抓取与分析(二) SNMP报文抓取与分析(二) 1.SNMP报文表示简介 基本编码规则BER 标识域Tag表示 长度域length表示 2.SNMP报文详细分析(以一个get-respon ...
- Fresco 源码分析(二) Fresco客户端与服务端交互(1) 解决遗留的Q1问题
4.2 Fresco客户端与服务端的交互(一) 解决Q1问题 从这篇博客开始,我们开始讨论客户端与服务端是如何交互的,这个交互的入口,我们从Q1问题入手(博客按照这样的问题入手,是因为当时我也是从这里 ...
- yhd日志分析(二)
yhd日志分析(二) 继续yhd日志分析,统计数据 日期 uv pv 登录人数 游客人数 平均访问时长 二跳率 独立ip数 1 分析 登录人数 count(distinct endUserId) 游客 ...
- SQLite入门与分析(二)---设计与概念(续)
SQLite入门与分析(二)---设计与概念(续) 写在前面:本节讨论事务,事务是DBMS最核心的技术之一.在计算机科学史上,有三位科学家因在数据库领域的成就而获ACM图灵奖,而其中之一Jim G ...
- Linux内核启动代码分析二之开发板相关驱动程序加载分析
Linux内核启动代码分析二之开发板相关驱动程序加载分析 1 从linux开始启动的函数start_kernel开始分析,该函数位于linux-2.6.22/init/main.c start_ke ...
- 一些有用的javascript实例分析(二)
原文:一些有用的javascript实例分析(二) 5 求出数组中所有数字的和 window.onload = function () { var oBtn = document.getElement ...
- Android4.0图库Gallery2代码分析(二) 数据管理和数据加载
Android4.0图库Gallery2代码分析(二) 数据管理和数据加载 2012-09-07 11:19 8152人阅读 评论(12) 收藏 举报 代码分析android相册优化工作 Androi ...
- MapReduce深度分析(二)
MapReduce深度分析(二) 五.JobTracker分析 JobTracker是hadoop的重要的后台守护进程之一,主要的功能是管理任务调度.管理TaskTracker.监控作业执行.运行作业 ...
随机推荐
- 关于ios7的适配问题
过年回来一直搞ios7的项目适配,也算是有些眉目. 方法一:直接动用Window #if __IPHONE_OS_VERSION_MAX_ALLOWED>=__IPHONE_7_0 [appli ...
- ExcelConvert
public static class ExcelConvert { #region - 由数字转换为Excel中的列字母 - public static int ToIndex(string col ...
- android使用百度地图SDK 去掉百度Logo的小技巧
// 隐藏logoView child = mMapView.getChildAt(1); if (child != null && (child instanceof ImageVi ...
- 正确使用 Volatile 变量
Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”:与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少, ...
- [CoreOS 转载] CoreOS实践指南(三):系统服务管家Systemd
转载:http://www.csdn.net/article/2015-01-08/2823477 摘要:CoreOS是采用了高度精简的系统内核及外围定制的操作系统.ThoughtWorks的软件工程 ...
- vim复制内容到系统剪贴板
vim提供了y键盘操作用于复制文本,但是复制之后的文本位于当前窗口的缓冲区中,不在系统剪贴板中,这给跨程序文本拷贝代码很来很多麻烦.搜索发现,可以使用]y指令快速将选定的文本复制到系统剪贴板中. 顺便 ...
- Linux screen用法简介
[admin@VM_0_2_centos ~]$ screen -bash: screen: 未找到命令 [admin@VM_0_2_centos ~]$ sudo su [sudo] passwor ...
- 【机器学习】K-Means算法
K-Means算法是一种cluster analysis的算法,其主要是来计算数据聚集的算法,主要通过不断地取离种子点最近均值的算法. 问题 K-Means算法主要解决的问题如下图所示.我们可以看到, ...
- java 多线程 29 :多线程组件之 Exchanger
Exchanger Exchanger,从名字上理解就是交换.Exchanger用于在两个线程之间进行数据交换,注意也只能在两个线程之间进行数据交换.线程会阻塞在Exchanger的exchange方 ...
- linux 的内核的作用和功能
Linux内核[kernel]是整个操作系统的最底层, 它负责整个硬件的驱动,以及提供各种系统所需的核心功能, 包括防火墙机制.是否支持LVM或Quota等文件系统等等, 如果内核不认识某个最新的硬件 ...