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 相关文章推荐
Python2.6版本中实现字典推导 PEP 274(Dict Comprehensions)
Apr 28 Python
浅谈Python中数据解析
May 05 Python
Python中文竖排显示的方法
Jul 28 Python
git进行版本控制心得详谈
Dec 10 Python
Python 查看文件的编码格式方法
Dec 21 Python
django传值给模板, 再用JS接收并进行操作的实例
May 28 Python
Python3的介绍、安装和命令行的认识(推荐)
Oct 20 Python
Python实现爬取马云的微博功能示例
Feb 16 Python
python中selenium操作下拉滚动条的几种方法汇总
Jul 14 Python
Django的models模型的具体使用
Jul 15 Python
Python 日期时间datetime 加一天,减一天,加减一小时一分钟,加减一年
Apr 16 Python
python实现画图工具
Aug 27 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
基于php设计模式中工厂模式详细介绍
2013/05/15 PHP
PHP编程实现csv文件导入mysql数据库的方法
2017/04/29 PHP
Alliance vs Liquid BO3 第二场2.13
2021/03/10 DOTA
JavaScript中通过闭包解决只能取得包含函数中任何变量最后一个值的问题
2010/08/12 Javascript
javascript中运用闭包和自执行函数解决大量的全局变量问题
2010/12/30 Javascript
jquery动态加载图片数据练习代码
2011/08/04 Javascript
js利用prototype调用Array的slice方法示例
2014/06/09 Javascript
让JavaScript和其它资源并发下载的方法
2014/10/16 Javascript
jquery插件方式实现table查询功能的简单实例
2016/06/06 Javascript
Javascript 判断两个IP是否在同一网段实例代码
2016/11/28 Javascript
jQuery使用siblings获取某元素所有同辈(兄弟姐妹)元素用法示例
2017/01/30 Javascript
JS实现数组按升序及降序排列的方法
2017/04/26 Javascript
详解VUE中常用的几种import(模块、文件)引入方式
2018/07/03 Javascript
seajs和requirejs模块化简单案例分析
2019/08/26 Javascript
小程序中使用css var变量(使js可以动态设置css样式属性)
2020/03/31 Javascript
Chrome插件开发系列一:弹窗终结者开发实战
2020/10/02 Javascript
python中将阿拉伯数字转换成中文的实现代码
2011/05/19 Python
跟老齐学Python之不要红头文件(1)
2014/09/28 Python
python获取本地计算机名字的方法
2015/04/29 Python
Python使用ftplib实现简易FTP客户端的方法
2015/06/03 Python
解决Pycharm调用Turtle时 窗口一闪而过的问题
2019/02/16 Python
Django框架自定义session处理操作示例
2019/05/27 Python
详解Python 定时框架 Apscheduler原理及安装过程
2019/06/14 Python
python tkinter实现连连看游戏
2020/11/16 Python
python3.9实现pyinstaller打包python文件成exe
2020/12/13 Python
python实现定时发送邮件
2020/12/23 Python
opencv实现图像平移效果
2021/03/24 Python
人事部主管岗位职责
2013/12/26 职场文书
情人节活动策划方案
2014/02/27 职场文书
技术总监管理职责范本
2014/03/06 职场文书
公司授权委托书范文
2014/09/21 职场文书
预备党员表决心的话
2015/09/22 职场文书
关于食品安全的演讲稿范文(三篇)
2019/10/21 职场文书
Opencv中cv2.floodFill算法的使用
2021/06/18 Python
django中websocket的具体使用
2022/01/22 Python
ubuntu如何搭建vsftpd服务器
2022/12/24 Servers