静态服务器加载的是一个静态html页面,或者是存在服务器的中的静态数据,动态服务器是,当客户端发送一个请求,服务器拿到这个请求找到相关的程序代码执行,将执行结果返回给客户端的一个过程
下面看看动态服务器执行的过程
WSGI
怎么在你刚刚建立的web服务器上运行一个Django应用和一个Flask应用呢。如何做不做任何改变而适应不同的web架构呢。
在以前,选择PYTHON WEB架构会限制可用的web服务器,反之亦然。
如果架构和服务器可以协同工作就好了
那么怎么不修改服务器架构代码而确保可以运行web服务器呢,答案是Python Web server Gataway Interface简称WSGI
WSGI的接口定义非常简单,他只要求Web开发者实现一个函数。就可以响应web请求。我们来看一下最简单的代码
def applicaiton(env, start_response):
# env.get("Method")
# env.get("PATH_INFO")
# env.get("QUERY_STRING")
status = "200 OK"
headers = [
("Content-Type", "text/plain")
]
start_response(status, headers)
return time.ctime()
下面的代码演示一个动态服务器的代码
import socket
import re
import sys
from multiprocessing import Process
# 设置静态文件根目录
HTML_ROOT_DIR = "./html"
WISG_PYTHON_DIR ='./wsgipython'
class HTTPServer(object):
""""""
def __init__(self):
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
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]用户连接上了" % 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):
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("request data:", request_data)
request_lines = request_data.splitlines()
for line in request_lines:
print(line)
# 解析请求报文
# 'GET / HTTP/1.1'
request_start_line = request_lines[0]
# 提取用户请求的文件名
print("*" * 10)
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)
if file_name.endswith('.py'):
# //给一个包名或者模块名,就可以返回一个模块
#env是我们解析请求报文所拿到的相关数据;实际我们需要传入更多的参数。
m= __import__(file_name[1:-3])
env={
'PATH_INFO':file_name,
'METHOD':method
}
#env是本次请求的相关信息,。
response_body=m.applicaiton(env,self.start_response)
response = self.response_headers+'\r\n'+response_body
else:
if "/" == file_name:
file_name = "/index.html"
# 打开文件,读取内容
try:
file = open(HTML_ROOT_DIR + file_name, "rb")
except IOError:
response_start_line = "HTTP/1.1 404 Not Found\r\n"
response_headers = "Server: My server\r\n"
response_body = "The file is not found!"
else:
file_data = file.read()
file.close()
# 构造响应数据
response_start_line = "HTTP/1.1 200 OK\r\n"
response_headers = "Server: My server\r\n"
response_body = file_data.decode("utf-8")
response = response_start_line + response_headers + "\r\n" + response_body
print("response data:", response)
# 向客户端返回响应数据
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,WISG_PYTHON_DIR)
http_server = HTTPServer()
# http_server.set_port
http_server.bind(8200)
http_server.start()
if __name__ == "__main__":
main()
我们需要动态执行代码,我们写在一个.py文件中,我现在给这个文件卸载ctime.py
# coding:utf-8
import time
# "/ctime.py?timezone=e8"
# "/ctime.py?timezone=e1"
#application的返回值会作为服务器返回报文中的响应体部分。
#wsg协议中要决定,响应头头报文。
def applicaiton(env, start_response):
# env.get("Method")
# env.get("PATH_INFO")
# env.get("QUERY_STRING")
status = "200 OK"
headers = [
("Content-Type", "text/plain")
]
start_response(status, headers)
return time.ctime()
当我们在浏览器地址栏输入http://127.0.0.1:8200/ctime.py,就可以显示了一个时间信息。