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中实现远程调用(RPC、RMI)简单例子
Apr 28 Python
简单的Python抓taobao图片爬虫
Oct 26 Python
举例详解Python中的split()函数的使用方法
Apr 07 Python
Python 反转字符串(reverse)的方法小结
Feb 20 Python
一篇文章读懂Python赋值与拷贝
Apr 19 Python
详解python中Numpy的属性与创建矩阵
Sep 10 Python
Python 等分切分数据及规则命名的实例代码
Aug 16 Python
Python socket实现的文件下载器功能示例
Nov 15 Python
简单了解python装饰器原理及使用方法
Dec 18 Python
python 函数中的参数类型
Feb 11 Python
PyTorch之nn.ReLU与F.ReLU的区别介绍
Jun 27 Python
Python环境搭建过程从安装到Hello World
Feb 05 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中break及continue两个流程控制指令区别分析
2011/04/18 PHP
thinkphp普通查询与表达式查询实例分析
2014/11/24 PHP
php中http与https跨域共享session的解决方法
2014/12/20 PHP
PHP命令空间namespace及use的用法小结
2017/11/27 PHP
php远程请求CURL实例教程(爬虫、保存登录状态)
2020/12/10 PHP
JavaScript 学习 - 提高篇
2007/02/02 Javascript
JS链式调用的实现方法
2013/03/07 Javascript
网页整体变灰白色(兼容各浏览器)实例
2013/04/21 Javascript
JQ获取动态加载的图片大小的正确方法分享
2013/11/08 Javascript
详解Node.js包的工程目录与NPM包管理器的使用
2016/02/16 Javascript
javascript结合Flexbox简单实现滑动拼图游戏
2016/02/18 Javascript
ES6深入理解之“let”能替代”var“吗?
2017/06/28 Javascript
Nodejs异步回调之异常处理实例分析
2018/06/22 NodeJs
[06:16]DOTA2守卫传承者——职业选手谈心路历程
2015/02/26 DOTA
Python中的map()函数和reduce()函数的用法
2015/04/27 Python
Python多进程分块读取超大文件的方法
2016/04/13 Python
Python实现批量检测HTTP服务的状态
2016/10/27 Python
详解Python中的静态方法与类成员方法
2017/02/28 Python
python学习必备知识汇总
2017/09/08 Python
Python面向对象之反射/自省机制实例分析
2018/08/24 Python
Pycharm更换python解释器的方法
2018/10/29 Python
Python面向对象程序设计示例小结
2019/01/30 Python
Python3.4解释器用法简单示例
2019/03/22 Python
python使用opencv对图像mask处理的方法
2019/07/05 Python
flask 实现token机制的示例代码
2019/11/07 Python
Python3.6 中的pyinstaller安装和使用教程
2020/03/16 Python
GIVENCHY纪梵希官方旗舰店:高定彩妆与贵族护肤品
2018/04/16 全球购物
玉兰油美国官网:OLAY美国
2018/10/25 全球购物
C,C++的几个面试题小集
2013/07/13 面试题
大学生毕业鉴定
2014/01/31 职场文书
社会学专业求职信
2014/02/24 职场文书
2014年最新学习全国两会精神心得
2014/03/17 职场文书
计划生育个人总结
2015/03/02 职场文书
培训督导岗位职责
2015/04/10 职场文书
2015年三年级班主任工作总结
2015/05/21 职场文书
股东出资协议书
2016/03/21 职场文书