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写的,也足够用. 压力测试过程中要统计时间. 比如每秒的并发数,每秒的最大响应 ...
随机推荐
- Webdriver测试脚本1(打开网页并打印标题)
案例: 启动火狐浏览器 首页打开博客园页面,打印网页标题,等待3秒 打开百度首页,打印网页标题,再等待2秒 关闭浏览器 from selenium import webdriver from time ...
- 计算1+2+...+100之和<for循环的学习>
#include <stdio.h> /* 计算1+2+....+100 soulsjie 20170525 */ void main(){ int i; int s=0; for(i=0 ...
- bzoj 1413 [ZJOI2009]取石子游戏
1413: [ZJOI2009]取石子游戏 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 747 Solved: 490[Submit][Statu ...
- [转]如何阅读android framework源码
但如果想深入的了解Android系统, 那么可以看下我的一些简单的总结. 知识 Java Java是AOSP的主要语言之一. 没得说, 必需熟练掌握. 熟练的Android App开发 Linux A ...
- [NOIP2004] 提高组 洛谷P1089 津津的储蓄计划
题目描述 津津的零花钱一直都是自己管理.每个月的月初妈妈给津津300元钱,津津会预算这个月的花销,并且总能做到实际花销和预算的相同. 为了让津津学习如何储蓄,妈妈提出,津津可以随时把整百的钱存在她那里 ...
- 【CodeChef】KNGHTMOV(方案数DP)
题意: 考虑一张无限大的方格棋盘.我们有一个“骑士”,它必须从(0,0)格开始,按照如下规则,移动至(X,Y)格:每一步,它只能从(u,v)格移动至(u+Ax,v+Ay)或者(u+Bx,v+By).注 ...
- codevs1128 导弹拦截
题目描述 Description 经过11 年的韬光养晦,某国研发出了一种新的导弹拦截系统,凡是与它的距离不超过其工作半径的导弹都能够被它成功拦截.当工作半径为0 时,则能够拦截与它位置恰好相同的导弹 ...
- jquery判断单选按钮radio是否选中的方法
JQuery控制radio选中和不选中方法总结 一.设置选中方法 复制代码代码如下: $("input[name='名字']").get(0).checked=true; $(&q ...
- hdu - 1172 猜数字 (思维题)
http://acm.hdu.edu.cn/showproblem.php?pid=1172 这个题换一种想法,可以找出四位数中所有满足条件的数看是否只有一个. #include <iostre ...
- Java并发包——使用新的方式创建线程
Java并发包——使用新的方式创建线程 摘要:本文主要学习了如何使用Java并发包中的类创建线程. 部分内容来自以下博客: https://www.cnblogs.com/dolphin0520/p/ ...