WebSocket协议是基于TCP的一种新的协议。WebSocket最初在HTML5规范中被引用为TCP连接,作为基于TCP的套接字API的占位符。它实现了浏览器与服务器全双工(full-duplex)通信。其本质是保持TCP连接,在浏览器和服务端通过Socket进行通信。

本文将使用Python编写Socket服务端,一步一步分析请求过程!!!

1. 启动服务端

1
2
3
4
5
6
7
8
9
10
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('127.0.0.1'8002))
sock.listen(5)
# 等待用户连接
conn, address = sock.accept()
...
...
...

启动Socket服务器后,等待用户【连接】,然后进行收发数据。

2. 客户端连接

1
2
3
4
<script type="text/javascript">
    var socket = new WebSocket("ws://127.0.0.1:8002/xxoo");
    ...
</script>

当客户端向服务端发送连接请求时,不仅连接还会发送【握手】信息,并等待服务端响应,至此连接才创建成功!

3. 建立连接【握手】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('127.0.0.1'8002))
sock.listen(5)
# 获取客户端socket对象
conn, address = sock.accept()
# 获取客户端的【握手】信息
data = conn.recv(1024)
...
...
...
conn.send('响应【握手】信息')

请求和响应的【握手】信息需要遵循规则:

  • 从请求【握手】信息中提取 Sec-WebSocket-Key
  • 利用magic_string 和 Sec-WebSocket-Key 进行hmac1加密,再进行base64加密
  • 将加密结果响应给客户端

注:magic string为:258EAFA5-E914-47DA-95CA-C5AB0DC85B11

请求【握手】信息为:

+ View Code

提取Sec-WebSocket-Key值并加密:

+ View Code

4.客户端和服务端收发数据

客户端和服务端传输数据时,需要对数据进行【封包】和【解包】。客户端的JavaScript类库已经封装【封包】和【解包】过程,但Socket服务端需要手动实现。

第一步:获取客户端发送的数据【解包】

 基于Python实现解包过程(未实现长内容)

解包详细过程:

+ View Code

The MASK bit simply tells whether the message is encoded. Messages from the client must be masked, so your server should expect this to be 1. (In fact, section 5.1 of the spec says that your server must disconnect from a client if that client sends an unmasked message.) When sending a frame back to the client, do not mask it and do not set the mask bit. We'll explain masking later. Note: You have to mask messages even when using a secure socket.RSV1-3 can be ignored, they are for extensions.

The opcode field defines how to interpret the payload data: 0x0 for continuation, 0x1 for text (which is always encoded in UTF-8), 0x2 for binary, and other so-called "control codes" that will be discussed later. In this version of WebSockets, 0x3 to 0x7 and 0xB to 0xF have no meaning.

The FIN bit tells whether this is the last message in a series. If it's 0, then the server will keep listening for more parts of the message; otherwise, the server should consider the message delivered. More on this later.

Decoding Payload Length

To read the payload data, you must know when to stop reading. That's why the payload length is important to know. Unfortunately, this is somewhat complicated. To read it, follow these steps:

  1. Read bits 9-15 (inclusive) and interpret that as an unsigned integer. If it's 125 or less, then that's the length; you're done. If it's 126, go to step 2. If it's 127, go to step 3.
  2. Read the next 16 bits and interpret those as an unsigned integer. You're done.
  3. Read the next 64 bits and interpret those as an unsigned integer (The most significant bit MUST be 0). You're done.

Reading and Unmasking the Data

If the MASK bit was set (and it should be, for client-to-server messages), read the next 4 octets (32 bits); this is the masking key. Once the payload length and masking key is decoded, you can go ahead and read that number of bytes from the socket. Let's call the data ENCODED, and the key MASK. To get DECODED, loop through the octets (bytes a.k.a. characters for text data) of ENCODED and XOR the octet with the (i modulo 4)th octet of MASK. In pseudo-code (that happens to be valid JavaScript):

var DECODED = "";
for (var i = 0; i < ENCODED.length; i++) {
    DECODED[i] = ENCODED[i] ^ MASK[i % 4];
}

Now you can figure out what DECODED means depending on your application.

第二步:向客户端发送数据【封包】

 View Code

5. 基于Python实现简单示例

a. 基于Python socket实现的WebSocket服务端:

+ View Code

b. 利用JavaScript类库实现客户端

+ View Code

6. 基于Tornado框架实现Web聊天室

Tornado是一个支持WebSocket的优秀框架,其内部原理正如1~5步骤描述,当然Tornado内部封装功能更加完整。

以下是基于Tornado实现的聊天室示例:

 app.py
 index.html

示例源码下载

参考文献:https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers

本文转自武沛齐博客园博客,原文链接:http://www.cnblogs.com/wupeiqi/p/6558766.html,如需转载请自行联系原作者

你真的了解WebSocket吗?相关推荐

  1. websocket如何区分用户_WebSocket与普通Socket的差异

    1.背景 1.1.WebSocket与普通Socket的差异 Socket 简单理解:Socket = IP地址 + 端口 + 协议. 具体来说,Socket是一套标准,它完成了对TCP/IP的高度封 ...

  2. 看完让你彻底搞懂Websocket原理

    2019独角兽企业重金招聘Python工程师标准>>> 本文为转载,尊重原作者的著作版权. 偶然在知乎上看到一篇回帖,瞬间觉得之前看的那么多资料都不及这一篇回帖让我对 websock ...

  3. 看完让你彻底理解 WebSocket 原理,附完整的实战代码(包含前端和后端)

    1.前言 最近有同学问我有没有做过在线咨询功能.同时,公司也刚好让我接手一个 IM 项目.所以今天抽时间记录一下最近学习的内容.本文主要剖析了 WebSocket 的原理,以及附上一个完整的聊天室实战 ...

  4. websocket趣说_转

    websocket协议:https://tools.ietf.org/html/rfc6455 作者:Ovear链接:https://www.zhihu.com/question/20215561/a ...

  5. (转)WebSocket的原理

    前言:无聊逛知乎,就逛到H5的栏目去了,正好看到了关于Websocket的东西.个人是比较喜欢看这类风格的,转到博客分享,以便自己以后理解. ---------------------分割线----- ...

  6. websocket之一:websocket简介

    Websocket websocket为一次HTTP握手后,后续通讯为tcp协议的通讯方式. WebSocket 使用一种被称作"Upgrade handshake(升级握手)"的 ...

  7. socket/WebSocket/WebService/http/https概念

    学习了这么久的java技术, 但是这5个 socket/WebSocket/WebService/http/https  概念还不是很清楚, 总是很模糊,或者是弄混. 惭愧! ! 学习之前, 要对这个 ...

  8. 这里有一篇简单易懂的webSocket 快到碗里来~

    这篇文章是我在学习的时候看到的  刚开始还不是很理解  后来自己百度 又问了一些人  回过头在看这篇文章 真的挺好的 但是原创已经不知道是谁了  转载哦~~~ -------------------- ...

  9. 深刻理解Websocket原理

    原文: http://www.ihorve.com/?p=508 对Websocket一直很懵逼,前端时间在知乎上看到了一篇文章理解了很多. 一.websocket与http WebSocket是HT ...

最新文章

  1. 【网络流24题】解题报告:K、航空路线问题(最小费用最大流)
  2. cocoapods 终极方案
  3. 网页游戏架设_这10年来手机游戏的迭代,也是一部硬件发展史丨触乐
  4. jenkins中Git Parameter Plugin使用
  5. 软件构造学习笔记-实验4
  6. html5新增的type类型,html5新增的type类型
  7. Leviathan系列4-7
  8. Mina Basics 04- 会话
  9. java正则匹配性能,Java正则表达式的性能问题
  10. C语言冒泡排序三种写法,冒泡排序的三种实现方法
  11. 全网首发:gstreamer如何接入RTSP流(IP摄像头)的代码范例
  12. 【JavaScript知识点五】javascript 流程语句
  13. QImage图片裁剪
  14. 【PID优化】基于蝙蝠 粒子群 花卉授粉算法和布谷鸟搜索算法实现热交换器的PI控制器优化
  15. 10kV变电所运维平台的现代化智能构建方案
  16. 什么是 DataSource?什么又是 DruidDataSource?
  17. 文献阅读—GAIN:Missing Data Imputation using Generative Adversarial Nets
  18. 易班php,易班轻应用开发:PHP版
  19. 2022暑期实习网易互娱游戏研发
  20. python 实现问卷星自动填写多份

热门文章

  1. 我自学python的路-Python 学习路线(非常适合小白的入门级教程)
  2. python100行代码-python代码统计 100行
  3. python基础代码事例-学习笔记:python3,代码。小例子习作(2017)
  4. python怎么读取文件-Python中怎么读写文件
  5. 简明python教程购买-简明python教程哪版(python看什么书)
  6. open source license主流的开源软件协议介绍
  7. mybatis中statementHandler的设计与实现
  8. TCP/IP协议:链路层
  9. Gallery的使用(一)
  10. SPOJ - PHRASES Relevant Phrases of Annihilation —— 后缀数组 出现于所有字符串中两次且不重叠的最长公共子串...