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
# 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服务器案例的更多相关文章
- python之Web服务器案例
HTTP协议简介 1. 使用谷歌/火狐浏览器分析 在Web应用中,服务器把网页传给浏览器,实际上就是把网页的HTML代码发送给浏览器,让浏览器显示出来.而浏览器和服务器之间的传输协议是HTTP,所以: ...
- python网络-动态Web服务器案例(30)
一.浏览器请求HTML页面的过程 了解了HTTP协议和HTML文档,其实就明白了一个Web应用的本质就是: 浏览器发送一个HTTP请求: 服务器收到请求,生成一个HTML文档: 服务器把HTML文档作 ...
- python网络-静态Web服务器案例(29)
一.静态Web服务器案例代码static_web_server.py # coding:utf-8 # 导入socket模块 import socket # 导入正则表达式模块 import re # ...
- Python搭建Web服务器,与Ajax交互,接收处理Get和Post请求的简易结构
用python搭建web服务器,与ajax交互,接收处理Get和Post请求:简单实用,没有用框架,适用于简单需求,更多功能可进行扩展. python有自带模块BaseHTTPServer.CGIHT ...
- python写web服务器
#coding = utf-8 from http.server import BaseHTTPRequestHandler, HTTPServer class RequestHandler(Base ...
- (转)Python的web服务器
1.浏览器请求动态页面过程 2.WSGI Python Web Server Gateway Interface (或简称 WSGI,读作“wizgy”). WSGI允许开发者将选择web框架和web ...
- Python的web服务器
1.浏览器请求动态页面过程 2.WSGI Python Web Server Gateway Interface (或简称 WSGI,读作“wizgy”). WSGI允许开发者将选择web框架和web ...
- Python——轻量级web服务器flask的学习
前言: 根据工程需要,开始上手另一个python服务器---flask,flask是一个轻量级的python服务器,简单易用.将我的学习过程记录下来,有新的知识会及时补充. 记录只为更好的分享~ 正文 ...
- python对web服务器做压力测试并做出图形直观显示
压力测试有很多工具啊.apache的,还有jmeter, 还有loadrunner,都比较常用. 其实你自己用python写的,也足够用. 压力测试过程中要统计时间. 比如每秒的并发数,每秒的最大响应 ...
随机推荐
- rbac组件之权限操作(四)
对于权限表的操作有两种方式,第一种是一个个的权限进行curd,另外一种是批量操作,自动发现django程序中的路由,进行批量curd,首先介绍第一种方式. 因为在列出菜单时,已经将权限列表列出来了,所 ...
- 版本控制git之一 仓库管理 安装 基础
版本控制git之一-仓库管理 git 再开始这个话题之前,让我想起了一件很痛苦的事情,在我大学写毕业论文的时候,我当时的文件是这样保存的 毕业论文_初稿.doc 毕业论文_修改1.doc 毕业 ...
- Python中的列表(3)
我们创建的列表元素的顺序是无法预测的,因为我们无法控制用户提供数据的顺序. 为了组织列表中的元素,所以Python帮我们提供一些方法用来排序列表中的元素. 1.方法 sort() 可以对列表永久性排序 ...
- Linux 网卡配置
网卡配置(环境CentOS 6.7) 图形界面修改: # 在命令行直接输入setup进入配置 1.[root@mingyaun ~]# setup 2.NetWork configuration 3. ...
- HDU 5492 Find a path
Find a path Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID ...
- Android RoundedBitmapDrawable:Android官方的圆角图形图象实现方案
Android RoundedBitmapDrawable:Android官方的圆角图形图象实现方案 RoundedBitmapDrawable是Android在support v4的扩展包中新 ...
- SQL Server-索引管理
http://www.2cto.com/database/201305/207508.html SQL Server-索引管理 一.显示索引信息 在建立索引后,可以对表索引信息进行查询. (1)在 ...
- [BZOJ1264][AHOI2006]基因匹配Match(DP + 树状数组)
传送门 有点类似LCS,可以把 a[i] 在 b 串中的位置用一个链式前向星串起来,由于链式前向星是从后往前遍历,所以可以直接搞. 状态转移方程 f[i] = max(f[j]) + 1 ( 1 &l ...
- Netbeans工具使用记录
#自动换行设置 工具->选项->编辑器->格式设置
- Codeforces700C. Break Up
n<=1000,m<=30000的图,问割掉边权和尽量小的0.1或2条边使S和T不连通,输出割了哪些边,无解-1. 道理是很好懂的,先随便找S到T的一条路径,找不到输出0,找到的话这条路上 ...