import socket
import re
import multiprocessing
import time
import dynamic.mini_frame
import sys
class WSGIServer(object):
def _init_(self,port,app,static_path):
# 1。创建套接字
self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp_server_socket.setsockopt(socket.SOL_SOCJET, socket.SOCK_REUSEADDR,1)
# 2。绑定
self.tcp_server_socket.bind(('', 7890))
# 3。变为监听套接字(最大链接书128)
self.tcp_server_socket.listen(128)
self.application = app
self.static_path = static_path
def service_client(self,new_socket):
# '''为这个客户端返回数据'''
# 1.接收浏览器发送出来的请求,即HTTP请求
# GET/HTTP/1.1
request = new_socket.recv(1024).decode('utf-8')
request_lines = request.splotlines()
print ('')
print ('>>>' *30)
print (request_lines)
# 新客户端链接
# GET/index.html HTTP/1.
# get post put del
ret = ret.match(r'[^/]+(/[^ ]*))', request_lines[0])
file_name = ''
if ret:
file_name = ret.group(1)
print ('*' *50, file_name)
if file_name == '/':
file_name = '/index.html'
# 2.返回HTTP格式的数据给浏览器
if not file_name.endswith('.py')
try:
f =open('self.static_path + file_name', 'rb')
# f = open('.../Desktop/项目/项目.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 准备发送给浏览器的Body
# response += 'hahaha'
# f = open('.../Desktop/项目/项目.html','rb')
# html_content = f.read()
# f.close()
# 将Response Header 发送给浏览器
new_socket.send(response.encode('utf-8'))
# 将Response Body 发送给浏览器
new_socket.send(html_content)
else:#如果是以。py 结尾,就认为是动态资源的请求
env = dict()
env['PATH_INFO'] = file_name
body = self.application(env,self.set_response_header)
header = 'HTTP/1.1 %s\r\n '% self.status
for temp in self.headers:
header += '%s:%s\r\n'%(temp[0],temp[1])
header += '\r\n'
response = header + body
new_socket.send(response.encode('utf-8'))
# 关闭客户端套接字
new_socket.close()
def set_response_header(self,status,headers):
self.status = status
self.headers = headers
self.headers += headers
def run_forver(self):
while True:
# 4。等待新客户端的链接
new_socket, client_addr = self.tcp_server_socket.accept()
# 局部变量
# 5。为这个客户端服务
# service_client()
p = multiprocessing.Process(target=service_client,args=(new_socket,))
p.start()
new_socket.close()
# 6。关闭监听套接字
self.tcp_server_socket.close()
def main():
#用来完成整体的控制,创建一个web 服务器对象。调用run_forver方法运行
if len(sys.argv) == 3:
try:
port = int(sys.argv[1])
frame_app_name = sys.argv[2]# 接收下面的mini_frame:appliction
except Exception as ret:
print('端口输入错误')
return
else:
print('请按照以下方式运行')
print('python web_server.py 7890 mini_frame:application')
return
#正则匹配。 ( 。*都要)
ret = re.match(r '([^:]):(.*)',frame_app_name)
if ret:
frame_name = ret.group(1)
app_name = ret.group(2)
else:
print('请按照以下方式运行')
print('python web_server.py 7890 mini_frame:application')
#需要重启时执行该命令
return
with open('./web_server.conf') as f :
conf_info = eval(f.read()) # 读取配置文件,转为字典
#此时con_info 是一个字典,里面数据为
# {
# 'static_path:'./static',
# 'dynamic_path':'./dynamic'
# }
sys.path.append(conf_info['dynamic_path']) # 选择其他方法寻找 mini——frame
# 相当于创建软连接
# import xxx
frame = __import__(frame_name) #返回值标记着导入的模块
app = getattr(frame,app_name) # 此时app就指向dynamic/miniframe 模块中的applictaion函数
#app 指application函数
#app_name 指上面 else 中的 application
print(app)
wsgi_server = WSGIServer(port,app,conf_info['static_path'])
wsgi_server.run_forver()
if __name__ =='__main__':
main()