Websocket协议之握手连接
Websocket协议是为了解决web即时应用中服务器与客户端浏览器全双工通信的问题而设计的,是完全意义上的Web应用端的双向通信技术,可以取代之前使用半双工HTTP协议而模拟全双工通信,同时克服了带宽和访问速度等的诸多问题。协议定义为ws和wss协议,分别为普通请求和基于SSL的安全传输,占用端口与http协议系统,ws为80端口,wss为443端口,这样可以支持HTTP代理。
协议包含两个部分,第一个是“握手”,第二个是数据传输。
一、Websocket URI
定义的两个协议框架ws和wss与http类似,而且各自部分的要求也是在HTTP协议中使用的一样,各自的URI如下:
ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]
wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ]
其中port是可选项,query前接“?”。
二、握手(Opening & Closing Handshake)打开连接
当建立一个Websocket连接时,为了保持基于HTTP协议的服务器软件和中间件进行兼容工作,客户端打开一个连接时使用与HTTP连接的同一个端口到服务器进行连接,这样被设计为一个升级的HTTP请求。
1、发送握手请求
此时的连接状态是CONNECTING,客户端需要提供host、port、resource-name和一个是否是安全连接的标记,也就是一个WebSocket URI。
客户端发送的一个到服务器端握手请求如下:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
这个升级的HTTP请求头中的字段顺序是可以随便的。与普通HTTP请求相比多了一些字段。
- Sec-WebSocket-Protocol:字段表示客户端可以接受的子协议类型,也就是在Websocket协议上的应用层协议类型。上面可以看到客户端支持chat和superchat两个应用层协议,当服务器接受到这个字段后要从中选出一个协议返回给客户端。
- Upgrade:告诉服务器这个HTTP连接是升级的Websocket连接。
- Connection:告知服务器当前请求连接是升级的。
- Origin:该字段是用来防止客户端浏览器使用脚本进行未授权的跨源攻击,这个字段在WebSocket协议中非常重要。服务器要根据这个字段判断是否接受客户端的Socket连接。可以返回一个HTTP错误状态码来拒绝连接。
- Sec-WebSocket-Key:为了表示服务器同意和客户端进行Socket连接,服务器端需要使用客户端发送的这个Key进行校验,然后返回一个校验过的字符串给客户端,客户端验证通过后才能正式建立Socket连接。服务器验证方法是:首先进行 Key + 全局唯一标示符(GUID)“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”连接起来,然后将连接起来的字符串使用SHA-1哈希加密,再进行base64加密,将得到的字符串返回给客户端作为握手依据。其中GUID是一个对于不识别WebSocket的网络端点不可能使用的字符串。
- 请求的WebSocket URI必须要是定义的有效的URI。
- 如果客户端已经有一个WebSocket连接到远程服务器端,不论是否是同一个服务器,客户端必须要等待上一个连接关闭后才能发送新的连接请求,也就是同一客户端一次只能存在一个WebSocket连接。如果想同一个服务器有多个连接,客户端必须要串行化进行。如果客户端检测到多个到不同服务器的连接,应该限制一个最大连接数,在web浏览器中应该设定最多可以打开的标签页的数目。这样可以防止到远程服务器的DDOS攻击,但这是对到多个服务器的连接,如果是到同一个服务器连接,并没有数目限制。
- 如果使用了代理服务器,那么客户端建立连接的时候需要告知代理服务器向目标服务器打开TCP连接。
- 如果连接没有打开,一定是某一方出现错误,此时客户端必须要关闭再次连接的尝试。
- 连接建立后,握手必须要是一个有效的HTTP请求
- 请求的方式必须是GET,HTTP协议的版本至少是1.1
- Upgrade字段必须包含而且必须是"websocket",Connection字段必须内容必须是“Upgrade”
- Sec-Websocket-Version必须,而且必须是13
2、返回握手应答
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
响应头握手过程中是服务器返回的是否同意握手的依据。
- 首行返回的是HTTP/1.1协议版本和状态码101,表示变换协议(Switching Protocol)
- Upgrade 和 Connection:这两个字段是服务器返回的告知客户端同意使用升级并使用websocket协议,用来完善HTTP升级响应
- Sec-WebSocket-Accept:服务器端将加密处理后的握手Key通过这个字段返回给客户端表示服务器同意握手建立连接。
- Sec-Websocket-Procotol:服务器选择的一个应用层协议。
上述响应头字段被客户端浏览器解析,如果验证到Sec-WebSocket-Accept字段的信息符合要求就会建立连接,同时就可以发送WebSocket的数据帧了。如果该字段不符合要求或者为空或者HTTP状态码不为101,就不会建立连接。
- 解析握手请求头:获取握手依据Key并进行处理,检测HTTP的GET请求和版本是否准确,Host字段是否有权限,Upgrade字段中websocket是一个与大小写无关的ASCII字符串,Connection字段是一个大小写无关的"Upgrade"ASCII字符串,Websocket协议版本必须为13,其他的关于Origin、Protocol和Extensions可选。
- 发送握手响应头:检测是否是wss协议连接,如果是就是用TLS握手连接,否则就是普通连接。服务器可以添加额外的验证信息到客户端进行验证。当进行一系列验证之后,服务器必须返回一个有效的HTTP响应头。响应头中每一行一个字段,结束必须为“\r\n”,使用的ABNF语法。
Websocket协议之握手连接的更多相关文章
- Websocket协议数据帧传输和关闭连接
之前总结了关于Websocket协议的握手连接方式等其他细节,现在对socket连接建立后的数据帧传输和关闭细节总结. 一.数据帧格式 数据传输使用的是一系列数据帧,出于安全考虑和避免网络截获,客户端 ...
- 初识WebSocket协议
1.什么是WebSocket协议 RFC6455文档的表述如下: The WebSocket Protocol enables two-way communication between a clie ...
- WebSocket协议
websocket 简介 (2013-04-09 15:39:28) 转载▼ 分类: websocket 一 WebSocket是html5新增加的一种通信协议,目前流行的浏览器都支持这个协议,例 ...
- WebSocket --为什么引入WebSocket协议
Browser已经支持http协议,为什么还要开发一种新的WebSocket协议呢?我们知道http协议是一种单向的网络协议,在建立连接后,它只允许Browser/UA(UserAgent)向WebS ...
- WebSocket协议入门介绍
目录 目录 WebSocket协议是什么 WebSocket是应用层协议 WebSocket与Http的区别 为什么要使用WebSocket 如何使用WebSocket 客户端API 在客户端使用We ...
- WebSocket协议-基础篇
本篇文章主要讲述以下几点: WebSocket协议出现的背景 WebSocket与HTTP WebSocket API WebSocket协议出现的背景 我们在上网过程中经常用到的是HTTP和HTTP ...
- WebSocket协议探究(序章)
一 WebSocket协议基于HTTP和TCP协议 与往常一样,进入WebSocket协议学习之前,先进行WebSocket协议抓包,来一个第一印象. WebSocket能实现客户端和服务器间双向.基 ...
- WebSocket协议中文版
WebSocket协议中文版 摘要 WebSocket协议实现在受控环境中运行不受信任代码的一个客户端到一个从该代码已经选择加入通信的远程主机之间的全双工通信.用于这个安全模型是通常由web浏览器使用 ...
- websocket协议握手详解
最近使用tornado做长链接想着怎么着也要试试websocket协议吧.所以说干就干. 首先要知道websocket是基于http协议的,为什么这么说?因为从协议来说,websocket是借用了一部 ...
随机推荐
- Tomcat配置域名访问
在server.xml文件中的<Host>标签里面添加 <Alias>你的域名(比如:www.baidu.com)</Alias> <Context path ...
- javascript简单笔记
js有一个非常好用的内置处理小数点函数,a.toFixed(2). 调试代码常用:console.log(var); 返回上一级,并重新加载页面 window.location.href = docu ...
- Apache的RewriteRule规则详细介绍
R[=code](force redirect) 强制外部重定向 (rkyW z强制在替代字符串加上http://thishost[:thisport]/前缀重定向到外部的URL.如果code不指定, ...
- GWT 中日期格式化 ,处置Date
GWT的view中不能用java原生的DateFormat 必须使用gwt封装的格式化方法,方法如下 import com.google.gwt.i18n.client.DateTimeFormat; ...
- 关于Arrays类总结
Arrays是java中的工具类,其中所有的方法都是static.类名就可以直接调用其中的方法. 本文部分引用自: http://www.importnew.com/8952.html Arrays. ...
- C语言中 指针和数组
C语言的数组表示一段连续的内存空间,用来存储多个特定类型的对象.与之相反,指针用来存储单个内存地址.数组和指针不是同一种结构因此不可以互相转换.而数组变量指向了数组的第一个元素的内存地址. 一个数组变 ...
- 怎样安装WIN7系统
如何避免win7自动创建200M隐藏分区 1 安装win7到选择安装到哪个分区的时候,不能选择 unallocated diskspace ,也不能选 delete 已有的分区(例如C盘)安全的做法是 ...
- 【转】PL/SQL编辑数据"这些查询结果不可更新,请包括ROWID或使用SELECT...FOR UPDATE获得可更新结果"处理
[转]PL/SQL编辑数据"这些查询结果不可更新,请包括ROWID或使用SELECT...FOR UPDATE获得可更新结果"处理 只要有人用了: select t.* from ...
- Java编写的文本编辑器(菜鸟作品)
//这是主窗体文件 Wordwin.java import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.sw ...
- 【转】JavaScript系列文章:自动类型转换
我们都知道,JavaScript是类型松散型语言,在声明一个变量时,我们是无法明确声明其类型的,变量的类型是根据其实际值来决定的,而且在运行期间,我们可以随时改变这个变量的值和类型,另外,变量在运行期 ...