文件目录:
dynamic中:框架
static:css,jss静态文件
teplates:模板
web_server.conf: 配置文件
web_server.py: 主程序
run.sh:运行脚本
web_server.py:
1 import socket 2 import multiprocessing 3 import re 4 import dynamic.mini_frame 5 import sys 6 7 class WSGIServer(object): 8 def __init__(self,port,app,static_path): 9 # 1.创建socket对象 10 self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 11 # 2.设置重复使用地址 12 self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 13 # 3.绑定端口 14 self.tcp_server_socket.bind(("", port)) 15 # 4.设置监听状态 16 self.tcp_server_socket.listen(128) 17 # web服务器模板中的application方法 18 self.application = app 19 # config文件 20 self.static_path = static_path 21 22 23 24 def clinet_server(self,new_client_socket): 25 # 1.接受消息 26 request = new_client_socket.recv(1024).decode("utf-8") 27 lines = request.splitlines() 28 # print("") 29 # print(">" * 20) 30 # print(lines) 31 # 2.匹配请求网页 32 request_name = re.match(r"[^/]+(/[^ ]*)",lines[0]) 33 if request_name: 34 file_name = request_name.group(1) 35 if file_name == "/": 36 file_name = "/index.html" 37 38 # 返回数据给浏览器 39 if not file_name.endswith(".py"): 40 # 3.打开文件 41 try: 42 f = open(self.static_path + file_name,"rb") 43 except Exception as ret: 44 pass 45 else: 46 html_content = f.read() 47 f.close() 48 # 4.创建header和body 49 response_body = html_content 50 response_header = "HTTP/1.1 200 ok " 51 response_header += "Content-Length:%d " % len(response_body) 52 response_header += " " 53 response = response_header.encode("utf-8") + response_body 54 # 5.发送 55 new_client_socket.send(response) 56 57 58 else: 59 # 如果是.py结尾,则认为是动态页面请求/ 60 env = dict(); 61 env['PATH_INFO'] = file_name 62 print(env['PATH_INFO']) 63 # application(字典, 方法名) 固定用法 64 body = self.application(env, self.start_respones_header) 65 # 拼装header头 66 header = "HTTP/1.1 %s " % self.status 67 for temp in self.headers: 68 header += "%s:%s " % (temp[0], temp[1]) 69 header += " " 70 # 拼装返回数据 71 response = header + body 72 # 发送数据 73 new_client_socket.send(response.encode("utf-8")) 74 75 # 6.关闭socket 76 new_client_socket.close() 77 78 def start_respones_header(self, status, headers): 79 """接受并保存application传过来的值""" 80 self.status = status 81 self.headers = [("server","mini_web v1.0")] 82 self.headers += headers 83 84 85 def run_forever(self): 86 """运行""" 87 while True: 88 # 5.接收客户地址,创建新socket 89 new_socket,client_addr = self.tcp_server_socket.accept() 90 # 6.为新客户端服务 91 p = multiprocessing.Process(target=self.clinet_server,args=(new_socket,)) 92 p.start() 93 # 7.关闭新客户端 94 new_socket.close() 95 # 7.关闭socket 96 self.tcp_server_socket.close() 97 98 def main(): 99 # 给程序传参数, 导入sys库 100 ret = sys.argv 101 if len(ret) == 3: 102 # 接收端口信息 103 port = int(ret[1]) 104 # 接收web服务器信息 105 frame_app_name = ret[2] 106 else: 107 print("请重新输入参数") 108 # web服务器包和名 109 frame_app = re.match(r"([^:]+):([^:]+)",frame_app_name) 110 frame_name = frame_app.group(1) 111 app_name = frame_app.group(2) 112 113 # 导入包的路径 114 sys.path.append("./dynamic") 115 # 导入模板 116 frame = __import__(frame_name) 117 # 此时app指向了 dynamic/mini_frame模板中的application这个函数 118 app = getattr(frame,app_name) 119 120 with open("web_server.conf","r") as f: 121 # eval() 把{"xx":"xx"} 这种字符串转化为字典 122 config_path = eval(f.read()) 123 124 wsgi_server = WSGIServer(port,app,config_path['static_path']) 125 wsgi_server.run_forever() 126 127 128 if __name__ == '__main__': 129 main()
mini_frame.py:
1 def center(): 2 with open("./templates/center.html","r") as f: 3 return f.read() 4 5 def index(): 6 with open("./templates/index.html", "r") as f: 7 return f.read() 8 9 def application(env, start_respones): 10 start_respones('200 ok',[("Content-Type","text/html;charset=utf-8")]) 11 file_name = env['PATH_INFO'] 12 # print(file_name) 13 if file_name == "/index.py": 14 return index() 15 elif file_name == "/center.py": 16 return center() 17 else: 18 return "python 中国"
web_server.conf:
{ "static_path":"./static", "dynamic_path":"./dynamic" }
run.sh:
python3 web_server.py 7788 mini_frame:application