Python基础Web服务器案例

一、WSGI

1、PythonWeb服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI) 是Python应用程序或框架和Web服务器之间的一种接口,已经被广泛接受, 它已基本达成它的可移植性方面的目标。

2、WSGI 没有官方的实现, 因为WSGI更像一个协议。 只要遵照这些协议, WSGI应用(Application)都可以在任何服务器(Server)上运行, 反之亦然。

3、WSGI允许开发者将选择web框架和web服务器分开,web服务器必须具备WSGI接口。

4、示例:浏览器请求动态页面过程

二、Web动态服务器代码示例

1、目录结构

2、服务器 MyWebServer.py

  1 # coding:utf-8
  2
  3 import socket
  4 import re
  5 import sys
  6
  7 from multiprocessing import Process
  8
  9 # 设置框架文件根目录
 10 FRAMEWORK_DIR = "./Frameworks"
 11
 12
 13 class HTTPServer(object):
 14     """web服务器"""
 15     def __init__(self, application):
 16         """构造函数, application指的是框架的app"""
 17         self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 18         # 服务端close时释放端口
 19         self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 20         # web框架
 21         self.app = application
 22         # 响应头
 23         self.response_headers = ""
 24
 25     def start(self):
 26         """服务器启动"""
 27         self.server_socket.listen(128)
 28         while True:
 29             client_socket, client_address = self.server_socket.accept()
 30             # print("[%s : %s]用户连接上了" % (client_address[0],client_address[1]))
 31             print("[%s, %s]用户连接上了\r\n" % client_address)
 32             # 开启多进程,处理客户端请求
 33             handle_client_process = Process(target=self.handle_client, args=(client_socket,))
 34             handle_client_process.start()
 35             client_socket.close()
 36
 37     def start_response(self, status, headers):
 38         """传递给web框架的方法(回调),用来获得框架返回的状态、headers"""
 39         response_headers = "HTTP/1.1 " + status + "\r\n"
 40         for header in headers:
 41             response_headers += "%s: %s\r\n" % header
 42         # 在服务器中记录框架返回的响应头
 43         self.response_headers = response_headers
 44
 45     def handle_client(self, client_socket):
 46         """处理客户端请求"""
 47
 48         # 获取客户端请求数据
 49         request_data = client_socket.recv(1024)
 50         print("客户端的请求数据:\r\n", request_data.decode("utf-8"))
 51         request_lines = request_data.splitlines()
 52         print("将请求数据按照每一行切片:\r\n")
 53         for index in range(len(request_lines)-1):
 54             print("第%d行: %s"%(index+1,request_lines[index].decode("utf-8")))
 55
 56         # 解析请求报文:提取用户请求的文件名、方法名
 57         request_start_line = request_lines[0]
 58         print(request_start_line.decode("utf-8"))
 59         file_name = re.match(r"\w+ +(/[^ ]*) ", request_start_line.decode("utf-8")).group(1)
 60         method = re.match(r"(\w+) +/[^ ]* ", request_start_line.decode("utf-8")).group(1)
 61         env = {
 62             "PATH_INFO": file_name,
 63             "METHOD": method
 64         }
 65
 66         # 传入请求参数和响应回调方法,获得响应体内容:此处把对象当做函数直接来用,会掉对象的__call__方法
 67         response_body = self.app(env, self.start_response)
 68
 69         # 拼接出完整的回复内容:响应头 + 响应体
 70         response = self.response_headers + "\r\n" + response_body
 71
 72         # 向客户端返回响应数据:python3中必须是 bytes()返回的bytes对象
 73         client_socket.send(bytes(response, "utf-8"))
 74
 75         # 关闭客户端连接
 76         client_socket.close()
 77
 78     def bind(self, port):
 79         self.server_socket.bind(("", port))
 80
 81
 82 def main():
 83
 84     # 增加检索包的路径
 85     sys.path.insert(1, FRAMEWORK_DIR)
 86
 87     # 获取程序启动参数
 88     if len(sys.argv) < 2:
 89         sys.exit("ERROR, you should input :python3 MyWebServer.py [Module]:app")
 90     module_name, app = sys.argv[1].split(":")
 91
 92     # 动态载入模块
 93     m = __import__(module_name)
 94
 95     # 获取模块中的属性:此处是web框架的实例对象
 96     app = getattr(m, app)
 97
 98     # 创建并开启服务器
 99     http_server = HTTPServer(app)
100     http_server.bind(8888)
101     http_server.start()
102
103
104 if __name__ == "__main__":
105     main()

3、web框架 MyWebFramework.py

  1 # coding:utf-8
  2
  3 import time
  4
  5 # from MyWebServer import HTTPServer
  6
  7 # 设置静态文件根目录
  8 HTML_ROOT_DIR = "./html"
  9
 10
 11 class Application(object):
 12     """框架的核心部分,也就是框架的主题程序,框架是通用的"""
 13     def __init__(self, urls):
 14         # 设置路由信息
 15         self.urls = urls
 16
 17     def __call__(self, env, start_response):
 18         """将类名当做函数来直接调用,重写此方法。此处方法的作用是返回给服务器响应体"""
 19
 20         # 获取文件名(路径),默认为"/"
 21         path = env.get("PATH_INFO", "/")
 22
 23         # 判断是静态还是动态文件
 24         if path.startswith("/static"):
 25             # 要访问静态文件: /static/index.html
 26             file_name = path[7:]
 27             # 打开文件,读取内容
 28             try:
 29                 file = open(HTML_ROOT_DIR + file_name, "rb")
 30             except IOError:
 31                 # 代表未找到路由信息,404错误
 32                 status = "404 Not Found"
 33                 headers = []
 34                 # 调用传入的回调方法,将状态和头部信息返回
 35                 start_response(status, headers)
 36                 # 直接返回响应体
 37                 return "Page not found"
 38             else:
 39                 # 读取文件内容
 40                 file_data = file.read()
 41                 file.close()
 42
 43                 # 设置响应内容
 44                 status = "200 OK"
 45                 headers = []
 46                 start_response(status, headers)
 47                 return file_data.decode("utf-8")
 48         else:
 49             # 访问动态文件,查询路由表中是否包含要执行的文件(是否有路由信息)
 50             for url, handler in self.urls:
 51                 if path == url:
 52                     # handler 即为路由表中映射的方法(非字符串)
 53                     return handler(env, start_response)
 54
 55             # 代表未找到路由信息,404错误
 56             status = "404 Not Found"
 57             headers = []
 58             start_response(status, headers)
 59             return "Program not found"
 60
 61
 62 def show_time(env, start_response):
 63     status = "200 OK"
 64     headers = [
 65         ("Content-Type", "text/plain")
 66     ]
 67     # 调用传入的回调方法,将状态和头部信息返回
 68     start_response(status, headers)
 69     return time.ctime()
 70
 71
 72 def print_hello(env, start_response):
 73     status = "200 OK"
 74     headers = [
 75         ("Content-Type", "text/plain")
 76     ]
 77     start_response(status, headers)
 78     return "hello everyone"
 79
 80
 81 def print_json(env, start_response):
 82     status = "200 OK"
 83     headers = [
 84         ("Content-Type", "text/plain")
 85     ]
 86     start_response(status, headers)
 87     jsonStr = "{\"code\":200,\"data\": {\"list\":[{\"firstName\":\"Qi\",\"lastName\":\"Zhang\"}]},\"msg\":\"OK\"}"
 88     return jsonStr
 89
 90
 91 def show_default(env, start_response):
 92     try:
 93         file = open(HTML_ROOT_DIR + "/index.html", "rb")
 94     except IOError:
 95         status = "404 Not Found"
 96         headers = []
 97         start_response(status, headers)
 98         return "DefaultPage not found"
 99     else:
100         file_data = file.read()
101         file.close()
102         status = "200 OK"
103         headers = []
104         start_response(status, headers)
105         return file_data.decode("utf-8")
106
107
108 # 路由信息,根据映射表,动态调用web框架中的方法
109 urls = [("/", show_default),
110         ("/time", show_time),
111         ("/hello", print_hello),
112         ("/json", print_json)]
113
114 # 通过路由表实例化对象(当前模块载入时就会创建),直接提供给服务器
115 app = Application(urls)

4、执行

(1)从业务和使用逻辑上,应该是“启动”服务器,所以运行服务器程序

(2)配置程序参数

(3)浏览器验证: 127.0.0.1:8888 、 json 127.0.0.1:8888/json  、127.0.0.1:8888/static/index.html

原文地址:https://www.cnblogs.com/cleven/p/10735243.html

时间: 2024-10-13 21:18:06

Python基础Web服务器案例的相关文章

Python的web服务器的程序设计

1. 使用python编写一个静态的web服务器,能够处理静态页面的http请求 原理: a. 使用socket进行服务端和浏览器之间的通信 b. 使用多线程处理多个客户端浏览器的请求 c. 使用http协议发送响应数据 实现: # coding:UTF-8 import socket from multiprocessing import Process def handle_request(client_socket): request_data = client_socket.recv(1

Python的web服务器

1.浏览器请求动态页面过程 2.WSGI Python Web Server Gateway Interface (或简称 WSGI,读作"wizgy"). WSGI允许开发者将选择web框架和web服务器分开.可以混合匹配web服务器和web框架,选择一个适合的配对.比如,可以在Gunicorn 或者 Nginx/uWSGI 或者 Waitress上运行 Django, Flask, 或 Pyramid.真正的混合匹配,得益于WSGI同时支持服务器和架构. web服务器必须具备WSG

小型公司访问web服务器案例

今天主要给大家带来一个小型公司的网络搭建,保证每一台计算机都可以访问www.ntd1711.com. 实验名称:小型公司网络的搭建 实验拓扑:实验目的:确保每个终端可以访问www.ntd1711.com(192.168.30.88)地址规划: 设备 IP地址及子网掩码 所属vlan 网关 PC1 192.168.10.1/24 VLAN10 192.168.10.254 PC2 192.168.20.2/24 VLAN20 192.168.20.254 PC3 192.168.10.3/24 V

python简易web服务器学习笔记(二)

import BaseHTTPServer #------------------------------------------------------------------------------- class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): '''Respond to HTTP requests with info about the request.''' # Template for page to sen

Python——轻量级web服务器flask的学习

前言: 根据工程需要,开始上手另一个python服务器---flask,flask是一个轻量级的python服务器,简单易用.将我的学习过程记录下来,有新的知识会及时补充. 记录只为更好的分享~ 正文: 首先在Linux下搭建flask环境,详见如下安装步骤: 安装教程 安装好后只需要编写python程序即可,现在开始第一个flaskweb程序: from flask import Flask app = Flask(__name__) @app.route('/') def hello_wor

python简易web服务器学习笔记(三)

import sys, os, BaseHTTPServer #------------------------------------------------------------------------------- class ServerException(Exception): '''For internal error reporting.''' pass #--------------------------------------------------------------

python对web服务器做压力测试并做出图形直观显示

压力测试有很多工具啊.apache的,还有jmeter, 还有loadrunner,都比较常用. 其实你自己用python写的,也足够用. 压力测试过程中要统计时间. 比如每秒的并发数,每秒的最大响应时间, 最小响应时间, 平均响应时间.最后再统一所有的请求完成后的上术参数. 将这些参数输出成CSV格式的文件. 如果不知道什么是CSV就是指将数据用引号包起来,中间用逗号分开,一系统数据放一行. 有了这个CSV文件,你用EXCEL打开来做图就可以. 如果你熟练,可以使用gnuplot这个命令行工具

2 web服务器案例

1.老师给的思路 #tcp socket 服务端 socket = socket.socket() socket.bind() socket.listen() client_socket = socket.accept() while True: p = Process(target=fun, args=()) p.start() client_socket.close() def fun(client_socket): #接受数据 #request_data = recv(1024) #pri

《Python入门》第一个Python Web程序——简单的Web服务器

上一篇讲了<Python入门>Windows 7下Python Web开发环境搭建笔记,接下来讲一下Python语言Web服务的具体实现:第一个Python Web程序--简单的Web服务器. 与其它Web后端语言不同,Python语言需要自己编写Web服务器. 如果你使用一些现有的框架的话,可以省略这一步: 如果你使用Python CGI编程的话,也可以省略这一步: 用Python建立最简单的web服务器 利用Python自带的包可以建立简单的web服务器.在DOS里cd到准备做服务器根目录