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利用beautifulSoup实现爬虫
Sep 29 Python
Python获取本机所有网卡ip,掩码和广播地址实例代码
Jan 22 Python
详解django自定义中间件处理
Nov 21 Python
python模拟菜刀反弹shell绕过限制【推荐】
Jun 25 Python
如何修复使用 Python ORM 工具 SQLAlchemy 时的常见陷阱
Nov 19 Python
python创建n行m列数组示例
Dec 02 Python
python读取ini配置的类封装代码实例
Jan 08 Python
Selenium启动Chrome时配置选项详解
Mar 18 Python
Python利用PyPDF2库获取PDF文件总页码实例
Apr 03 Python
python中如何打包用户自定义模块
Sep 23 Python
如何使用Python进行PDF图片识别OCR
Jan 22 Python
PyQt5通过信号实现MVC的示例
Feb 06 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
Windows2003 下 MySQL 数据库每天自动备份
2006/12/21 PHP
解决控件遮挡问题:关于有窗口元素和无窗口元素
2007/01/28 PHP
Php无限级栏目分类读取的实现代码
2014/02/19 PHP
Yii实现MySQL多数据库和读写分离实例分析
2014/12/03 PHP
php递归调用删除数组空值元素的方法
2015/04/28 PHP
全面解析PHP验证码的实现原理 附php验证码小案例
2016/08/17 PHP
php mongodb操作类 带几个简单的例子
2016/08/25 PHP
php下载文件超时时间的设置方法
2016/10/06 PHP
基于laravel where的高级使用方法
2019/10/10 PHP
Javascript模块模式分析
2008/05/16 Javascript
基于jQuery实现点击同时更改两个iframe的网址
2010/07/01 Javascript
使用js正则控制input标签只允许输入的值
2013/07/29 Javascript
IE8下String的Trim()方法失效的解决方法
2013/11/08 Javascript
js实现获取焦点后光标在字符串后
2014/09/17 Javascript
JavaScript中的条件判断语句使用详解
2015/06/03 Javascript
jQuery+CSS3实现3D立方体旋转效果
2015/11/10 Javascript
jQuery如何封装输入框插件
2016/08/19 Javascript
Angular.js中数组操作的方法教程
2017/07/31 Javascript
详解javascript appendChild()的完整功能
2018/08/18 Javascript
vue-video-player 通过自定义按钮组件实现全屏切换效果【推荐】
2018/08/29 Javascript
vue中使用protobuf的过程记录
2018/10/26 Javascript
JS获取当前时间的实例代码(昨天、今天、明天)
2018/11/13 Javascript
下载糗事百科的内容_python版
2008/12/07 Python
python解析模块(ConfigParser)使用方法
2013/12/10 Python
Python paramiko模块的使用示例
2018/04/11 Python
python中的json总结
2018/10/11 Python
python mock测试的示例
2020/10/19 Python
Swanson中国官网:美国斯旺森健康产品公司
2021/03/01 全球购物
应届生护士求职信
2013/11/01 职场文书
搞笑婚礼主持词
2014/03/13 职场文书
工程质量承诺书
2014/03/27 职场文书
党支部换届选举方案
2014/05/08 职场文书
电大奖学金获奖感言
2014/08/14 职场文书
企业整改报告范文
2014/11/08 职场文书
学校德育工作总结2015
2015/05/11 职场文书
python开发飞机大战游戏
2021/07/15 Python