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中强大的命令行库click入门教程
Dec 26 Python
Python scikit-learn 做线性回归的示例代码
Nov 01 Python
TensorFlow模型保存/载入的两种方法
Mar 08 Python
对Pycharm创建py文件时自定义头部模板的方法详解
Feb 12 Python
详解Python网络框架Django和Scrapy安装指南
Apr 01 Python
在python plt图表中文字大小调节的方法
Jul 08 Python
pygame实现俄罗斯方块游戏(基础篇2)
Oct 29 Python
Python 中使用 PyMySQL模块操作数据库的方法
Nov 10 Python
pygame编写音乐播放器的实现代码示例
Nov 19 Python
python实现差分隐私Laplace机制详解
Nov 25 Python
解决os.path.isdir() 判断文件夹却返回false的问题
Nov 29 Python
python代码实现将列表中重复元素之间的内容全部滤除
May 22 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 number_format() 函数定义和用法
2012/06/01 PHP
PHP抓取、分析国内视频网站的视频信息工具类
2014/04/02 PHP
php使用parse_str实现查询字符串解析到变量中的方法
2017/02/17 PHP
PHP+MySQL使用mysql_num_rows实现模糊查询图书信息功能
2018/05/31 PHP
PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
2019/12/20 PHP
jquery select选中的一个小问题
2009/10/11 Javascript
兼容IE和Firefox火狐的上下、左右循环无间断滚动JS代码
2013/04/19 Javascript
jQuery实现当按下回车键时绑定点击事件
2014/01/28 Javascript
我的Node.js学习之路(一)
2014/07/06 Javascript
Easyui Treegrid改变默认图标的方法
2016/04/29 Javascript
Bootstrap3制作图片轮播效果
2016/05/12 Javascript
jQuery插件fullPage.js实现全屏滚动效果
2016/12/02 Javascript
微信小程序 JS动态修改样式的实现代码
2017/02/10 Javascript
JavaScript实现类似淘宝的购物车效果
2017/03/16 Javascript
Angular实现一个简单的多选复选框的弹出框指令实例
2017/04/25 Javascript
深入理解AngularJs-scope的脏检查(一)
2017/06/19 Javascript
解决Vue2.x父组件与子组件之间的双向绑定问题
2018/03/06 Javascript
关于node-bindings无法在Electron中使用的解决办法
2018/12/18 Javascript
js+canvas实现简单扫雷小游戏
2021/01/22 Javascript
vue 自定义组件的写法与用法详解
2020/03/04 Javascript
Vue3 实现双盒子定位Overlay的示例
2020/12/22 Vue.js
python使用电子邮件模块smtplib的方法
2016/08/28 Python
python如何使用正则表达式的前向、后向搜索及前向搜索否定模式详解
2017/11/08 Python
python进行TCP端口扫描的实现
2018/12/21 Python
Selenium+Python 自动化操控登录界面实例(有简单验证码图片校验)
2019/06/28 Python
HTML5网页音乐播放器的示例代码
2017/11/09 HTML / CSS
HTML高亮关键字的实现代码
2018/10/22 HTML / CSS
英国手机零售商:Carphone Warehouse
2018/06/06 全球购物
货代行业个人求职简历的自我评价
2013/10/22 职场文书
应用数学专业求职信
2014/03/14 职场文书
优秀广告词大全
2014/03/19 职场文书
2014年售后服务工作总结
2014/11/18 职场文书
2015年社区工作总结
2015/04/08 职场文书
汉语拼音教学反思
2016/02/22 职场文书
教你快速构建一个基于nginx的web集群项目
2021/11/27 Servers
日本动漫十大公认神作:第五现已全网禁播,《死亡笔记》在榜
2022/03/18 日漫