经过本人对WebSocket协议的研究和WebSocket服务器的编写,对WebSocket有了深入的了解,在此写个总结供以后研究参考。

1.概要

WebSocket是最新提出用于实现服务器与浏览器双向通信的一种解决方案,用于取代一些传统的数据推送方案(如iframe长连接,ajax轮询等)。该方案由于一直在草案阶段,最新的版本为version 13.该版本出现在RFC6455中。而在safari(包括桌面和移动版本)上则是使用的websocket的 draft-ietf-hybi版。照这个趋势看来,WebSocket早晚会向RFC6455的方向定型。

在本文中,称RFC6455版的chrome版,safari使用的版本为safari版。

这两个文件我已经下载下来作为本文附件,可直接参考。chrome版 safari版

2.握手协议

HTTP服务器识别WebSocket协议的方式首先是判断HTTP头中的Connection和Upgrade头,如果Connection是Upgrade,且Upgrade头是WebSocket,则可以确定为WebSocket请求,这时候要进行WebSocket的握手处理,两个版本的握手方式不同,最新的Chrome版本通过Sec-WebSocket-Key的设置进行一些计算返回Sec-WebSocket-Accept响应头,而safari版本通过Sec-WebSocket-Key1,Sec-WebSocket-Key2及请求主体三个共同计算响应主体的。下面进行分别讨论。

chrome版

Sec-WebSocket-Key是客户端随机生成并进行base64的字符串,它的原始内容是什么服务器不需要关心,服务器需要将这个字符串,与”258EAFA5-E914-47DA-95CA-C5AB0DC85B11″这个字符串进行拼接,然后对这个拼接好的字符串进行sha-1运算,再把sha-1散列得到的20字节进行base64编码即为响应头Sec-WebSocket-Accept的值。

safari版

这个版本让人觉得有点意思,有种小学玩数数棍的感觉。下面给个示例请求:

Sec-WebSocket-Key1: 18x 6]8vM;54 *(5: { U1]8 z [ 8

Sec-WebSocket-Key2: 1_ tx7X d < nw 334J702) 7]o}` 0

Tm[K T2u

首先,我们把Sec-WebSocket-Key1和Sec-WebSocket-Key2中的所有数字从左到右提出来组成一个整数,那么上面的示例可以组成1868545188 和 1733470270两个数。

接下来我们去数两个串各自的空格数,数出来分别为12和10

然后将上面的数除以下面的数,可得到155712099 和 173347027

这两个数是32位的整数,以Big-Endian的方式(低地址存放最高字节)各保存为4个字节,再与请求体中的8个字节拼接,可以得到一个16字节的串.再对这个串进行md5,md5结果的16字节即作为响应体返回给客户端.

这个示例将返回fQJ,fN/4F4!~K~MH,示例是巧合,实际上返回的内容可以是乱码的.但key中不会出现乱码.

下面是我已经写好的计算响应值的C函数:

/**

* chrome版websocket响应值计算

*/

void websocket_accept_key(const char* key,int key_len,char* out){

char tmp[128];

unsigned char sha[20];

if(key_len==0) key_len=strlen(key);

strcpy(tmp,key);

strcpy(tmp+key_len,"258EAFA5-E914-47DA-95CA-C5AB0DC85B11");

sha1(tmp,key_len+36,sha);

base64_encode(sha,20,out);

}

/**

* safari版websocket响应值计算

*/

void websocket_accept_key_old(const char* key1,int key1Len,const char* key2,int key2Len,char* body,char* out){

char tmp[16];

unsigned long long kv1=0;

unsigned long long kv2=0;

int c1=0;

int c2=0;

int i;

if(key1Len<=0) key1Len=strlen(key1);

if(key2Len<=0) key2Len=strlen(key2);

for(i=0;i

if(key1[i]>='0' && key1[i]<='9') kv1=kv1*10+(key1[i]-'0');

else if(key1[i]==' ') c1++;

}

for(i=0;i

if(key2[i]>='0' && key2[i]<='9') kv2=kv2*10+(key2[i]-'0');

else if(key2[i]==' ') c2++;

}

kv1/=c1;

kv2/=c2;

for(i=3;i>=0;i--){

tmp[i]=kv1&0xff;

tmp[i+4]=kv2&0xff;

kv1=kv1>>8;

kv2=kv2>>8;

}

for(i=0;i<8;i++){

tmp[i+8]=body[i];

}

md5(tmp,16,out);

out[16]=0;

}

为什么要做这么复杂的握手?这是为了让客户端知道这个服务器是否真的支持websocket,因为这个协议本来很像HTTP协议,如果直接向HTTP服务器发起这样的请求,服务器同样会响应并返回Bad request.

3.结论

经过分析可以知道两种方式的握手步骤,对比下来version13版的websocket握手更加简单.目前version13已经正为websocket正式版本,后期的改动应该不会有太多大的变动.

websocket握手失败_WebSocket握手总结相关推荐

  1. websocket握手失败_WebSocket握手期间出错:意外的响应代码:500

    WebSocket握手期间出错:意外的响应代码:500 我在我的网站上使用websocket,但随机发送给我以下错误消息: WebSocket连接到'ws://client.mydomain.com/ ...

  2. websocket创建失败_WebSocket sendSocketMessage 发送失败,onSocketMessage接收不到数据

    详细问题描述 Socket链接 手机调试没有任何问题 onSocketOpen onSocketMessage 能发送 能接收数据 但是打包编译后 APP上面只能连接成功,发送接收代码不执行 失效 [ ...

  3. 握手失败_拜托了,看完这篇别再问我什么是TCP三次握手和四次挥手

    TCP三次握手和四次挥手的问题在面试中是最为常见的考点之一.很多读者都知道三次和四次,但是如果问深入一点,他们往往都无法作出准确回答. 三次握手如何建立连接? 三次握手建立链接 从图中可以清楚的看到, ...

  4. [TCP/IP] TCP第三次握手失败怎么办

    三次握手 客户端 ==> SYN是1同步 ,ACK确认标志是0,seq序号是x ==> 服务器 客户端 <== SYN是1同步 ,ACK确认标志是1,seq序号是y,ack确认号是x ...

  5. 阿里云环境中TLS/SSL握手失败的场景分析

    TLS/SSL握手是一个相对复杂的过程,在阿里云环境中结合产品,安全等特性,可能会让TLS/SSL握手过程的不定性更多.本文来总结下各种握手失败的场景. 一次TLS/SSL握手的过程 本文不详细介绍T ...

  6. jssdk信息验证失败_阿里云环境中TLS/SSL握手失败的场景分析

    TLS/SSL握手是一个相对复杂的过程,在阿里云环境中结合产品,安全等特性,可能会让TLS/SSL握手过程的不定性更多.本文来总结下各种握手失败的场景. 一次TLS/SSL握手的过程 本文不详细介绍T ...

  7. android https握手失败,Android SSL错误握手失败

    最近我在连接特定服务器的测试中发生了类似的错误: 握手失败;返回-1,SSL错误代码1,net_error -103 我通过搜索铬源代码找到了一些有用的理由,这表明了ret代码的含义.也许它可以帮助你 ...

  8. 【网络编程开发系列】好端端的MQTT-broker重新部署后居然出现TLS握手失败了

    摘要:本文通过一次真实的现网案例复盘,深度还原TLS握手问题的排查思路和方法,希望对广大读者有所启发和帮助. 文章目录 1 写在前面 2 问题描述 2.1 项目背景 2.2 现场问题 3 场景复现 3 ...

  9. Android 10 SSL双向认证握手失败

    Android 10 SSL双向认证握手失败 公司项目前端时间遇到的一个问题(已经解决了),最近有时间准备分享一下. 项目工程中一直使用SSL双向认证的套接字通信方式,前段时间有Android 10的 ...

  10. fiddler 抓包 System.IO.IOException 由于意外的数据包格式,握手失败

    抓安卓模拟器包 1.打开https捕捉, 信任根证书 2.证书手动安装, 基本上就是点下一步, 然后完事了 3.调整连接(这样只有连上这个端口的请求才会捕获)  如: 本机ip地址:8899  模拟器 ...

最新文章

  1. PHP Shell生成工具Weevely
  2. linux查看java jdk安装路径和设置环境变量
  3. SQL Server 2012 新特性:新增和修改函数
  4. 推荐给开发人员的实用命令行工具
  5. java 比较器类_java常用类——比较器
  6. application实现网页计数_SpringBoot整合NoSQL 数据库(Redis)实现缓存
  7. 制造业中人工智能的应用有哪些?
  8. 不重复计数函数php,EXCEL多条件不重复计数函数是什么
  9. EXCEL 绘制斜线表头
  10. 【电力负荷预测】基于matlab日特征气象因素支持向量机SVM电力负荷预测【含Matlab源码 1612期】
  11. 诺诺打赏源码_2020二开诺诺视频打赏源码/VIP付费看视频带试看 已对接支付+代理...
  12. 【引文74 引文114】基于区块链的联邦学习的激励机制设计
  13. 引子——漂在中关村 1
  14. 科大讯飞输入法android离线语音,讯飞输入法Android5.0.1752 离线语音更轻快的表达...
  15. PHP学习笔记——图形图像
  16. 密码学基础算法(二)中国剩余定理
  17. for in 用法
  18. 如何在多可系统里设置腾讯通RTX参数
  19. Restoration forWeakly Blurred and Strongly Noisy Images 阅读理解
  20. word中插入endnote 为什么会是大括号,而且后面没有文献

热门文章

  1. python爬虫获取下一页_Python爬虫怎么获取下一页的URL和网页内容?
  2. 7.计算机网络的发展 计算机网络发展背景 原因 阿帕网与计算机网络 通信方式 电路 报文 分组 包 交换 卡恩 瑟夫 网络控制协议 NCP TCP ip诞生发展 tcp 协议族 应用编程接口
  3. java 使用CA认证
  4. 几种常见电源防反接设计
  5. html 5 游戏 脚本,HTML 5开发RPG游戏之四(游戏脚本化)(2)
  6. Expressive Body Capture: 3D Hands, Face, and Body from a Single Image
  7. 2019“我爱北京——市民新春联欢会”将现300人大合唱
  8. 黑客帝国、乱雨纷飞效果
  9. HackingLab 脚本关
  10. Faster-RCNN简易复现