python 实现socket服务端并发的四种方式


Posted in Python onDecember 14, 2020

多进程&多线程

服务端:多进程和多线程的开启方式相同。

缺点:<1> 由于Cpython的GIL,导致同一时间无法运行多个线程;<2> 不可能无限开进进程或线程

解决办法:多进程、concurrent.futures.ProcessPoolExecutor、线程池

import socket
from multiprocessing import Process
from threading import Thread


class MyTcpServer:
  def __init__(self, ip, port):
    self.ip = ip
    self.port = port
    self.server = socket.socket()
    self.server.bind((self.ip, self.port))
    self.server.listen(5)

  def wait_accept(self):
    conn, addr = self.server.accept()
    return conn, addr

  def handle_request(self, conn):
    while 1:
      try:
        data = conn.recv(1024)
        if not data: break
        conn.send(data.upper())
      except Exception as e:
        print(e)
        break
    conn.close()


if __name__ == '__main__':
  server = MyTcpServer('127.0.0.1', 8888)
  while 1:
    conn, addr = server.wait_accept()
    p = Process(target=server.handle_request, args=(conn, ))	# 创建一个进程
    p.start()	# 告诉操作提供,开启这个进程

进程池&线程池

异步提交任务,支持异步接收返回结果(submit返回一个futures对象,调用add_done_callback方法)

import socket
from concurrent.futures import ProcessPoolExecutor
# from concurrent.futures import ThreadPoolExecutor


class MyTcpServer:
  def __init__(self, ip, port):
    self.ip = ip
    self.port = port
    self.server = socket.socket()
    self.server.bind((self.ip, self.port))
    self.server.listen(5)

  def wait_accept(self):
    conn, addr = self.server.accept()
    return conn, addr

  def handle_request(self, conn):
    while 1:
      try:
        data = conn.recv(1024)
        if not data: break
        conn.send(data.upper())
      except Exception as e:
        print(e)
        break
    conn.close()


if __name__ == '__main__':
  server = MyTcpServer('127.0.0.1', 8888)
  pool = ProcessPoolExecutor(5)    # 5个进程一直服务

  while 1:
    conn, addr = server.wait_accept()
    pool.submit(server.handle_request, conn)	# 异步提交任务

socketserver

优点:简化socket服务端创建流程。
提供服务端串行和并发两种服务模式(TCPServer,ThreadingTCPServer)
缺点:windows上无法使用多进程实现并发

import socketserver


class MyTcpHandler(socketserver.BaseRequestHandler):
  def handle(self):		# 通信循环
    while 1:
      try:
        data = self.request.recv(1024)
        if not data: break
        self.request.send(data.upper())
      except Exception as e:
        print(e)
        break
    self.request.close()


if __name__ == '__main__':
  ip_port = '127.0.0.1', 8888
  server = socketserver.ThreadingTCPServer(ip_port, MyTcpHandler) # 异步处理 
  server.serve_forever()		# 连接循环

协程

优点:单线程内实现并发,代码级别模拟IO切换,提高程序运行效率

from gevent import spawn, monkey;monkey.patch_all()		# 猴子补丁,补丁:常规IO
import socket


class MyTcpServer:
  def __init__(self, ip, port, my_spawn):
    self.ip = ip
    self.port = port
    self.server = socket.socket()
    self.server.bind((self.ip, self.port))
    self.server.listen(5)
    self.spawn = my_spawn		# 保存spawn本地

  def wait_accept(self):
    while 1:
      conn, addr = self.server.accept()
      self.spawn(self.handle_request, conn)	# 检测 handle_request的io

  def handle_request(self, conn):
    while 1:
      try:
        data = conn.recv(1024)
        if not data: break
        conn.send(data.upper())
      except Exception as e:
        print(e)
        break
    conn.close()


if __name__ == '__main__':
  server = MyTcpServer('127.0.0.1', 8888, spawn)
  g1 = server.spawn(server.wait_accept)	# 检测wait_accept的io
  g1.join()	# 等待g1运行结束,即一直在循环检测io

以上就是python 实现socket服务端并发的四种方式的详细内容,更多关于python socket服务端并发的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python列表生成器的循环技巧分享
Mar 06 Python
浅谈Python程序与C++程序的联合使用
Apr 07 Python
Python在线运行代码助手
Jul 15 Python
利用python模拟sql语句对员工表格进行增删改查
Jul 05 Python
对Python3中的input函数详解
Apr 22 Python
Python基于plotly模块实现的画图操作示例
Jan 23 Python
Python3 venv搭建轻量级虚拟环境的步骤(图文)
Aug 09 Python
Python socket 套接字实现通信详解
Aug 27 Python
pytorch使用 to 进行类型转换方式
Jan 08 Python
python else语句在循环中的运用详解
Jul 06 Python
Python导入父文件夹中模块并读取当前文件夹内的资源
Nov 19 Python
详解numpy1.19.4与python3.9版本冲突解决
Dec 15 Python
linux centos 7.x 安装 python3.x 替换 python2.x的过程解析
Dec 14 #Python
Python获取指定网段正在使用的IP
Dec 14 #Python
python利用pytesseract 实现本地识别图片文字
Dec 14 #Python
python 利用百度API识别图片文字(多线程版)
Dec 14 #Python
python3中for循环踩过的坑记录
Dec 14 #Python
Python 数据分析之逐块读取文本的实现
Dec 14 #Python
Python 2.6.6升级到Python2.7.15的详细步骤
Dec 14 #Python
You might like
使用PHP和XSL stylesheets转换XML文档
2006/10/09 PHP
php木马攻击防御之道
2008/03/24 PHP
《PHP编程最快明白》第六讲:Mysql数据库操作
2010/11/01 PHP
thinkPHP查询方式小结
2016/01/09 PHP
php array_reverse 以相反的顺序返回数组实例代码
2017/04/11 PHP
基于ThinkPHP实现的日历功能实例详解
2017/04/15 PHP
php连接sftp的作用以及实例代码
2019/09/23 PHP
javascript函数库-集合框架
2007/04/27 Javascript
学习ExtJS border布局
2009/10/08 Javascript
js根据日期判断星座的示例代码
2014/01/23 Javascript
Bootstrap超大屏幕的实现代码
2017/03/22 Javascript
Vue使用vue-cli创建项目
2017/09/01 Javascript
利用SpringMVC过滤器解决vue跨域请求的问题
2018/02/10 Javascript
vue使用iframe嵌入网页的示例代码
2020/06/09 Javascript
解决Vue中mounted钩子函数获取节点高度出错问题
2018/05/18 Javascript
详解vue-router 初始化时做了什么
2018/06/11 Javascript
使用vue的transition完成滑动过渡的示例代码
2018/06/25 Javascript
layui实现table加载的示例代码
2018/08/14 Javascript
vue解决跨域问题(推荐)
2020/11/10 Javascript
[50:38]DOTA2-DPC中国联赛 正赛 Phoenix vs CDEC BO3 第二场 3月7日
2021/03/11 DOTA
详细解读Python中解析XML数据的方法
2015/10/15 Python
Jmeter HTTPS接口测试证书导入过程图解
2020/07/22 Python
详解vscode实现远程linux服务器上Python开发
2020/11/10 Python
ONLY德国官方在线商店:购买时尚女装
2017/09/21 全球购物
捷克领先的户外服装及配件市场零售商:ALPINE PRO
2018/01/09 全球购物
草莓网官网:StrawberryNET
2019/08/21 全球购物
二年级小学生评语
2014/04/21 职场文书
学习十八大宣传标语
2014/10/09 职场文书
2014年行政工作总结
2014/11/19 职场文书
2016新春团拜会致辞
2015/08/01 职场文书
办公室卫生管理制度
2015/08/04 职场文书
导游词之桂林
2019/08/20 职场文书
python3 sqlite3限制条件查询的操作
2021/04/07 Python
对Keras自带Loss Function的深入研究
2021/05/25 Python
dubbo集成zipkin获取Traceid的实现
2021/07/26 Java/Android
解决Mysql中的innoDB幻读问题
2022/04/29 MySQL