服务器代码
import socket
import re
import multiprocessing
import mini_web_06
class WebServer(object):
#一个功能一个函数
#相关的功能合成一个类
def __init__(self):
# 1. 创建套接字
self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 2. 绑定
self.tcp_server_socket.bind(("", 7890))
# 3. 变为监听套接字
self.tcp_server_socket.listen(128)
def service_client(self,new_socket):
"""为这个客户端返回数据"""
# 1. 接收浏览器发送过来的请求 ,即http请求
# GET / HTTP/1.1
# .....
request = new_socket.recv(1024).decode("utf-8")
# print(">>>"*50)
# print(request)
request_lines = request.splitlines()
print("")
print(">"*20)
print(request_lines)
# GET /index.html HTTP/1.1
# get post put del
file_name = ""
ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0])
if ret:
file_name = ret.group(1)
# print("*"*50, file_name)
if file_name == "/":
file_name = "/index.html"
#判断静态或者动态
#.py这个是动态
if file_name.endswith(".py"):
# 调用一个函数得到一个body结果
#创建一个字典
url_dict = dict()
url_dict['file_name'] = file_name
body = mini_web_06.application(url_dict,self.head_params)
#根据不同的地址返回不同的页面
head = "HTTP/1.1 %s\r\n"%self.stauts
#把头部的字段拼接
for temp in self.params:
head += "%s:%s\r\n"%(temp[0],temp[1])
#发送
content = head + "\r\n" + body
new_socket.send(content.encode("utf-8"))
else:
# 2. 返回http格式的数据,给浏览器
try:
f = open("./html" + file_name, "rb")
except:
response = "HTTP/1.1 404 NOT FOUND\r\n"
response += "\r\n"
response += "------file not found-----"
new_socket.send(response.encode("utf-8"))
else:
html_content = f.read()
f.close()
# 2.1 准备发送给浏览器的数据---header
response = "HTTP/1.1 200 OK\r\n"
response += "\r\n"
# 2.2 准备发送给浏览器的数据---boy
# response += "hahahhah"
# 将response header发送给浏览器
new_socket.send(response.encode("utf-8"))
# 将response body发送给浏览器
new_socket.send(html_content)
# 关闭套接
new_socket.close()
def run_server(self):
"""用来完成整体的控制"""
while True:
# 4. 等待新客户端的链接
new_socket, client_addr = self.tcp_server_socket.accept()
# 5. 为这个客户端服务
p = multiprocessing.Process(target=self.service_client, args=(new_socket,))
p.start()
new_socket.close()
# 关闭监听套接字
tcp_server_socket.close()
def head_params(self,stauts,params):
#存数据
self.stauts = stauts
self.params = params
def main():
server = WebServer()
server.run_server()
if name == “main“:
main()
web_mini框架代码
根据不同不地址返回不同的内容
environ这是服务器给框架传数据,用字典的方式
start_response:框架给服务器传响应头
return这个就是响应体
定义一个空的字典用来存地址跟引用的关系
import re
url_dict = dict()
def route(file_name):
def set_fun(func):
def call_fun(*args, **kwargs):
return func(*args, **kwargs)
# 存起来
url_dict[file_name] = call_fun
return call_fun
return set_fun
@route(“/index.py”)
def index(match):
return “index show page!”
@route(“/center.py”)
def center(match):
return “center show page!”
@route(r”/add/(\d+).py”) #多个地址对应一个函数/add/8998.py
def add(match):
return “add%s”%match.group(1)
def application(environ, start_response):
start_response(‘200 OK’, [(‘Content-Type’, ‘text/html’), (“author”, “oldyang”)])
# 根据不同的地址返回不同的内容
file_name = environ[‘file_name’]
# 多个if使用字典去替换
# url_dict = {"/index.py":index,"/center.py":center}
#用正则去循环去字典去匹配地址,如果匹配到了数据返回
for key,func in url_dict.items():
#正则
match = re.match(key,file_name) #路径匹配
if match:
#说明匹配到了
return func(match)
#到没有匹配
return "not page is find!"