|
Python动态服务器网页(需要使用WSGI接口),基本实现步骤如下:
1.等待客户端的链接,服务器会收到一个http协议的请求数据报
2.利用正则表达式对这个请求数据报进行解析(请求方式、提取出文件的环境)
3.提取出文件的环境之后,利用截断取片的方法将文件名转化为模块名称
4.使用m = __import__(),就可以得到返回值为m的模块
5.创建一个env字典:其中包含的是请求方式及文件环境等各种的键值对
6.创建一个新的动态脚本,其中定义了application这个函数,必须包含env和start_response的参数(也是服务器里的调用方法)
7.在这个动态脚本中定义状态码status和响应头headers(注意是字典形式,如Content-Type)
8.然后再调用start_response(status,headers),但是要注意,这个函数在服务器被定义
9.在动态脚本中编写动态执行程序
10.m.appliction的返回值就是回应数据包的body,它的数据头在start_response被整合
11.将数据头与数据body拼接起来,然后发送给客户端,就可显示动态网页
MyWebServer- import socket
- import re
- import sys
-
- from multiprocessing import Process
- from MyWebFramework import Application
-
- # 设置静态文件根目录
- HTML_ROOT_DIR = "./html"
- WSGI_PYTHON_DIR = "./wsgipython"
-
- class HTTPServer(object):
- """"""
- def __init__(self, application):
- """构造函数, application指的是框架的app"""
- self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- self.app = application
-
- 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):
- """
- status = "200 OK"
- headers = [
- ("Content-Type", "text/plain")
- ]
- star
- """
- 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)
-
- env = {
- "PATH_INFO": file_name,
- "METHOD": method
- }
- response_body = self.app(env, self.start_response)
- response = self.response_headers + "\r\n" + response_body
-
- # 向客户端返回响应数据
- 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, WSGI_PYTHON_DIR)
- if len(sys.argv) < 2:
- sys.exit("python MyWebServer.py Module:app")
- # python MyWebServer.py MyWebFrameWork:app
- module_name, app_name = sys.argv[1].split(":")
- # module_name = "MyWebFrameWork"
- # app_name = "app"
- m = __import__(module_name)
- app = getattr(m, app_name)
- http_server = HTTPServer(app)
- # http_server.set_port
- http_server.bind(8000)
- http_server.start()
-
- if __name__ == "__main__":
- main()
复制代码 MyWebFrameWork- 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", "/")
- # /static/index.html
- if path.startswith("/static"):
- # 要访问静态文件
- 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 "not found"
- else:
- file_data = file.read()
- file.close()
-
- status = "200 OK"
- headers = []
- start_response(status, headers)
- return file_data.decode("utf-8")
-
- for url, handler in self.urls:
- #("/ctime", show_ctime)
- if path == url:
- return handler(env, start_response)
-
- # 代表未找到路由信息,404错误
- status = "404 Not Found"
- headers = []
- start_response(status, headers)
- return "not found"
-
- def show_ctime(env, start_response):
- status = "200 OK"
- headers = [
- ("Content-Type", "text/plain")
- ]
- start_response(status, headers)
- return time.ctime()
-
- def say_hello(env, start_response):
- status = "200 OK"
- headers = [
- ("Content-Type", "text/plain")
- ]
- start_response(status, headers)
- return "hello itcast"
-
- def say_haha(env, start_response):
- status = "200 OK"
- headers = [
- ("Content-Type", "text/plain")
- ]
- start_response(status, headers)
- return "hello haha"
-
- urls = [
- ("/", show_ctime),
- ("/ctime", show_ctime),
- ("/sayhello", say_hello),
- ("/sayhaha", say_haha),
- ]
- app = Application(urls)
- # if __name__ == "__main__":
- # urls = [
- # ("/", show_ctime),
- # ("/ctime", show_ctime),
- # ("/sayhello", say_hello),
- # ("/sayhaha", say_haha),
- # ]
- # app = Application(urls)
- # http_server = HTTPServer(app)
- # http_server.bind(8000)
- # http_server.start()
复制代码 来源:https://www.cnblogs.com/djdjdj123/p/17329903.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
|