WEBSOCKET学习笔记

项目背景

最近在做物联网嵌入式产品,网络协议需要使用到WEBSOCKET协议来通讯,为了实现这个功能,决定用 C语言写一个这个协议,以便在低成本的硬件环境下实现WEBSOCKET通讯功能。

以下内容,多数来自于网络,进行了排版总结。

本文参考文档:
https://www.amobbs.com/thread-5587801-1-1.html?_dsign=7c3738b7
https://www.runoob.com/html/html5-websocket.html
https://baike.baidu.com/item/base64/8545775?fr=aladdin

WEBSOCKET概念

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

Websocket 使用 ws 或 wss 的统一资源标志符,类似于 HTTPS,其中 wss 表示在 TLS 之上的 Websocket。

Websocket 使用和 HTTP 相同的 TCP 端口,可以绕过大多数防火墙的限制。默认情况下,Websocket 协议使用 80 端口;运行在 TLS 之上时,默认使用 443 端口。

WEBSOCKET的握手

WEBSOCKET使用HTTP来握手:

一个握手的例子:

客户端请求:

GET / HTTP/1.1
Upgrade: websocket  //表示希望升级到 Websocket 协议。
Connection: Upgrade  //表示客户端希望连接升级
Host: example.com
Origin: http://example.com //可选的,通常用来表示在浏览器中发起此 Websocket 连接所在的页面

/*
是随机的字符串,服务器端会用这些数据来构造出一个 SHA-1 的信息摘要。把 “Sec-WebSocket-Key” 
加上一个特殊字符串 “258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,然后计算 SHA-1 摘要,之后
进行 BASE-64 编码,将结果做为 “Sec-WebSocket-Accept” 头的值,返回给客户端。如此操作,可
以尽量避免普通 HTTP 请求被误认为 Websocket 协议
*/
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==  


Sec-WebSocket-Version: 13 // 表示支持的 Websocket 版本。RFC6455 要求使用的版本是 13,之前草案的版本均应当弃用。

服务器回应:

HTTP/1.1 101 Switching Protocols   //101代表协议切换成功
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=  //这个是根据Sec-WebSocket-Key算出来的
Sec-WebSocket-Location: ws://example.com/
SHA-1 与 BASE-64 编码:

SHA-1比较复杂,可以直接搜到C语言库来实现

BASE-64 编码规则:
①.把3个字节变成4个字节。
②每76个字符加一个换行符。
③.最后的结束符也要处理。

举例
转换前 11111111, 11111111, 11111111 (二进制)
转换后 00111111, 00111111, 00111111, 00111111 (二进制)
转换后,我们用一个码表来得到我们想要的字符串(也就是最终的Base64编码)

数据通讯

握手完成后就可以数据通讯了,在 WebSocket 协议中,数据使用帧序列来传输。为避免混淆网络中间件(例如拦截代理)和出于安全原因,第 10.3 节进一步讨论,客户端必须掩码(mask)它发送到服务器的所有帧(更多详细信息请参见 5.3 节)。
当收到一个没有掩码的帧时,服务器 必须关闭连接。
服务器必须不掩码发送到客户端的所有帧。如果客户端检测到掩码的帧,它必须关闭连接。

基本帧协议

借用某论坛大神的图与示例数据
WEBSOCKET学习笔记_第1张图片

比如收到一帧数据:
82 8a 2c ab b0 f2 28 af b1 52 9c、ab、b0、f2、2c、ab

那么82 8a代表 fin为1,二进制帧 ,有4个掩护码(2c ab b0 f2) ,数据长度为10

数据为:
28、AF、B1、52、9C、AB、B0、F2、2C、AB。

解码后的数据:
04 (28 ^ 2c)、04 (AF ^ ab)、01 (B1 ^ b0) 、A0 (52 ^ f2)、B0 (9C ^ 2c)、00 (AB ^ AB)、00 ( b0 ^ b0)、00 ( f2 ^ f2)、00 (2c ^ 2c)、00 (AB ^ AB)。

停止通讯

浏览器关闭时多数没有发送关闭帧,而是采用TCP来关闭,除IE浏览器主动发送pong帧保持心跳,其他浏览器采用TCP保持心跳。

你可能感兴趣的:(技术经验,物联网,OCPP协议,websocket)