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是借用了一部 ...
随机推荐
- iOS开发——高级技术&密码锁功能的实现
密码锁功能的实现 一个ios手势密码功能实现 ipad/iphone 都可以用 没有使用图片,里面可以通过view自己添加 keychain做的数据持久化,利用苹果官方KeychainItemWrap ...
- 解决MVC Jquery"此请求已被阻止,因为当用在 GET 请求中时,会将敏感信息透漏给第三方网站"的问题
在ASP.NET MVC项目中,使用AJAX向控制器发送GET请求获取JSON数据时,出现这个错误:"此请求已被阻止,因为当用在 GET 请求中时,会将敏感信息透漏给第三方网站.若要允许 G ...
- java_泛型方法使用实例
//提供两种使用情况,第二种情况定义前者是后者的子类-类型通配方式 package ming; import java.util.ArrayList; import java.util.Collect ...
- if elseif else
1)if,else if需要接判断表达式,只有在满足条件的时候执行而else语句是在前面条件都不满足的时候才能执行(2) 一个if...else if...else语句中可以有多个else if语句, ...
- oracle数据库管理员简介、导入数据与导出数据
数据库管理员: sys和system的权限区别:sys:所有oracle的数据字典的基表和视图都存放在sys用户中,这些基表和视图对于oracle的运行时至关重要的,由数据库 自己维护,任何用户都不能 ...
- VS版本下载
tfs2012:BVGTF-T7MVR-TP46H-9Q97G-XBXRB http://www.microsoft.com/zh-cn/download/details.aspx?id=30658 ...
- Win7:“找不到该项目”错误解决大法
1.将以下代码复制粘贴到一新建的txt记事本文档中,并另存为del.bat文件(或者你喜欢的名字),注意扩展名为批处理文件bat. DEL /F /A /Q \\?\%1RD /S /Q \\?\%1 ...
- Linux下root密码忘记的解决办法
{启动方式} ========================================================================== 一. lilo 1. 在出现 lil ...
- [转载]Ubuntu 14.04设置固定ip
参考链接: ubuntu14.04设置静态ip Ubuntu10.10的网络配置 (总结的比较好些) 由于我的虚拟机中的Ubuntu 14.04中,只安装了一个gitlab,gitlab中配置了固定i ...
- HTTP层 —— 路由
1.基本路由 最基本的 Laravel 路由只接收一个 URI 和一个闭包,并以此提供一个非常简单且优雅的定义路由方法: Route::get('foo', function () { return ...