socketserver模块使用 & websocket
socketserver:
socketserver可用于实现并发通信。
socketserver 模块简化了编写网络服务程序的任务;同时 SocketServer 模块也是 Python标准库中很多服务器框架的基础。
socketserver 模块可以简化网络服务器的编写。Python把网络服务抽象成两个主要的类,一个是 Server 类,用于处理连接相关的网络操作,另外一个则是 RequestHandler 类,用于处理数据相关的操作;并且提供了两个Mixin类,用于扩展 Server,实现多进程或多线程。
Server 类:
它包含了种五种server类,BaseServer(不直接对外服务)。TCPServer使用TCP协议,UDPServer使用UDP协议,还有两个不常使用的,
即UnixStreamServer和UnixDatagramServer,这两个类仅仅在unix环境下有用(AF_unix)。
RequestHandler类:
所有requestHandler都继承BaseRequestHandler基类。
注: 全双工管道通信:既可以 收,也可以 发
单工、半双工和全双工的区别: https://blog.csdn.net/starstar1992/article/details/53032409
socketserver 的使用方法:
import socketserver """
socketserver: 基于多线程实现的并发通信
sockerserver 使用方法(固定套路):
1. 定义功能类
class MyServer(socketserver.BaseRequestHandler):
def handler(self):
pass 2. server = socketserver.threadingTCPServer(("127.0.0.1",8800),MyServer) 3. server.server_forerver()
""" class MyServer(socketserver.BaseRequestHandler): # 必须要继承 socketserver.BaseRequestHandler 这个类 def handler(self): # 必须要有 handler() 这个方法
"""
handler() 方法里面要放并发的业务逻辑
该方法下的 self.request 也是固定写法,是一个套接字对象,即相当于 以前 socket 时的 conn
"""
# 写自己的业务逻辑
pass # 通过 socketserver 引一个要 并发的类
server = socketserver.ThreadingTCPServer(("127.0.0.1",8800),MyServer) # 第一个参数:IP和端口,第二个参数:要实例化的 功能类;threadingTCPServer 这个类是通过 多线程 帮我们实现的并发;用的是 TCP 协议
# server = socketserver.ForkingTCPServer(("127.0.0.1",8800),MyServer) # 多进程 TCP 通信
server.server_forerver()
websocket:
websocket 其实就是 web socket,它也是一种协议 http 的问题:
1. http 是一个协议
- 数据格式
- 一次请求和响应之后断开连接(无状态、短连接)
2. 服务端不可以向客户端主动推送消息(因为不知道客户端的IP端口)
3. 服务端只能做出响应
4. 为了伪造服务端向客户端主动推送消息的效果,我们使用:轮询和长轮询 websocket 是一种新的协议: 1. 连接时需要握手;2.发送数据进行加密;3.连接之后不断开; websocket 解决了 服务端能够真正向客户端推送消息;缺点:兼容性
- 数据格式:
- 连接请求: http协议
- 收发请求: websocket协议
- 不断开连接 基于 flask的websocket示例:
# 安装:
pip install gevent-websocket 支持 websocket 的框架:
所有框架都支持,但是,
flask : gevent-websocket
django:channel
tornado 框架自带 websocket 应用场景:实时响应
基于 flask 和 websocket 实现一个在线投票功能:
app.py
from flask import Flask,render_template,request
import json # 使用 websocket 时 需要导入下面的两个模块
from geventwebsocket.handler import WebSocketHandler
from gevent.pywsgi import WSGIServer # 发送 websocket 请求得通过 js 来实现 app = Flask(__name__) USERS = {
'':{'name':'钢弹','count':0},
'':{'name':'铁锤','count':0},
'':{'name':'贝贝','count':100},
} # http://127.0.0.1:5000/index # 浏览器在渲染 index.html 时,在执行 var ws = new WebSocket('ws://192.168.13.253:5000/message') 这句js代码时,客户端就会和服务端建立一个 websocket 的连接
@app.route('/index')
def index():
return render_template('index.html',users=USERS) # http://127.0.0.1:5000/message
WEBSOCKET_LIST = [] # 用于保存所有的 websocket 连接;可理解为所有的客户端 @app.route('/message')
def message():
ws = request.environ.get('wsgi.websocket') # 如果不是 websocket 协议的请求,request.environ.get('wsgi.websocket') 的值是 None;如果是 websocket 请求, ws 将是一个 websocket 对象
if not ws:
print('http')
return '您使用的是Http协议'
WEBSOCKET_LIST.append(ws) # 把当前的 ws 连接添加到 WEBSOCKET_LIST 中
while True:
cid = ws.receive() # 接收投票的 cid; ws.receive() :接收客户端发过来的 websocket协议的 数据
if not cid: # 如果客户端关闭连接 ws.receive() 接收到的将会是 None
WEBSOCKET_LIST.remove(ws)
ws.close() # 后台的 ws 也关闭
break old = USERS[cid]['count']
new = old + 1
USERS[cid]['count'] = new for client in WEBSOCKET_LIST:
client.send(json.dumps({'cid':cid,'count':new})) # 给前端返回一个字典 # 服务端通过 websocket 协议就可以向客户端主动推送消息;这是由于 客户端与服务端的连接没有断开; 需要事先在客户端的浏览器上 new 一个 WebSocket 的对象 (WebSocket 支持H5等,但低版本的浏览器不支持) if __name__ == '__main__':
http_server = WSGIServer(('0.0.0.0', 5000), app, handler_class=WebSocketHandler) # 如果是 http 协议的请求,就交给 app 去处理;如果是 websocket 协议的请求,就交给 WebSocketHandler 去处理。 # app 的 werkzeug 只能处理 http 请求
http_server.serve_forever()
index.html
<!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>
<h1>丑男投票系统</h1>
<ul>
{% for k,v in users.items() %}
<li onclick="vote({{k}})" id="id_{{k}}">{{v.name}}<span>{{v.count}}</span></li>
{% endfor %}
</ul> <script src="{{ url_for('static',filename='jquery-3.3.1.min.js')}}"></script>
<script>
var ws = new WebSocket('ws://192.168.13.253:5000/message') // 实例化一个WebSocket 对象: 用于向 192.168.13.253:5000/message 这个url 发送 websocket 协议的请求;该连接不会断开
// 前端通过 ws.send("你好") 来发送 websocket协议的数据 ws.onmessage = function (event) { // 服务端返回 ws 数据的时候, ws.onmessage() 自动触发
/* 服务器端向客户端发送数据时,自动执行 */
// {'cid':cid,'count':new}
var response = JSON.parse(event.data); // event.data 就是 服务端返回回来的数据
$('#id_'+response.cid).find('span').text(response.count); }; function vote(cid) {
ws.send(cid) // 发送 websocket 数据
}
</script>
</body>
</html>
socketserver模块使用 & websocket的更多相关文章
- socket 和 SocketServer 模块
一 .Socket 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket socket(TCP,IP)通常也称作"套接字",用于描述IP地址和端 ...
- SocketServer模块
在利用select实现伪并发的socket博文中我们说了: 如果要实现一个server端可以和多个客户端进行通信可以使用 1.多线程 2.多进程 3.select I/O多路复用 在那篇博文中我们介绍 ...
- 浅析python中socketserver模块使用
虽然说用python编写简单的网络程序狠方便,但是复杂一点的网络程序还是用现成的框架比较好,这样就可以专心事物逻辑,而不是套接字的各种细节.Socketserver模块简化了编写网络服务程序,同时so ...
- Python网络编程(2)-粘包现象及socketserver模块实现TCP并发
1. 基于Tcp的远程调用命令实现 很多人应该都使用过Xshell工具,这是一个远程连接工具,通过上面的知识,就可以模拟出Xshell远程连接服务器并调用命令的功能. Tcp服务端代码如下: impo ...
- Python之socketserver模块和验证客户端链接的合法性
验证客户端链接的合法性 分布式系统中实现一个简单的客户端链接认证功能 #_*_coding:utf-8_*_ from socket import * import hmac,os secret_ke ...
- python 内置标准库socketserver模块的思考
socketserver模块简化了编写网络服务器的任务, 在很大程度上封装了一些操作, 你可以看成是事件驱动型的设计, 这很不错.它定义了两个最基本的类--服务器类 BaseServer, 请求处理类 ...
- socketserver模块TCP和UDP协议形式
# >>>>>>>>>>>>>>>>>>>>服务端socketserver模块通 ...
- Python网络编程(3)——SocketServer模块与简单并发服务器
主要类型 该模块有四个比较主要的类,其中常用的是 TCPServer 和 UDPServer. 1. TCPServer 2. UDPServer 3. UnixStreamServer,类似于TCP ...
- python-基于UDP通信的套接字,socketserver模块的使用
一.基于UDP协议通信的套接字 udp是没有链接的,所以先启动哪一端都不会报错 import socket server=socket.socket(socket.AF_INET,socket.SOC ...
随机推荐
- ASP.Net 控件
简单控件 Label -作用是显示文字,编译后元素是Span 1.文本类 边框: BorderColor 边框颜色 BordersTyle 边框样式 BorderWidth 边框粗细 Literal- ...
- 关于.Net中Process的使用方法和各种用途汇总(二):用Process启动cmd.exe完成将cs编译成dll
上一章博客我为大家介绍了Process类的所有基本使用方法,这一章博客我来为大家做一个小扩展,来熟悉一下Process类的实际使用,废话不多说我们开始演示. 先看看我们的软件要设计成的布局吧. 首先我 ...
- Mac OS 下安装和配置 maven
1. 安装 Maven 前的必须准备 需先安装 Java 环境 下载合适的 JDK 配置 JDK 环境变量 JAVA_HOME:为 JDK 安装目录 Path:为 JDK/bin 目录 测试是否成功: ...
- Android开发中使用startActivityForResult()方法从Activity A跳转Activity B出现B退出时A也同时退出的解决办法
最近一个 App 中用到了 startActivityForResult() 方法,使用的时候却出现了一些问题,比如我在 Activity A 中调用该方法向 Activity B 中跳转,如果 B ...
- 来自锐动天地的直播ios SDK
直播iOS SDK,可以在手机iOS端实时采集视频,同时在拍摄过程中支持多种实时滤镜效果,只要调用视频直播接口,通过3G.4G.WIFI等网络,推流发送给云端流媒体直播系统处理,并通过CDN视频加速分 ...
- Android EditText 输入金额(小数点后两位)
EditText edit = new EditText(context); InputType.TYPE_NUMBER_FLAG_DECIMAL //小数点型 InputType.TYPE_CLAS ...
- cron on Centos
1. crond.service 2. configuration 2.0 format # Example of job definition: # .---------------- minute ...
- [转载]迅为4418开发板Qt移植移动4G模块第一部分
本文转自迅为论坛:http://topeetboard.com 平台:iTOP-4418开发板 1.首先要配置内核,这个一步和Android系统移植3G或者4G模块是一样的.一般模块的 ...
- viewport 640宽的做法 针对iphone和安卓单独设置
<!DOCTYPE html> <html lang="ch"> <head> <meta charset="utf-8&quo ...
- com口操作excel
_Application app; //Excel应用程序接口 Workbooks books; //工作薄集合 _Workbook book; //工作薄 Work ...