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 相关文章推荐
举例讲解Python中的身份运算符的使用方法
Oct 13 Python
python 爬取微信文章
Jan 30 Python
python matplotlib画图实例代码分享
Dec 27 Python
30秒轻松实现TensorFlow物体检测
Mar 14 Python
解决Spyder中图片显示太小的问题
Apr 27 Python
python re模块的高级用法详解
Jun 06 Python
celery4+django2定时任务的实现代码
Dec 23 Python
python实现公司年会抽奖程序
Jan 22 Python
python 将有序数组转换为二叉树的方法
Mar 26 Python
使用Python opencv实现视频与图片的相互转换
Jul 08 Python
python同步两个文件夹下的内容
Aug 29 Python
python GUI计算器的实现
Oct 09 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
第三节 定义一个类 [3]
2006/10/09 PHP
apache+php+mysql安装配置方法小结
2010/08/01 PHP
php whois查询API制作方法
2011/06/23 PHP
PHP采集腾讯微博的实现代码
2012/01/19 PHP
PHP ignore_user_abort函数详细介绍和使用实例
2014/07/15 PHP
推荐一款PHP+jQuery制作的列表分页的功能模块
2014/10/14 PHP
PHP二维数组去重算法
2016/12/17 PHP
JQuery浮动DIV提示信息并自动隐藏的代码
2010/08/29 Javascript
关于jQuery判断元素是否存在的问题示例探讨
2014/07/21 Javascript
jquery $(document).ready()和window.onload的区别浅析
2015/02/04 Javascript
js实现兼容IE和FF的上下层的移动
2015/05/04 Javascript
七夕情人节丘比特射箭小游戏
2015/08/20 Javascript
bootstrap与Jquery UI 按钮样式冲突的解决办法
2016/09/23 Javascript
JS实现中国公民身份证号码有效性验证
2017/02/20 Javascript
JavaScript进阶(三)闭包原理与用法详解
2020/05/09 Javascript
python ip正则式
2009/05/07 Python
Python中为feedparser设置超时时间避免堵塞
2014/09/28 Python
Python常用小技巧总结
2015/06/01 Python
在Python的Django框架中编写编译函数
2015/07/20 Python
Django使用Mysql数据库已经存在的数据表方法
2018/05/27 Python
python+opencv实现高斯平滑滤波
2020/07/21 Python
使用python爬取微博数据打造一颗“心”
2019/06/28 Python
python遍历文件目录、批量处理同类文件
2019/08/31 Python
Python实现直播推流效果
2019/11/26 Python
python爬虫模拟浏览器的两种方法实例分析
2019/12/09 Python
在Python中实现函数重载的示例代码
2019/12/12 Python
Python爬虫爬取煎蛋网图片代码实例
2019/12/16 Python
Python 获取命令行参数内容及参数个数的实例
2019/12/20 Python
tensorflow2.0与tensorflow1.0的性能区别介绍
2020/02/07 Python
Keras—embedding嵌入层的用法详解
2020/06/10 Python
python打包生成so文件的实现
2020/10/30 Python
Speedo速比涛中国官方网站:全球领先泳装运动品牌
2018/04/24 全球购物
德国购买门票网站:ADticket.de
2019/10/31 全球购物
几个人围成一圈的问题
2013/09/26 面试题
const char*, char const*, char*const的区别是什么
2014/07/09 面试题
2019年工作总结范文
2019/05/21 职场文书