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中编写ORM框架的入门指引
Apr 29 Python
Django Admin实现上传图片校验功能
Mar 06 Python
python3结合openpyxl库实现excel操作的实例代码
Sep 11 Python
python调用opencv实现猫脸检测功能
Jan 15 Python
python仿抖音表白神器
Apr 08 Python
Python实现二叉树前序、中序、后序及层次遍历示例代码
May 18 Python
Django中celery执行任务结果的保存方法
Jul 12 Python
Python正则表达式急速入门(小结)
Dec 16 Python
基于MSELoss()与CrossEntropyLoss()的区别详解
Jan 02 Python
tensorflow的计算图总结
Jan 12 Python
Python如何使用paramiko模块连接linux
Mar 18 Python
一劳永逸彻底解决pip install慢的办法
May 24 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
8个必备的PHP功能实例代码
2013/10/27 PHP
Windows下PHP开发环境搭建教程(Apache+PHP+MySQL)
2016/06/13 PHP
php中的异常和错误浅析
2017/05/03 PHP
基于ThinkPHP5.0实现图片上传插件
2017/09/25 PHP
php判断/计算闰年的方法小结【三种方法】
2019/07/06 PHP
用Mootools获得操作索引的两种方法分享
2011/12/12 Javascript
jquery中的mouseleave和mouseout的区别 模仿下拉框效果
2012/02/07 Javascript
Jquery UI震动效果实现原理及步骤
2013/02/04 Javascript
jQuery学习笔记之jQuery动画效果
2013/09/09 Javascript
转换字符串为json对象的方法详解
2013/11/29 Javascript
浅析JavaScript中的typeof运算符
2013/11/30 Javascript
深入学习jQuery Validate表单验证(二)
2016/01/18 Javascript
jQuery网页定位导航特效实现方法
2016/12/19 Javascript
JavaScript 基础表单验证示例(纯Js实现)
2017/07/20 Javascript
动态创建Angular组件实现popup弹窗功能
2017/09/15 Javascript
浅谈webpack打包过程中因为图片的路径导致的问题
2018/02/21 Javascript
使用 Vue cli 3.0 构建自定义组件库的方法
2019/04/30 Javascript
微信小程序实现比较功能的方法汇总(五种方法)
2020/03/07 Javascript
[01:06]DOTA2亚洲邀请赛专属珍藏-荧煌之礼
2017/03/24 DOTA
Python交换变量
2008/09/06 Python
Python实现OpenCV的安装与使用示例
2018/03/30 Python
Tensorflow实现AlexNet卷积神经网络及运算时间评测
2018/05/24 Python
Python3正则匹配re.split,re.finditer及re.findall函数用法详解
2018/06/11 Python
python实现创建新列表和新字典,并使元素及键值对全部变成小写
2019/01/15 Python
Python中请不要再用re.compile了
2019/06/30 Python
Python3 批量扫描端口的例子
2019/07/25 Python
numpy 声明空数组详解
2019/12/05 Python
详解Python中字符串前“b”,“r”,“u”,“f”的作用
2019/12/18 Python
深入浅析Python 函数注解与匿名函数
2020/02/24 Python
神路信息Java面试题目
2013/03/31 面试题
职业规划书如何设计?
2014/01/09 职场文书
禁毒宣传工作方案
2014/05/23 职场文书
中职生求职信
2014/07/01 职场文书
水电工程师岗位职责
2015/02/13 职场文书
php随机生成验证码,php随机生成数字,php随机生成数字加字母!
2021/04/01 PHP
总结Pyinstaller打包的高级用法
2021/06/28 Python