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 09 Python
python通过ftplib登录到ftp服务器的方法
May 08 Python
Django自定义认证方式用法示例
Jun 23 Python
Python使用Tkinter实现机器人走迷宫
Jan 22 Python
python中pip的安装与使用教程
Aug 10 Python
python看某个模块的版本方法
Oct 16 Python
python交互界面的退出方法
Feb 16 Python
Python文件打开方式实例详解【a、a+、r+、w+区别】
Mar 30 Python
python issubclass 和 isinstance函数
Jul 25 Python
解析python的局部变量和全局变量
Aug 15 Python
Tensorflow 模型转换 .pb convert to .lite实例
Feb 12 Python
使用python画出逻辑斯蒂映射(logistic map)中的分叉图案例
Dec 11 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
PHP4 与 MySQL 数据库操作函数详解
2006/10/09 PHP
深入file_get_contents函数抓取内容失败的原因分析
2013/06/25 PHP
如何修改和添加Apache的默认站点目录
2013/07/05 PHP
php的memcache类分享(memcache队列)
2014/03/26 PHP
PHP不用递归实现无限分级的例子分享
2014/04/18 PHP
php自定义apk安装包实例
2014/10/20 PHP
PHP设计模式之装饰者模式代码实例
2015/05/11 PHP
Laravel 5.4因特殊字段太长导致migrations报错的解决
2017/10/22 PHP
php创建类并调用的实例方法
2019/09/25 PHP
js function定义函数使用心得
2010/04/15 Javascript
JavaScript自定义事件介绍
2013/08/29 Javascript
js中对象的声明方式以及数组的一些用法示例
2013/12/11 Javascript
javascript日期格式化示例分享
2014/03/05 Javascript
纯js实现div内图片自适应大小(已测试,兼容火狐)
2014/06/16 Javascript
javascript控制图片播放的实现代码
2020/07/29 Javascript
AngularJS 路由详解和简单实例
2016/07/28 Javascript
JavaScript简单验证表单空值及邮箱格式的方法
2017/01/20 Javascript
JS中showModalDialog关闭子窗口刷新主窗口用法详解
2017/03/25 Javascript
代码整洁之道(重构)
2018/10/25 Javascript
js图数据结构处理 迪杰斯特拉算法代码实例
2019/09/11 Javascript
python+influxdb+shell编写区域网络状况表
2018/07/27 Python
pandas每次多Sheet写入文件的方法
2018/12/10 Python
django 使用全局搜索功能的实例详解
2019/07/18 Python
TensorFlow tf.nn.conv2d实现卷积的方式
2020/01/03 Python
python数据分析工具之 matplotlib详解
2020/04/09 Python
CSS超出文本指定宽度用省略号代替和文本不换行
2016/05/05 HTML / CSS
详解HTML5中的拖放事件(Drag 和 drop)
2016/11/14 HTML / CSS
APM Monaco中国官网:来自摩纳哥珠宝品牌
2017/12/27 全球购物
大学生求职简历的自我评价
2013/10/14 职场文书
电气专业应届生求职信
2013/11/01 职场文书
职业生涯规划书基本格式
2014/01/06 职场文书
培训协议书范本
2014/04/22 职场文书
医药销售自荐书
2014/05/29 职场文书
社区两委对照检查材料
2014/08/23 职场文书
2014年艾滋病防治工作总结
2014/12/10 职场文书
如何书写你的职业生涯规划书?
2019/06/27 职场文书