Python Web静态服务器非堵塞模式实现方法示例


Posted in Python onNovember 21, 2019

本文实例讲述了Python Web静态服务器非堵塞模式实现方法。分享给大家供大家参考,具体如下:

单进程非堵塞 模型

#coding=utf-8
from socket import *
import time
# 用来存储所有的新链接的socket
g_socket_list = list()
def main():
  server_socket = socket(AF_INET, SOCK_STREAM)
  server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR , 1)
  server_socket.bind(('', 7890))
  server_socket.listen(128)
  # 将套接字设置为非堵塞
  # 设置为非堵塞后,如果accept时,恰巧没有客户端connect,那么accept会
  # 产生一个异常,所以需要try来进行处理
  server_socket.setblocking(False)
  while True:
    # 用来测试
    time.sleep(0.5)
    try:
      newClientInfo = server_socket.accept()
    except Exception as result:
      pass
    else:
      print("一个新的客户端到来:%s" % str(newClientInfo))
      newClientInfo[0].setblocking(False) # 设置为非堵塞
      g_socket_list.append(newClientInfo)
    for client_socket, client_addr in g_socket_list:
      try:
        recvData = client_socket.recv(1024)
        if recvData:
          print('recv[%s]:%s' % (str(client_addr), recvData))
        else:
          print('[%s]客户端已经关闭' % str(client_addr))
          client_socket.close()
          g_socket_list.remove((client_socket,client_addr))
      except Exception as result:
        pass
    print(g_socket_list) # for test
if __name__ == '__main__':
  main()

web静态服务器-单进程非堵塞

import time
import socket
import sys
import re
class WSGIServer(object):
  """定义一个WSGI服务器的类"""
  def __init__(self, port, documents_root):
    # 1. 创建套接字
    self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 2. 绑定本地信息
    self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    self.server_socket.bind(("", port))
    # 3. 变为监听套接字
    self.server_socket.listen(128)
    self.server_socket.setblocking(False)
    self.client_socket_list = list()
    self.documents_root = documents_root
  def run_forever(self):
    """运行服务器"""
    # 等待对方链接
    while True:
      # time.sleep(0.5) # for test
      try:
        new_socket, new_addr = self.server_socket.accept()
      except Exception as ret:
        print("-----1----", ret) # for test
      else:
        new_socket.setblocking(False)
        self.client_socket_list.append(new_socket)
      for client_socket in self.client_socket_list:
        try:
          request = client_socket.recv(1024).decode('utf-8')
        except Exception as ret:
          print("------2----", ret) # for test
        else:
          if request:
            self.deal_with_request(request, client_socket)
          else:
            client_socket.close()
            self.client_socket_list.remove(client_socket)
      print(self.client_socket_list)
  def deal_with_request(self, request, client_socket):
    """为这个浏览器服务器"""
    if not request:
      return
    request_lines = request.splitlines()
    for i, line in enumerate(request_lines):
      print(i, line)
    # 提取请求的文件(index.html)
    # GET /a/b/c/d/e/index.html HTTP/1.1
    ret = re.match(r"([^/]*)([^ ]+)", request_lines[0])
    if ret:
      print("正则提取数据:", ret.group(1))
      print("正则提取数据:", ret.group(2))
      file_name = ret.group(2)
      if file_name == "/":
        file_name = "/index.html"
    # 读取文件数据
    try:
      f = open(self.documents_root+file_name, "rb")
    except:
      response_body = "file not found, 请输入正确的url"
      response_header = "HTTP/1.1 404 not found\r\n"
      response_header += "Content-Type: text/html; charset=utf-8\r\n"
      response_header += "Content-Length: %d\r\n" % (len(response_body))
      response_header += "\r\n"
      # 将header返回给浏览器
      client_socket.send(response_header.encode('utf-8'))
      # 将body返回给浏览器
      client_socket.send(response_body.encode("utf-8"))
    else:
      content = f.read()
      f.close()
      response_body = content
      response_header = "HTTP/1.1 200 OK\r\n"
      response_header += "Content-Length: %d\r\n" % (len(response_body))
      response_header += "\r\n"
      # 将header返回给浏览器
      client_socket.send( response_header.encode('utf-8') + response_body)
# 设置服务器服务静态资源时的路径
DOCUMENTS_ROOT = "./html"
def main():
  """控制web服务器整体"""
  # python3 xxxx.py 7890
  if len(sys.argv) == 2:
    port = sys.argv[1]
    if port.isdigit():
      port = int(port)
  else:
    print("运行方式如: python3 xxx.py 7890")
    return
  print("http服务器使用的port:%s" % port)
  http_server = WSGIServer(port, DOCUMENTS_ROOT)
  http_server.run_forever()
if __name__ == "__main__":
  main()

更多关于Python相关内容可查看本站专题:《Python Socket编程技巧总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
一个基于flask的web应用诞生 用户注册功能开发(5)
Apr 11 Python
Python自动化运维之IP地址处理模块详解
Dec 10 Python
python操作列表的函数使用代码详解
Dec 28 Python
Puppeteer使用示例详解
Jun 20 Python
Python Matplotlib 基于networkx画关系网络图
Jul 10 Python
Python注释、分支结构、循环结构、伪“选择结构”用法实例分析
Jan 09 Python
详解python常用命令行选项与环境变量
Feb 20 Python
Python异常原理及异常捕捉实现过程解析
Mar 25 Python
在jupyter notebook中调用.ipynb文件方式
Apr 14 Python
python中Django文件上传方法详解
Aug 05 Python
使用Python实现NBA球员数据查询小程序功能
Nov 09 Python
总结python 三种常见的内存泄漏场景
Nov 20 Python
Windows10下Tensorflow2.0 安装及环境配置教程(图文)
Nov 21 #Python
使用python代码进行身份证号校验的实现示例
Nov 21 #Python
Python 面向对象之封装、继承、多态操作实例分析
Nov 21 #Python
用python画一只可爱的皮卡丘实例
Nov 21 #Python
Python 私有化操作实例分析
Nov 21 #Python
使用python的turtle绘画滑稽脸实例
Nov 21 #Python
使用Python的Turtle绘制哆啦A梦实例
Nov 21 #Python
You might like
最贵的咖啡是怎么产生的,它的风味怎么样?
2021/03/04 新手入门
解析PHP中DIRECTORY_SEPARATOR,PATH_SEPARATOR两个常量的作用
2013/06/21 PHP
PHP生成随机字符串(3种方法)
2015/09/25 PHP
PHP中如何防止外部恶意提交调用ajax接口
2016/04/11 PHP
PHP 表单提交及处理表单数据详解及实例
2016/12/27 PHP
Lumen timezone 时区设置方法(慢了8个小时)
2018/01/20 PHP
php实现等比例压缩图片
2018/07/26 PHP
[原创]保存的js无法执行的解决办法
2007/02/25 Javascript
js 匿名调用实现代码
2009/06/19 Javascript
javascript自执行函数之伪命名空间封装法
2010/12/25 Javascript
JQuery表格拖动调整列宽效果(自己动手写的)
2014/09/01 Javascript
NodeJS学习笔记之Connect中间件模块(一)
2015/01/27 NodeJs
一种Javascript解释ajax返回的json的好方法(推荐)
2016/06/02 Javascript
react.js 翻页插件实例代码
2017/01/19 Javascript
基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能
2019/11/12 Javascript
使用Python获取CPU、内存和硬盘等windowns系统信息的2个例子
2014/04/15 Python
以Flask为例讲解Python的框架的使用方法
2015/04/29 Python
Python模拟脉冲星伪信号频率实例代码
2018/01/03 Python
Python中的asyncio代码详解
2019/06/10 Python
8种用Python实现线性回归的方法对比详解
2019/07/10 Python
python Elasticsearch索引建立和数据的上传详解
2019/08/04 Python
Pytorch 解决自定义子Module .cuda() tensor失败的问题
2020/06/23 Python
基于Python和C++实现删除链表的节点
2020/07/06 Python
python破解同事的压缩包密码
2020/10/14 Python
python实现企业微信定时发送文本消息的示例代码
2020/11/24 Python
西班牙最大的在线滑板和街头服饰商店:Fillow.net
2019/04/15 全球购物
PHP使用Redis队列执行定时任务实例讲解
2021/03/24 PHP
临床医师专业个人自我评价范文
2013/11/07 职场文书
即将毕业大学生自荐信
2014/01/24 职场文书
协议书怎么写
2014/04/21 职场文书
公司募捐倡议书
2014/05/14 职场文书
四风查摆剖析材料
2014/10/10 职场文书
新郎婚礼答谢词
2015/01/04 职场文书
入党申请书怎么写?
2019/06/11 职场文书
升级 Win11 还是坚守 Win10?微软 Win11 新系统缺失功能大盘点
2022/04/05 数码科技
Django数据库(SQlite)基本入门使用教程
2022/07/07 Python