【python socket】实现websocket服务端
一、获取握手信息
首先通过如下代码,我们使用socket来获取客户端的握手信息
import socketsock = 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对象和地址msg = conn.recv(1024) # 获取客户端的握手信息
print(msg)我们可以通过http://www.websocket-test.com/来作为websocket客户端
当连接上服务端时,服务端打印如下信息

二、格式化websocket请求头
将上述打印信息转为JSON格式:
def get_headers(data):"""将请求头格式化成字典:param data::return:"""header_dict = {}data = str(data, encoding='utf-8')# for i in data.split('\r\n'):# print(i)header, body = data.split('\r\n\r\n', 1)header_list = header.split('\r\n')for i in range(0, len(header_list)):if i == 0:if len(header_list[i].split(' ')) == 3:header_dict['method'], header_dict['url'], header_dict['protocol'] = header_list[i].split(' ')else:k, v = header_list[i].split(':', 1)header_dict[k] = v.strip()return header_dict调用上述方法可以将服务端收到的握手信息转为Json格式:

三、提取key并加密
key = headers_dict["Sec-WebSocket-Key"] # 提取key# 对key进行加密
magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
value = key + magic_string
ac = base64.b64encode(hashlib.sha1(value.encode('utf-8')).digest())
# print(ac)四、将加密的结果返回客户端
# 将加密的结果返回客户端
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://%s%s\r\n\r\n"
response_str = response_tpl % (ac.decode('utf-8'), headers_dict['Host'], headers_dict['url'])
conn.send(response_str.encode("utf-8"))五、和客户端建立连接后的操作
这里建立连接后,将客户端发送的信息再返回给客户端
while True:try:info = conn.recv(8096)except Exception as e:info = Noneif not info:breakpayload_len = info[1] & 127if payload_len == 126:extend_payload_len = info[2:4]mask = info[4:8]decoded = info[8:]elif payload_len == 127:extend_payload_len = info[2:10]mask = info[10:14]decoded = info[14:]else:extend_payload_len = Nonemask = info[2:6]decoded = info[6:]bytes_list = bytearray()for i in range(len(decoded)):chunk = decoded[i] ^ mask[i % 4]bytes_list.append(chunk)body = str(bytes_list, encoding='utf-8')send_msg(conn, body.encode('utf-8'))服务端完整代码
实现了服务端接收与发送的分离;
当服务端接收到指定字符串时("exit"),服务端主动断开连接。
import socket,base64,hashlib,time,threadingdef get_headers(data):"""将请求头格式化成字典:param data::return:"""header_dict = {}data = str(data, encoding='utf-8')# for i in data.split('\r\n'):# print(i)header, body = data.split('\r\n\r\n', 1)header_list = header.split('\r\n')for i in range(0, len(header_list)):if i == 0:if len(header_list[i].split(' ')) == 3:header_dict['method'], header_dict['url'], header_dict['protocol'] = header_list[i].split(' ')else:k, v = header_list[i].split(':', 1)header_dict[k] = v.strip()return header_dictdef send_msg(conn, msg_bytes):"""WebSocket服务端向客户端发送消息:param conn: 客户端连接到服务器端的socket对象,即: conn,address = socket.accept():param msg_bytes: 向客户端发送的字节:return:"""import structtoken = b"\x81"length = len(msg_bytes)if length < 126:token += struct.pack("B", length)elif length <= 0xFFFF:token += struct.pack("!BH", 126, length)else:token += struct.pack("!BQ", 127, length)msg = token + msg_bytesconn.send(msg)return Truedef recv_msg(conn):while True:try:info = conn.recv(8096)except Exception as e:info = Noneif not info:breakpayload_len = info[1] & 127if payload_len == 126:extend_payload_len = info[2:4]mask = info[4:8]decoded = info[8:]elif payload_len == 127:extend_payload_len = info[2:10]mask = info[10:14]decoded = info[14:]else:extend_payload_len = Nonemask = info[2:6]decoded = info[6:]bytes_list = bytearray()for i in range(len(decoded)):chunk = decoded[i] ^ mask[i % 4]bytes_list.append(chunk)global bodybody = str(bytes_list, encoding='utf-8')print(body)if body == "exit":conn.close()breaksock = 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对象和地址data = conn.recv(1024) # 获取客户端的握手信息
headers_dict = get_headers(data)
key = headers_dict["Sec-WebSocket-Key"] # 提取key# 对key进行加密
magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
value = key + magic_string
ac = base64.b64encode(hashlib.sha1(value.encode('utf-8')).digest())
# print(ac)# 将加密的结果返回客户端
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://%s%s\r\n\r\n"
response_str = response_tpl % (ac.decode('utf-8'), headers_dict['Host'], headers_dict['url'])
conn.send(response_str.encode("utf-8"))# 和客户端建立连接后的操作# 启动接收客户端信息的线程
thread_obj = threading.Thread(target=recv_msg, args=(conn,))
thread_obj.daemon = True
thread_obj.start()# 不断给客户端发送信息
while True:if getattr(conn, "_closed") == False: # 客户端没有关闭send_msg(conn, str("你好").encode('utf-8'))time.sleep(1)else: # 客户端关闭break参考视频链接:https://www.bilibili.com/video/BV1tf4y1K7Ww?p=8&spm_id_from=pageDriver&vd_source=36a3e35639c44bb339f59760641390a8
参考文章:https://www.cnblogs.com/wupeiqi/p/6558766.html
相关文章:
【python socket】实现websocket服务端
一、获取握手信息首先通过如下代码,我们使用socket来获取客户端的握手信息import socketsock 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.li…...
PANGO的CFG那些事
先来看位于VCCIOCFG这个bank上引脚, MODE JTAG时,MODExxx. except 3’b000. 禁止设置为3’b000. Slave Parallel时,MODE 3’b110,不常用。 Slave Serial时,MODE 3’b111,不常用。 Master SPI 时&…...
路由协议(OSPF、ISIS、BGP)实验配置
目录 OSPF基础实验 建立OSPF邻居 配置虚连接 配置接口的网络类型 配置特殊区域 配置路由选路 配置路由过滤 ISIS基础实验配置 配置ISIS邻居建立 配置认证 配置路由扩散 配置路由过滤 配置定时器 BGP基础实验配置 建立BGP对等体 建立IBGP对等体 建立EBGP对等体…...
Python可变对象与不可变对象的浅拷贝与深拷贝
前言 本文主要介绍了python中容易面临的考试点和犯错点,即浅拷贝与深拷贝 首先,针对Python中的可变对象来说,例如列表,我们可以通过以下方式进行浅拷贝和深拷贝操作: import copya [1, 2, 3, 4, [a, b]]b a …...
滑模控制(Sliding mode control)快速入门
0. 简介 最近作者受到邀请,让我帮忙给刚入门的学弟讲讲滑模控制。可是作者也不知道怎么向未入门的学弟讲解这些基础知识,所以作者翻了翻近几年写的很好的文章以及视频。综合起来,来总结出一套比较基础,且适用于初学者的文章吧。这…...
golang的垃圾回收详解
golang的垃圾回收详解 一、三色标记法 作为一门现代化的语言,golang与java一样,都在语言中内置了垃圾回收的功能,不需要程序员自己去回收堆内存。而垃圾回收中,最重要的两个部分就是垃圾检测算法以及垃圾回收算法。垃圾检测算法决…...
线上负载过高排查(top/vmstat/ifstat/free/df)
目录 一、五大命令 二、故障排查步骤 1、top命令找出CPU占比最高的 2、ps -ef 或者 jps -l进一步定位 3、ps -mp位到具体线程或者代码 4、jstack精准定位到错误的地方 本文通过学习:周阳老师-尚硅谷Java大厂面试题第二季 总结的LinuxJDK命令操作相关的笔记 一…...
Java的注解(Annotation)
Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。Java 中的类、构造器、方法、成员变量、参数等都可以被注解进行标注。例如JUnit单元测试中的Test方法,可以使得方法直接运行。JUnit单元测试Test单元测试是针…...
信息系统项目管理师:配置管理
配置管理指的是在一个系统或软件中对配置项的管理,包括对配置项的定义、存储、跟踪和修改等一系列活动。配置项可以是硬件设备、软件组件、系统设置、网络配置等,配置管理旨在确保在不同时间点或环境下系统或软件的配置项的正确性和一致性。通过配置管理…...
web餐饮开源程序
简介 一款专门针对餐饮行业而开发桌面应用程序 技术 借助Panuon.UI.Silver控件库,开发的一款餐饮软件。 运行环境:.NETFramework,Versionv4.8。 运行数据库:MySql。 ORM框架:SqlSugar。 第三方插件:Panuon.UI.Silv…...
28个案例问题分析---027---单表的11个Update接口--MyBatis
一:背景介绍 项目开发中。我们使用的是MyBatis,在MyBatis的xml文件里,两个表的更新功能,写了足足11个更新接口,毫无复用的思想 这种方式可以正常的实现功能,但是没有复用,无论是从时间上还是维…...
大数据开发治理平台 DataWorks
序言学习下阿里DataWorks的设计理念以及要做的事情cuiyaonan2000163.com参考文档:https://www.aliyun.com/product/bigdata/idehttps://help.aliyun.com/document_detail/73015.htmlhttps://help.aliyun.com/document_detail/324149.html ----数据治理LaunchDataWorks基于阿里云…...
Xshell的下载、使用、配置【ssh、telnet、串口】
目录 一、概述 二、Xshell的使用 2.1 Xshell使用ssh协议远程连接Linux主机或服务器 2.2 Xshell使用telnet协议远程连接Linux开发板 2.3 Xshell使用SERIAL协议远程连接Linux开发板 三、Xshell常用配置 3.1 配置默认会话属性 一、概述 Xshell是由NetSarang公司开发的强大…...
C++回顾(七)—— 面向对象模型
7.1 静态成员变量和静态成员函数 7.1.1 静态成员变量 关键字 static 可以用于说明一个类的成员;静态成员提供了一个同类对象的共享机制;把一个类的成员说明为 static 时,这个类无论有多少个对象被创建,这些对象共享这个 static …...
开源监控服务uptime-kuma
好久没写文章了,刚好最近用了一个开源的监控服务,感觉蛮有意思的,记录一下 (一)安装 uptime-kuma安装方式有几种,这里当然是选择大家都爱的docker,一条命令搞定 docker run -d --restartalways -p 3001:…...
JavaScript混淆技术:了解其核心原理和常用手段
当今互联网时代,JavaScript已经成为了web前端开发的重点技术之一。其中,JavaScript代码的安全性问题一直是关注的焦点。为了保护JavaScript代码的安全性,很多人对其进行加密处理,众所周知,对于单纯的加密算法ÿ…...
大型医院云HIS系统:采用前后端分离架构,前端由Angular语言、JavaScript开发;后端使用Java语言开发 融合B/S版电子病历系统
一套医院云his系统源码 采用前后端分离架构,前端由Angular语言、JavaScript开发;后端使用Java语言开发。融合B/S版电子病历系统,支持电子病历四级,HIS与电子病历系统均拥有自主知识产权。 文末卡片获取联系! 基于云计…...
SAP UI5 Upload/Download file through NetWeaver Gateway
1、创建 SEGW对象 2、创建Entity Type 要把Media 标识打上 3、 激活对象然后到DPC Class的扩展对象里面重定义 /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_STREAM /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_STREAM /IWBEP/IF_MGW_APPL_SRV_RUNTIME~UPDATE_STREAM METHOD /iwbep/if_m…...
opencv校正图像
目录1、前言2、例程2.1、代码2.2、效果口罩说明书网页3、按步骤分析转灰度图降噪 Canny边缘检测膨胀(可视具体情况省略)轮廓检索选取角度1、前言 我们用相机拍照时,会因为角度问题造成拍歪,会影响图像的识别,这时就需…...
JavaScript:函数与箭头函数的区别
ref 1. 定义 函数 function getName() {}箭头函数 const getName () > {}2. 命名 函数分为匿名、具名。 function getName() {} let getName function () {}箭头函数只有匿名。 const getName () > {}3. 构造函数 箭头函数都是匿名函数,所以不能作为构造…...
Qwen2.5-VL-7B-Instruct保姆级:SSH远程部署+ngrok内网穿透共享演示
Qwen2.5-VL-7B-Instruct保姆级:SSH远程部署ngrok内网穿透共享演示 想不想在远程服务器上部署一个能“看图说话”的AI助手,还能随时随地通过网页访问它?今天,我就带你手把手搞定这件事。 我们将一起完成两个核心任务:…...
分解+组合+RUL预测!MVMD-Transformer-BiLSTM锂电池剩余寿命预测(容量特征提取+剩余寿命预测)
这段代码实现了一套完整的基于MVMD-Transformer-BiLSTM的电池剩余寿命预测:一、研究背景 锂离子电池在长期充放电循环中会发生容量衰减,准确预测其剩余使用寿命(RUL)对设备健康管理、安全保障与运维决策至关重要。传统预测方法常受…...
抖音内容高效下载实战:从单视频到批量采集的完整指南
抖音内容高效下载实战:从单视频到批量采集的完整指南 【免费下载链接】douyin-downloader 项目地址: https://gitcode.com/GitHub_Trending/do/douyin-downloader 还在为无法保存喜欢的抖音内容而烦恼吗?是否经常遇到需要批量下载用户主页所有作…...
Keil uVision5与STC8H单片机开发实战:手把手教你搭建第一个项目
Keil uVision5与STC8H单片机开发实战:从零搭建完整项目框架 作为一名长期从事嵌入式开发的工程师,我深知初学者在迈出第一步时面临的困惑。本文将带你完整走一遍STC8H单片机在Keil uVision5环境下的项目搭建流程,不仅包含基础操作,…...
OpenClaw移动端适配:手机飞书调用Qwen3-VL:30B的优化技巧
OpenClaw移动端适配:手机飞书调用Qwen3-VL:30B的优化技巧 1. 移动端适配的痛点与挑战 上周我在星图平台部署了Qwen3-VL:30B模型,并通过OpenClaw接入了飞书。当我在办公室用电脑测试时一切正常,但周末带孩子去公园时想用手机处理工作&#x…...
如何实现高效无水印视频批量下载?TikTokDownload工具全攻略
如何实现高效无水印视频批量下载?TikTokDownload工具全攻略 【免费下载链接】TikTokDownload 抖音去水印批量下载用户主页作品、喜欢、收藏、图文、音频 项目地址: https://gitcode.com/gh_mirrors/ti/TikTokDownload 在数字内容创作与素材收集的过程中&…...
铜钟音乐:告别广告与社交干扰的纯净听歌工具
铜钟音乐:告别广告与社交干扰的纯净听歌工具 【免费下载链接】tonzhon-music 铜钟 (Tonzhon.com): 免费听歌; 没有直播, 社交, 广告, 干扰; 简洁纯粹, 资源丰富, 体验独特!(密码重置功能已回归) 项目地址: https://gitcode.com/GitHub_Trending/to/ton…...
AIGlasses_for_navigation视频处理应用:使用AE制作导航效果演示片段视频
AIGlasses_for_navigation视频处理应用:使用AE制作导航效果演示片段视频 你有没有想过,那些看起来科技感十足、路径光效流畅的AR导航演示视频是怎么做出来的?是不是觉得需要专业的动画团队才能实现? 其实,借助像Afte…...
如何用G-Helper智能恢复ROG笔记本色彩显示:终极解决方案
如何用G-Helper智能恢复ROG笔记本色彩显示:终极解决方案 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other models 项目地…...
Windows安全中心总提示驱动不兼容?手把手教你清理老旧驱动,为内存完整性扫清障碍
Windows驱动深度清理指南:彻底解决内存完整性兼容性问题 每次打开Windows安全中心,那个刺眼的"驱动不兼容"提示总让人心烦?这不仅仅是烦人的弹窗问题,更是系统安全与性能的潜在威胁。作为长期使用Windows的资深用户&…...
