websocket工作原理

websocket是什么?

websocket是一套类似于http的协议。

扩展:

  http协议:\r\n分割、请求头和请求体\r\n分割、无状态、短连接。

{'GATEWAY_INTERFACE': 'CGI/1.1','SERVER_SOFTWARE': 'gevent/1.4 Python/3.6','SCRIPT_NAME': '',
'wsgi.version': (1, 0),
'wsgi.multithread': False,
'wsgi.multiprocess': False,
'wsgi.run_once': False,
'wsgi.url_scheme': 'http','wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding=
'UTF-8'>,
'SERVER_NAME': 'PC-20180312LANS','SERVER_PORT': '9527','REQUEST_METHOD': 'GET',
'PATH_INFO': '/conn_ws',
'QUERY_STRING': '',
'SERVER_PROTOCOL': 'HTTP/1.1',
'REMOTE_ADDR': '192.168.xx.xxx','REMOTE_PORT': '53449','HTTP_HOST': '192.168.xx.xxx:9527','HTTP_CONNECTION': 'keep-alive',
'HTTP_UPGRADE_INSECURE_REQUESTS': '1','HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121Safari/537.36','HTTP_ACCEPT': 'text/html,
application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8','HTTP_ACCEPT_ENCODING': 'gzip, deflate',
'HTTP_ACCEPT_LANGUAGE': 'zh,en-US;q=0.9,en;q=0.8,zh-CN;q=0.7', 'wsgi.input': <gevent.pywsgi.Input object at 0x0000000003B36C48>, 'wsgi.input_terminated': True,'werkzeug.request': <Request 'http://192.168.11.133:9527/conn_ws' [GET]>}

http协议:

  websocket协议:\r\n分割,创建连接后不断开、验证+数据加密;

{'GATEWAY_INTERFACE': 'CGI/1.1',
'SERVER_SOFTWARE': 'gevent/1.4 Python/3.6','SCRIPT_NAME': '',
'wsgi.version': (1, 0),
'wsgi.multithread': False,
'wsgi.multiprocess': False,
'wsgi.run_once': False,
'wsgi.url_scheme': 'http','wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding=
'UTF-8'>,
'SERVER_NAME': 'PC-20180312LANS','SERVER_PORT': '9527', 'REQUEST_METHOD': 'GET',
'PATH_INFO': '/conn_ws', 'QUERY_STRING': '',
'SERVER_PROTOCOL': 'HTTP/1.1',
'REMOTE_ADDR': '127.0.0.1',
'REMOTE_PORT': '53571','HTTP_HOST': '127.0.0.1:9527',
'HTTP_CONNECTION': 'Upgrade',
'HTTP_PRAGMA': 'no-cache',
'HTTP_CACHE_CONTROL': 'no-cache','HTTP_UPGRADE': 'websocket',
'HTTP_ORIGIN': 'http://localhost:63342',
'HTTP_SEC_WEBSOCKET_VERSION': '13','HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36',
'HTTP_ACCEPT_ENCODING': 'gzip, deflate, br',
'HTTP_ACCEPT_LANGUAGE': 'zh,en-US;q=0.9,en;q=0.8,zh-CN;q=0.7', 'HTTP_SEC_WEBSOCKET_KEY': 'ET/SDQc1sI+uhxm+EjHLcw==', 'HTTP_SEC_WEBSOCKET_EXTENSIONS': 'permessage-deflate; client_max_window_bits',
'wsgi.input': <gevent.pywsgi.Input object at 0x0000000003BC9468>, 'wsgi.input_terminated': True,
'wsgi.websocket_version': '13',

Websocket协议:

  其中主要不同的参数为:

'wsgi.websocket': <geventwebsocket.websocket.WebSocket object at 0x0000000003BC8528>,
'werkzeug.request': <Request 'http://127.0.0.1:9527/conn_ws' [GET]>}

websocket本质:

  就是一个创建连接后不断开的socket,当连接成功之后:

  客户端(浏览器)会自动向服务端发送消息,包含: Sec-WebSocket-Key : jocLOLLq1BQWp0aZgEWL5A==

  通过header_dict["Sec-WebSocket-Key"] = i.split(":")[1].strip()返回一个header_dict字典

  服务端接收之后,会对于该数据进行加密:

value = headers['Sec-WebSocket-Key'] + magic_string
ac = base64.b64encode(hashlib.sha1(value.encode('utf-8')).digest())
其中:
magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11

构造响应头:

1 response_tpl = "HTTP/1.1 101 Switching Protocols\r\n" \
2                "Upgrade:websocket\r\n" \
3                "Connection: Upgrade\r\n" \
4                "Sec-WebSocket-Accept: %s\r\n" \
5                "WebSocket-Location: ws://127.0.0.1:9527\r\n\r\n"

发送客户端(浏览器)

  -建立:双工通道,接下来就可以进行收发数据  

  -发送的数据是经过加密数据,

  -解密根据payload_len的值进行处理:

  -payload_len <= 125

  -payload_len == 126

  -payload_len == 127

  获取内容:

  -mask_key

  数据

  根据mask_key和数据进行位运算,就可以把值解析出来。

 1 hashstr = b'\x81\x83\xceH\xb6\x85\xffz\x85'
 2 # b'\x81    \x83    \xceH\xb6\x85\xffz\x85'
 3 # 将第二个字节也就是 \x83 第9-16位 进行与127进行位运算
 4 # 127二进制为01111111 进行"与"位运算 结果是两个数的最小值
 5 payload = hashstr[1] & 127
 6 print(payload)
 7 if payload == 127:
 8      extend_payload_len = hashstr[2:10]
 9      mask = hashstr[10:14]
10      decoded = hashstr[14:]
11 # 当位运算结果等于127时,则第3-10个字节为数据长度
12 # 第11-14字节为mask 解密所需字符串
13 # 则数据为第15字节至结尾
14
15 if payload == 126:
16      extend_payload_len = hashstr[2:4]
17      mask = hashstr[4:8]
18      decoded = hashstr[8:]
19 # 当位运算结果等于126时,则第3-4个字节为数据长度
20 # 第5-8字节为mask 解密所需字符串
21 # 则数据为第9字节至结尾
22
23 if payload <= 125:
24      extend_payload_len = None
25      mask = hashstr[2:6]
26      decoded = hashstr[6:]
27
28 # 当位运算结果小于等于125时,则这个数字就是数据的长度
29 # 第3-6字节为mask 解密所需字符串
30 # 则数据为第7字节至结尾
31
32 str_byte = bytearray()
33
34 for i in range(len(decoded)):
35      byte = decoded[i] ^ mask[i % 4]
36      str_byte.append(byte)
37
38 print(str_byte.decode("utf8"))

解密:

 1 import struct
 2 msg_bytes = "hello".encode("utf8")
 3 token = b"\x81"
 4 length = len(msg_bytes)
 5
 6 if length < 126:
 7     token += struct.pack("B", length)
 8 elif length == 126:
 9     token += struct.pack("!BH", 126, length)
10 else:
11     token += struct.pack("!BQ", 127, length)
12
13 msg = token + msg_bytes
14
15 print(msg)

加密:

转载于:https://www.cnblogs.com/HakunaMatata-/p/10581278.html

websocket工作原理相关推荐

  1. websocket 工作原理

    自己写一个websocket(教学用) 1 import socket, base64, hashlib 2 3 sock = socket.socket(socket.AF_INET, socket ...

  2. JavaScript 工作原理之五-深入理解 WebSockets 和带有 SSE 机制的HTTP/2 以及正确的使用姿势(译)...

    原文请查阅这里,略有改动,本文采用知识共享署名 4.0 国际许可协议共享,BY Troland. 本系列持续更新中,Github 地址请查阅这里. 这是 JavaScript 工作原理的第五章. 现在 ...

  3. js 数组 实现 完全树_JavaScript的工作原理:解析、抽象语法树(AST)+ 提升编译速度5个技巧

    摘要: JS的"编译原理". 原文:JavaScript的工作原理:解析.抽象语法树(AST)+ 提升编译速度5个技巧 作者:前端小智 Fundebug经授权转载,版权归原作者所有 ...

  4. WebSocket 实现原理

    一.WebSocket是HTML5出的东西(协议),也就是说HTTP协议没有变化,或者说没关系,但HTTP是不支持持久连接的(长连接,循环连接的不算)首先HTTP有1.1和1.0之说,也就是所谓的ke ...

  5. WebSocket 通信原理和详细使用(十六)

    今天我们详细分析WebSocket 通信原理和使用 一.什么是 WebSocket ? WebSocket --一种在 2011 年被互联网工程任务组( IETF )标准化的协议.WebSocket ...

  6. WebRTC源码研究(4)web服务器工作原理和常用协议基础

    文章目录 WebRTC源码研究(4)web服务器工作原理和常用协议基础 前言 做WebRTC 开发为啥要懂服务器开发知识 1. Web 服务器简介 2. Web 服务器的类型 3. Web 服务器的工 ...

  7. Spring的工作原理(一)简介

    Spring的工作原理 有时候面试的时候,面试官:会用Spring么?答:会,我们公司就用的Spring.面试官:Spring怎么进行控制反转的?切面怎么实现的?切面回用于哪一些场景?用到了哪一些设计 ...

  8. 解析ChatGPT背后的工作原理

    点击上方"芋道源码",选择"设为星标" 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | ...

  9. IT:前端进阶技术路线图(初级→中级→高级)之初级(研发工具/HTML/CSS/JS/浏览器)/中级(研发链路/工程化/库/框架/性能优化/工作原理)/高级(搭建/中后台/体验管理等)之详细攻略

    IT:前端进阶技术路线图(初级→中级→高级)之初级(研发工具/HTML/CSS/JS/浏览器)/中级(研发链路/工程化/库/框架/性能优化/工作原理)/高级(搭建/Node/IDE/中后台/体验管理/ ...

最新文章

  1. 需求分析阶段项目经验
  2. 云原生如此重要,可惜80%的人都不知道
  3. Codeforces Round #348 (VK Cup 2016 Round 2, Div. 2 Edition) B. Little Artem and Grasshopper 模拟题...
  4. 使用windbg查看PE结构
  5. mybatis 时间_开发工具:Mybatis.Plus.插件三种方式的逆向工程
  6. Windows单机配置Zookeeper环境
  7. unityscrollview生成大量_superscrollviewforUGUI的一些使用心得
  8. php 合并 js css,PHP实现合并多个JS和CSS文件示例
  9. Java学习之Thread之【Monitor】与【wait】与【notify】与【sleep】_加【Callable】【Executor】【ExecutorService】【Future】
  10. C#基础16:事件与观察者模式
  11. 落后产能的实现路径 | 凌云时刻
  12. 【解决方案】Ehome协议视频融合平台EasyCVR在危化行业的安防监控应用
  13. HLS视频流 H265解码问题处理
  14. WA47电子管麦克风
  15. 利用js制作动态小时钟
  16. CAD图层亮度的设置
  17. Python_pygame库学习笔记(1):pygame的由来,特点以及模块简介
  18. (二)Qt多线程实现海康工业相机图像实时采集
  19. 内外网逻辑隔离物理隔离_隔离域逻辑
  20. 喜讯 | 地空智能荣获两项国家软件著作权证书

热门文章

  1. 一些关于反汇编与逆向方面的博文分享
  2. 无缝滚动—marquee实现向上滚动(适合发布通告)
  3. 拨号到公司网络操作指南
  4. 根据IP查找在交换机上的端口
  5. 牛客寒假6-B.煤气灶
  6. Java 程序员必备的 15 个框架,前 3 个地位无可动摇!
  7. 如何做一个听话的 “输入框”
  8. 重定向、别名、绝对路径、相对路径 详解
  9. [改善Java代码]线程优先级只使用三个等级
  10. Linux学习总结(3)——Linux实用工具