一、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

 # coding:utf-8

 import socket
import re
import sys from multiprocessing import Process # 设置框架文件根目录
FRAMEWORK_DIR = "./Frameworks" class HTTPServer(object):
"""web服务器"""
def __init__(self, application):
"""构造函数, application指的是框架的app"""
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 服务端close时释放端口
self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# web框架
self.app = application
# 响应头
self.response_headers = "" def start(self):
"""服务器启动"""
self.server_socket.listen(128)
while True:
client_socket, client_address = self.server_socket.accept()
# print("[%s : %s]用户连接上了" % (client_address[0],client_address[1]))
print("[%s, %s]用户连接上了\r\n" % client_address)
# 开启多进程,处理客户端请求
handle_client_process = Process(target=self.handle_client, args=(client_socket,))
handle_client_process.start()
client_socket.close() def start_response(self, status, headers):
"""传递给web框架的方法(回调),用来获得框架返回的状态、headers"""
response_headers = "HTTP/1.1 " + status + "\r\n"
for header in headers:
response_headers += "%s: %s\r\n" % header
# 在服务器中记录框架返回的响应头
self.response_headers = response_headers def handle_client(self, client_socket):
"""处理客户端请求""" # 获取客户端请求数据
request_data = client_socket.recv(1024)
print("客户端的请求数据:\r\n", request_data.decode("utf-8"))
request_lines = request_data.splitlines()
print("将请求数据按照每一行切片:\r\n")
for index in range(len(request_lines)-1):
print("第%d行: %s"%(index+1,request_lines[index].decode("utf-8"))) # 解析请求报文:提取用户请求的文件名、方法名
request_start_line = request_lines[0]
print(request_start_line.decode("utf-8"))
file_name = re.match(r"\w+ +(/[^ ]*) ", request_start_line.decode("utf-8")).group(1)
method = re.match(r"(\w+) +/[^ ]* ", request_start_line.decode("utf-8")).group(1)
env = {
"PATH_INFO": file_name,
"METHOD": method
} # 传入请求参数和响应回调方法,获得响应体内容:此处把对象当做函数直接来用,会掉对象的__call__方法
response_body = self.app(env, self.start_response) # 拼接出完整的回复内容:响应头 + 响应体
response = self.response_headers + "\r\n" + response_body # 向客户端返回响应数据:python3中必须是 bytes()返回的bytes对象
client_socket.send(bytes(response, "utf-8")) # 关闭客户端连接
client_socket.close() def bind(self, port):
self.server_socket.bind(("", port)) def main(): # 增加检索包的路径
sys.path.insert(1, FRAMEWORK_DIR) # 获取程序启动参数
if len(sys.argv) < 2:
sys.exit("ERROR, you should input :python3 MyWebServer.py [Module]:app")
module_name, app = sys.argv[1].split(":") # 动态载入模块
m = __import__(module_name) # 获取模块中的属性:此处是web框架的实例对象
app = getattr(m, app) # 创建并开启服务器
http_server = HTTPServer(app)
http_server.bind(8888)
http_server.start() if __name__ == "__main__":
main()

3、web框架 MyWebFramework.py

 # coding:utf-8

 import time

 # from MyWebServer import HTTPServer

 # 设置静态文件根目录
HTML_ROOT_DIR = "./html" class Application(object):
"""框架的核心部分,也就是框架的主题程序,框架是通用的"""
def __init__(self, urls):
# 设置路由信息
self.urls = urls def __call__(self, env, start_response):
"""将类名当做函数来直接调用,重写此方法。此处方法的作用是返回给服务器响应体""" # 获取文件名(路径),默认为"/"
path = env.get("PATH_INFO", "/") # 判断是静态还是动态文件
if path.startswith("/static"):
# 要访问静态文件: /static/index.html
file_name = path[7:]
# 打开文件,读取内容
try:
file = open(HTML_ROOT_DIR + file_name, "rb")
except IOError:
# 代表未找到路由信息,404错误
status = "404 Not Found"
headers = []
# 调用传入的回调方法,将状态和头部信息返回
start_response(status, headers)
# 直接返回响应体
return "Page not found"
else:
# 读取文件内容
file_data = file.read()
file.close() # 设置响应内容
status = "200 OK"
headers = []
start_response(status, headers)
return file_data.decode("utf-8")
else:
# 访问动态文件,查询路由表中是否包含要执行的文件(是否有路由信息)
for url, handler in self.urls:
if path == url:
# handler 即为路由表中映射的方法(非字符串)
return handler(env, start_response) # 代表未找到路由信息,404错误
status = "404 Not Found"
headers = []
start_response(status, headers)
return "Program not found" def show_time(env, start_response):
status = "200 OK"
headers = [
("Content-Type", "text/plain")
]
# 调用传入的回调方法,将状态和头部信息返回
start_response(status, headers)
return time.ctime() def print_hello(env, start_response):
status = "200 OK"
headers = [
("Content-Type", "text/plain")
]
start_response(status, headers)
return "hello everyone" def print_json(env, start_response):
status = "200 OK"
headers = [
("Content-Type", "text/plain")
]
start_response(status, headers)
jsonStr = "{\"code\":200,\"data\": {\"list\":[{\"firstName\":\"Qi\",\"lastName\":\"Zhang\"}]},\"msg\":\"OK\"}"
return jsonStr def show_default(env, start_response):
try:
file = open(HTML_ROOT_DIR + "/index.html", "rb")
except IOError:
status = "404 Not Found"
headers = []
start_response(status, headers)
return "DefaultPage not found"
else:
file_data = file.read()
file.close()
status = "200 OK"
headers = []
start_response(status, headers)
return file_data.decode("utf-8") # 路由信息,根据映射表,动态调用web框架中的方法
urls = [("/", show_default),
("/time", show_time),
("/hello", print_hello),
("/json", print_json)] # 通过路由表实例化对象(当前模块载入时就会创建),直接提供给服务器
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

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

  1. python之Web服务器案例

    HTTP协议简介 1. 使用谷歌/火狐浏览器分析 在Web应用中,服务器把网页传给浏览器,实际上就是把网页的HTML代码发送给浏览器,让浏览器显示出来.而浏览器和服务器之间的传输协议是HTTP,所以: ...

  2. python网络-动态Web服务器案例(30)

    一.浏览器请求HTML页面的过程 了解了HTTP协议和HTML文档,其实就明白了一个Web应用的本质就是: 浏览器发送一个HTTP请求: 服务器收到请求,生成一个HTML文档: 服务器把HTML文档作 ...

  3. python网络-静态Web服务器案例(29)

    一.静态Web服务器案例代码static_web_server.py # coding:utf-8 # 导入socket模块 import socket # 导入正则表达式模块 import re # ...

  4. Python搭建Web服务器,与Ajax交互,接收处理Get和Post请求的简易结构

    用python搭建web服务器,与ajax交互,接收处理Get和Post请求:简单实用,没有用框架,适用于简单需求,更多功能可进行扩展. python有自带模块BaseHTTPServer.CGIHT ...

  5. python写web服务器

    #coding = utf-8 from http.server import BaseHTTPRequestHandler, HTTPServer class RequestHandler(Base ...

  6. (转)Python的web服务器

    1.浏览器请求动态页面过程 2.WSGI Python Web Server Gateway Interface (或简称 WSGI,读作“wizgy”). WSGI允许开发者将选择web框架和web ...

  7. Python的web服务器

    1.浏览器请求动态页面过程 2.WSGI Python Web Server Gateway Interface (或简称 WSGI,读作“wizgy”). WSGI允许开发者将选择web框架和web ...

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

    前言: 根据工程需要,开始上手另一个python服务器---flask,flask是一个轻量级的python服务器,简单易用.将我的学习过程记录下来,有新的知识会及时补充. 记录只为更好的分享~ 正文 ...

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

    压力测试有很多工具啊.apache的,还有jmeter, 还有loadrunner,都比较常用. 其实你自己用python写的,也足够用. 压力测试过程中要统计时间. 比如每秒的并发数,每秒的最大响应 ...

随机推荐

  1. form 表单onclick事件 禁止表单form提交

    最近遇到一次处理form数据的过滤,采用了button的onclick事件来检查,发现return false后表单仍然提交了. 于是仔细研究了下onclick.onsubmit.submit集合函数 ...

  2. 牛客网NOIP赛前集训营 第6场 T1 最长路

    [题解] 先建反向图,然后跑拓扑排序求出最长路. 将所有的点按照最长路从小到大分层,把上一层连向这一层的边按照边权为第一关键字.起点的排名为第二关键字排序. 按照这个顺序更新这一层的答案,按照这一层每 ...

  3. IIS 注册.NET Framework 4.0 命令

    cmd执行以下命令 32位Windows:C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -i 64位Windows:C ...

  4. KNN-K近邻算法(1)

    KNN(K-nearest neighbors) 思想简单 数学所需知识少(近零) 效果好 可解释机器学习算法使用过程中的很多细节问题 更完整的刻画机器学习应用的流程 天然可解决多分类问题 可解决回归 ...

  5. [OJ#39]左手右手

    [OJ#39]左手右手 试题描述 有 n 个人,每个人左右手上各写着一个整数.对于编号为 a 的人和编号为 b 的人, a 对 b 的好感度等于 a 左手上写的数字乘 b 右手上写的数字,a 和 b  ...

  6. noip模拟赛 道路分组

    分析:因为每一组编号都是连续的嘛,所以能分成一组的尽量分,每次加边后dfs判断一下1和n是否连通.有向图的判连通没有什么很快的方法,特别注意,并查集是错的!这个算法可以得到60分. 事实上每一次都不需 ...

  7. poj 1752 Advertisement (差分约束)

    题目大意:题目大意:有n个人在一条路上跑步,广告商准备在这条路上设置广告牌,假设这条路上每一个点有一个广告牌 现在已知这n个人从Ai开始跑,到Bi结束,那么他可以看到max(Ai,Bi)-min(Ai ...

  8. 转 POJ分类

    OJ上的一些水题(可用来练手和增加自信) (poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094)初期: 一. ...

  9. Rooks-LightOj1005(规律)

    A rook is a piece used in the game of chess which is played on a board of square grids. A rook can o ...

  10. codevs——2147 数星星

    2147 数星星  时间限制: 3 s  空间限制: 64000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description 小明是一名天文爱好者,他喜欢晚上看星星 ...