一.POOL

Pool就是为了多线程访问数据库,减少数据库压力

回顾pymysql

import pymysql
#建立连接
mysql_conn = pymysql.connect(host="127.0.0.1",
port=3306,
user="root",
password="",
charset="utf8",
db="day115")
#创建游标
c = mysql_conn.cursor(cursor=pymysql.cursors.DictCursor) sql = "select * from users WHERE name='jwb' and age=73 "
# 光标执行sql
# res为生成几行
res = c.execute(sql) #获取结果
print(c.fetchall()) c.close()
mysql_conn.close()

创建POOL

import pymysql
from DBUtils.PooledDB import PooledDB
POOL = PooledDB(
creator=pymysql, # 使用链接数据库的模块
maxconnections=6, # 连接池允许的最大连接数,0和None表示不限制连接数
mincached=2, # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
maxcached=5, # 链接池中最多闲置的链接,0和None不限制
maxshared=3, # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
blocking=True, # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
maxusage=None, # 一个链接最多被重复使用的次数,None表示无限制
setsession=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
ping=0,
# ping MySQL服务端,检查是否服务可用。
# 如:0 = None = never,
# 1 = default = whenever it is requested,
# 2 = when a cursor is created,
# 4 = when a query is executed,
# 7 = always
host="127.0.0.1",
port=3306,
user="root",
password="",
charset="utf8",
db="day115"
) #
# conn = POOL.connection() # pymysql - conn
# cur = conn.cursor(cursor=pymysql.cursors.DictCursor)
#
# sql = "select * from users WHERE name='jwb' and age=73 "
#
# res = cur.execute(sql)
#
#
# print(cur.fetchall())
#
# conn.close()

执行线程池

from dbpool import POOL
import pymysql def create_conn():
conn = POOL.connection()
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) return conn,cursor def close_conn(conn,cursor):
cursor.close()
conn.close() def insert(sql,args):
conn,cursor = create_conn()
res = cursor.execute(sql,args)
conn.commit()
close_conn(conn,cursor)
return res def fetch_one(sql,args):
conn,cursor = create_conn()
cursor.execute(sql,args)
res = cursor.fetchone()
close_conn(conn,cursor)
return res def fetch_all(sql,args):
conn,cursor = create_conn()
cursor.execute(sql,args)
res = cursor.fetchall()
close_conn(conn,cursor)
return res # sql = "insert into users(name,age) VALUES (%s, %s)" # insert(sql,("mjj",9)) sql = "select * from users where name=%s and age=%s" print(fetch_one(sql,("mjj",9)))

二.socket握手

就是在客户端请求头中获取Sec-WebSocket-Key与宝藏magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'进行匹配

当与客户端验证成功后就已经进行了握手

import socket, base64, hashlib

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('127.0.0.1', 9527))
sock.listen(5)
# 获取客户端socket对象
conn, address = sock.accept()
# 获取客户端的【握手】信息
data = conn.recv(1024)
print(data)
"""
GET /ws HTTP/1.1\r\n
Host: 127.0.0.1:9527\r\n
Connection: Upgrade\r\n
Pragma: no-cache\r\n
Cache-Control: no-cache\r\n
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36\r\n
Upgrade: websocket\r\n
Origin: http://localhost:63342\r\n
Sec-WebSocket-Version: 13\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n
Cookie: session=a6f96c20-c59e-4f33-84d9-c664a2f29dfc\r\n
Sec-WebSocket-Key: MAZZU5DPIxWmhk/UWL2+BA==\r\n #这个就是那把钥匙
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n\r\n
"""
# 以下动作是有websockethandler完成的
# magic string为:258EAFA5-E914-47DA-95CA-C5AB0DC85B11 def get_headers(data): #在获取的data列表中通过分割获取Sec-WebSocket-Key
header_dict = {}
header_str = data.decode("utf8")
for i in header_str.split("\r\n"):
if str(i).startswith("Sec-WebSocket-Key"):
header_dict["Sec-WebSocket-Key"] = i.split(":")[1].strip() return header_dict headers = get_headers(data) # 提取请求头信息
#
magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
#Sec-WebSocket-Key: MAZZU5DPIxWmhk/UWL2+BA==
value = headers['Sec-WebSocket-Key'] + magic_string
print(value)
#将钥匙Sec-WebSocket-Key和宝藏magic_string进行加密
ac = base64.b64encode(hashlib.sha1(value.encode('utf-8')).digest()) # 对请求头中的sec-websocket-key进行加密
response_tpl = "HTTP/1.1 101 Switching Protocols\r\n" \
"Upgrade:websocket\r\n" \
"Connection: Upgrade\r\n" \
"Sec-WebSocket-Accept: %s\r\n" \
"WebSocket-Location: ws://127.0.0.1:9527\r\n\r\n"
print(ac.decode('utf-8'))
response_str = response_tpl % (ac.decode('utf-8'))
# 响应【握手】信息
conn.send(response_str.encode("utf8"))
#
while True:
msg = conn.recv(8096)
print(msg)

需要在前端中访问

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body> </body>
<script type="application/javascript">
var ws = new WebSocket("ws://127.0.0.1:9527/ws"); </script>
</html>

发现,在前端发送的数据vm.send("abc)发到后端的数据是加密的,需要进行解密

解密方法

比如发送到服务端的是

b'\x81\x83H\xc0x\xa6y\xf2K'

第一个为统一的的\x81,用它的后一位与127求^,结果分三种 小于等于125,126,127
然后根据后面的数据长度/密码/数据/进行解密
#b'\x81\x89\xf3\x99\x81-\x15\x05\x01\xcbO\x1be\x97]'
#b'\x81\x85s\x92a\x10\x1b\xf7\r|\x1c'
#b'\x81\x83H\xc0x\xa6y\xf2K' hashstr = b'\x81\x85s\x92a\x10\x1b\xf7\r|\x1c'
# b'\x81 \x85s \x92a\x10\x1b\xf7 \r|\x1c' <126
# \x85s = 5
hashstr = b'\x81\xfe\x02\xdc\x8d\xe8-\xb2hm\xa5W5u\xc8:\x16\x0c\x95(kt\x87W\x00b\xc52\x01\x0c\x95\x1fdi\xbeW9A\xcb\x1c\x0f\x07\x91>iS\xa7W)A\xc9\n\x06\x0c\x95;h`\xab]1d\xca)\x07\r\x9a,j~\x9fW1b\xc2\x0e\x01\x0e\x80\x16eG\xb7W\x00Y\xcb2(\r\x80*iR\x8cV4c\xca\x15\x06\x0c\x94-nh\xafU\t^\xc9\x0c\x00\r\xa0\x19iQ\xa6Z\nK\xc9\n\x00\x0e\xaa:iR\xa3W\x0bm\xc2\x0e\x01\r\x92\x12hW\xbaV4c\xc8\x11&\r\x92*eR\x86V7f\xc8\x16\x1b\x00\xad7bT\xa1U\x16~\xc5\r0\r\xa8:hP\xb0V4c\xcb\x1c\x07\x01\xac5bT\xa1T!Z\xcb8(\x0c\x949iR\xa3[\x14s\xc9\n\x06\x0c\x94-nh\xafZ"r\xc8\x1c\x11\r\x912hT\x8dW\x11K\xc8"!\x07\x91>iS\x88W\x08a\xc87\x05\r\x95/di\xbaW3_\xc2\x0e\x01\x0e\xac\x10hT\xb5W2\x7f\xc8\x11&\x0c\x949kX\xb9]1d\xc9\n\x00\r\x83.hN\xa9Z\nB\xc5=?\x00\xbb6bT\xa1W1}\xc8$6\r\x89\x03iQ\xa4]1d\xc9\t(\r\x8c,hW\x8dZ=g\xc9\x0b\x06\x00\x9a\x1diQ\xb2Q\rj\xc8\x1c&\x0c\x95\x1fhR\xb1V5E\xc2\x0e\x01\x0c\x92\x03iP\x97V5h\xc9\x0f\x1e\x07\x91>dq\xb2U0r\xc55*\r\xbd\x14bT\xa1V5e\xc8\x1c\x11\r\x910hx\xa1Q\rj\xc59(\x0e\xb1;iU\xb1W(P\xca8"\x0f\x8a#hg\xa7V5R\xc8\r-\r\xbb6eh\xa8]1d\xc8\x1c\x11\x0c\x96*kt\xa4W\x02P\xc5\x1c7\r\xa8\x04h`\xbcZ8g\xc2\x0e\x01\x0c\x96\x17kp\x80[\x14s\xc9\n\x06\r\x94\x01kp\xa3V4c\xca"\x0b\x07\x91>iP\xa0W#t\xc83\x02\x0f\x8a3bT\xa1V0W\xc84\x08\r\x89$hT\xafT>}\xc9\x0b\x12\x0b\xad0iV\xa0V5E\xce2\x0c\x0c\x93?dk\xa3[\x0eE\xcb&5\x0c\x949nh\xacZ9Q\xca\x17\x03\x0b\xad3ey\x8eW\x08i\xca\x1f\x04\x07\x91>kE\x89U\x17n\xc5;"\r\x83,bT\xa1W2\x7f\xc5+\x1c\r\x92\x12jR\x82]1d\xcb*"\x0c\x96\x17hm\xa5W5u\xca\x1c\r\x0e\xa6&iS\x88[\x0c\x7f\xc4+\x16\x0c\x959nh\xafT\tr\xc9\t(\x0c\x95\x08hF\x86V5E\xc9\x0b\x06\x0c\x979bT\xa1V7c\xcb%-\r\x89\x15hX\xa2]1d\xcb0\x04\x0c\x96\x17hz\x85V4c\xc2\x0e\x01\x0f\xa9\x04hx\xa3T\x1bU\xc5\x13\x01\x07\x91>hW\xa8Z\x0eU\xc5\x11%\x00\x8c\x17dp\xb4T1g\xc2\x0e\x01\x0e\xb1;ka\xadW4W\xca)\x07\x0b\xad0'
# print(chushibiao[1],chushibiao[1]&127)
# print(chushibiao[2:4],chushibiao[4:8])
# 将第二个字节也就是 \x83 第9-16位 进行与127进行位运算
payload = hashstr[1] & 127
print(payload)
if payload == 127:
extend_payload_len = hashstr[2:10]
mask = hashstr[10:14]
decoded = hashstr[14:]
# 当位运算结果等于127时,则第3-10个字节为数据长度
# 第11-14字节为mask 解密所需字符串
# 则数据为第15字节至结尾 if payload == 126:
extend_payload_len = hashstr[2:4]
mask = hashstr[4:8]
decoded = hashstr[8:]
# 当位运算结果等于126时,则第3-4个字节为数据长度
# 第5-8字节为mask 解密所需字符串
# 则数据为第9字节至结尾 if payload <= 125:
extend_payload_len = None
mask = hashstr[2:6]
decoded = hashstr[6:] # 当位运算结果小于等于125时,则这个数字就是数据的长度
# 第3-6字节为mask 解密所需字符串
# 则数据为第7字节至结尾 str_byte = bytearray()
# b'\x81 \x85s \x92a\x10\x1b \xf7\r|\x1c' <126
for i in range(len(decoded)): # 0 \xf7 ^ \x92a 1 \r ^ \x10 \x1c ^ \x1b
byte = decoded[i] ^ mask[i % 4]
str_byte.append(byte) print(str_byte.decode("utf8"))

加密方法:

import struct
msg_bytes = "the emperor has not been half-baked in the early days of the collapse of the road, today down three points, yizhou weakness, this serious crisis autumn".encode("utf8")
token = b"\x81" # + 数据长度/运算位 + mask/数据长度 + mask/数据 + 数据
length = len(msg_bytes) if length < 126:
token += struct.pack("B", length)
elif length == 126:
token += struct.pack("!BH", 126, length)
else:
token += struct.pack("!BQ", 127, length) msg = token + msg_bytes print(msg)

flask POOL,websocket握手的更多相关文章

  1. Flask 实现 WebSocket 通讯---群聊和私聊

    一.WebSocket介绍 WebSocket是一种在单个TCP连接实现了服务端和客户端进行双向文本或二进制数据通信的一种通信的协议. WebSocket使得客户端和服务器之间的数据交换变得更加简单, ...

  2. flask使用websocket

    # flask使用websocket 1.概述 flask实现websocket有两种方式:flask_sockets,Flask-SocketIO. flask_sockets:该方式是flask对 ...

  3. 探讨Netty获取并检查Websocket握手请求的两种方式

    在使用Netty开发Websocket服务时,通常需要解析来自客户端请求的URL.Headers等等相关内容,并做相关检查或处理.本文将讨论两种实现方法. 方法一:基于HandshakeComplet ...

  4. 使用 Sa-Token 解决 WebSocket 握手身份认证

    前言 相比于 Http 的单项通信方式,WebSocket 可以从服务器向浏览器主动推送消息,这一特性可以帮助我们完成诸如 订单消息推送.IM实时聊天 等一些特定业务. 然而 WebSocket 本身 ...

  5. node.js 使用 net 模块模拟 websocket 握手,进行数据传递。

    websocket 是一种让浏览器与服务器之间建立持久的连接,并能进行双向数据传输的一种协议. websocket 属性应用层协议,基于tcp传输协议,并复用http的握手通道. 一.如何进行webs ...

  6. WebSocket握手总结

    网址:http://blog.csdn.net/edwingu/article/details/44040961 WebSocket protocol 是HTML5一种新的协议.它实现了浏览器与服务器 ...

  7. Flask基于websocket的简单聊天室

    1.安装gevent-websocket pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ gevent-websocket 2.cha ...

  8. Flask实现websocket

    from flask import Flask,request user_socket_dict = {} app = Flask(__name__) @app.route("/conn_w ...

  9. python模拟websocket握手过程中计算sec-websocket-accept

    背景 以前,很多网站使用轮询实现推送技术.轮询是在特定的的时间间隔(比如1秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给浏览器.轮询的缺点很明显,浏览器需要不断的向服 ...

随机推荐

  1. 非阻塞式I/O

    套接字的默认状态是阻塞的.这就意味着当发出一个不能立即完成的套接字调用时,其进程将被投入睡眠,等待相应的操作完成.可能阻塞的套接字调用可分为以下4类 (1)输入操作,包括read,readv,recv ...

  2. day67_10_11

    一.路由跳转 在vue中,路由条状有很多种. 其中有点击事件触发的路由跳转: this.$router.push('/course'); 和通过名字跳转的: this.$router.push({na ...

  3. day45_9_4前端(2)css

    一.css的三种css导入: 1.在标签中内部定义(不推荐). 2.在head中的style总定义样式. 3.使用link链接外部的css文件. <!DOCTYPE html> <h ...

  4. 《LSM算法原理》

    记内存中的树为T0, 硬盘上的树按时间顺序,记做T1, ..., Tk 读: T0 Tk -> Tk-1 -> ... -> T0 写 T0 T0超过一定大小后,插入硬盘变为Tk+1 ...

  5. 解决angular单页面页面底部跳转到新页面滚动条不在顶部的问题

    以上jquery,下面js this.router.events.subscribe((event) => { document.body.scrollTop=0; }); 另一种写法 impo ...

  6. 【BZOJ3876】[AHOI2014&JSOI2014] 支线剧情(无源汇有上下界网络流)

    点此看题面 大致题意: 有一张\(DAG\),经过每条边有一定时间,从\(1\)号点出发,随时可以返回\(1\)号点,求经过所有边的最短时间. 无源汇有上下界网络流 这是无源汇有上下界网络流的板子题. ...

  7. Paper | Model-blind video denoising via frame-to-frame training

    目录 故事 本文方法 流程 训练 实验 发表在2019年CVPR. 核心内容:基于Noise2Noise思想,这篇文章致力于无监督的视频盲去噪:是的,连噪声样本都不需要了. 这篇文章写作和概括太棒了! ...

  8. ASP.NET Core快速入门(第2章:配置管理)- 学习笔记(转载)

    原文地址:https://mp.weixin.qq.com/s?__biz=MjM5NjMzMzE2MA==&mid=2451733443&idx=2&sn=6d01721c5 ...

  9. 大话设计模式Python实现-备忘录模式

    备忘录模式(Memento Pattern):不破坏封装性的前提下捕获一个对象的内部状态,并在该对象之外保存这个状态,这样已经后就可将该对象恢复到原先保存的状态 下面是一个备忘录模式的demo: #! ...

  10. 行为驱动:Cucumber + Java - 实现数据的参数化

    1.什么是参数化 实际设计测试用例过程中,我们经常会用等价类.边界值这样的方法,针对一个功能进行测试数据上的测试,比如一个输入框,正向数据.逆向数据,非法输入等等 2.Cucumber的数据驱动 同上 ...