"""
webserver.py
使用面向对象的方法来做多进程的web server
"""
import socket
import re
import multiprocessing
class WSGIServer(object):
"""服务器对象"""
def __init__(self):
# 创建套接字
self.tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定ip和port
self.tcp_server.bind(("", 8080))
# 设置成监听模式
self.tcp_server.listen(128)
def service_client(self, new_socket):
# 接受数据
data = new_socket.recv(1024).decode("utf-8")
# print(data.decode("utf-8"))
data_list = data.splitlines()
# print(data_list[0])
# 正则匹配出文件名 'GET /img/home/tour8.jpg HTTP/1.1',
ret = re.match(r"[^/]+(/[^ ]*)",data_list[0])
print(ret)
file_name = ""
if ret:
file_name = ret.group(1)
print(file_name)
if file_name == "/":
file_name = "/index.html"
try:
# 打开文件
f = open("..//..//static/html/Trave" + file_name, "rb")
except:
response = "HTTP/1.1 404 NOT FOUND\r\n"
response += "\r\n"
response += "Not Found"
# 发送文件 header
new_socket.send(response.encode("utf-8"))
else:
# 传递数据
response = "HTTP:/1.1 200 OK\r\n"
response += "\r\n"
data_contend = f.read()
f.close()
# 发送文件 header
new_socket.send(response.encode("utf-8"))
# 发送文件body
new_socket.send(data_contend)
# 关闭套接字
new_socket.close()
def run_forerver(self):
"""使程序一直运行"""
while True:
# 等待客户端连接
new_client, addr = self.tcp_server.accept()
p = multiprocessing.Process(target=self.service_client, args=(new_client, ))
# 接受客户端的消息 回复客户端的消息
# service_client(new_client)
p.start()
new_client.close() # 多进程中会复制一份这个变量,所以要在主进程中也要关闭
self.tcp_server.close()
def main():
"""控制整体流程 --> 创建一个对象 --> 调用这个对象的run_forerver方法"""
wsgi_server = WSGIServer()
wsgi_server.run_forerver()
if __name__ == "__main__":
main()
解释:当浏览器请求文件以.py结尾的就当做动态网页
代码
"""
webserver.py
使用面向对象的方法来做多进程的web server 继承了动态的解析功能
当请求文件结尾以.py结尾的为动态网页
"""
import socket
import re
import multiprocessing
import time
class WSGIServer(object):
"""服务器对象"""
def __init__(self):
# 创建套接字
self.tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定ip和port
self.tcp_server.bind(("", 8080))
# 设置成监听模式
self.tcp_server.listen(128)
def service_client(self, new_socket):
# 接受数据
data = new_socket.recv(1024).decode("utf-8")
# print(data.decode("utf-8"))
data_list = data.splitlines()
# print(data_list[0])
# 正则匹配出文件名 'GET /img/home/tour8.jpg HTTP/1.1',
ret = re.match(r"[^/]+(/[^ ]*)",data_list[0])
print(ret)
file_name = ""
if ret:
file_name = ret.group(1)
print(file_name)
if file_name == "/":
file_name = "/index.html"
if not file_name.endswith('.py'):
try:
# 打开文件
f = open("..//..//static/html/Trave" + file_name, "rb")
except:
response = "HTTP/1.1 404 NOT FOUND\r\n"
response += "\r\n"
response += "Not Found"
# 发送文件 header
new_socket.send(response.encode("utf-8"))
else:
# 传递数据
response = "HTTP:/1.1 200 OK\r\n"
response += "\r\n"
data_contend = f.read()
f.close()
# 发送文件 header
new_socket.send(response.encode("utf-8"))
# 发送文件body
new_socket.send(data_contend)
else:
# 以.py结尾的则为动态的获取的页面
header = "HTTP:/1.1 200 OK\r\n"
header += "\r\n"
body = "nihao : %s" % time.ctime()
response = header + body
# 发送消息
new_socket.send(response.encode("utf-8"))
# 关闭套接字
new_socket.close()
def run_forerver(self):
"""使程序一直运行"""
while True:
# 等待客户端连接
new_client, addr = self.tcp_server.accept()
p = multiprocessing.Process(target=self.service_client, args=(new_client, ))
# 接受客户端的消息 回复客户端的消息
# service_client(new_client)
p.start()
new_client.close() # 多进程中会复制一份这个变量,所以要在主进程中也要关闭
self.tcp_server.close()
def main():
"""控制整体流程 --> 创建一个对象 --> 调用这个对象的run_forerver方法"""
wsgi_server = WSGIServer()
wsgi_server.run_forerver()
if __name__ == "__main__":
main()
webserver.py 服务器代码
"""
使用面向对象的方法来做多进程的web server 继承了动态的解析功能
当请求文件结尾以.py结尾的为动态网页
将web框架与逻辑处理的代码分开
"""
import socket
import re
import multiprocessing
import time
import mini_frame
class WSGIServer(object):
"""服务器对象"""
def __init__(self):
# 创建套接字
self.tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定ip和port
self.tcp_server.bind(("", 8080))
# 设置成监听模式
self.tcp_server.listen(128)
def service_client(self, new_socket):
# 接受数据
data = new_socket.recv(1024).decode("utf-8")
# print(data.decode("utf-8"))
data_list = data.splitlines()
# print(data_list[0])
# 正则匹配出文件名 'GET /img/home/tour8.jpg HTTP/1.1',
ret = re.match(r"[^/]+(/[^ ]*)",data_list[0])
print(ret)
file_name = ""
if ret:
file_name = ret.group(1)
print(file_name)
if file_name == "/":
file_name = "/index.html"
if not file_name.endswith('.py'):
try:
# 打开文件
f = open("..//..//static/html/Trave" + file_name, "rb")
except:
response = "HTTP/1.1 404 NOT FOUND\r\n"
response += "\r\n"
response += "Not Found"
# 发送文件 header
new_socket.send(response.encode("utf-8"))
else:
# 传递数据
response = "HTTP:/1.1 200 OK\r\n"
response += "\r\n"
data_contend = f.read()
f.close()
# 发送文件 header
new_socket.send(response.encode("utf-8"))
# 发送文件body
new_socket.send(data_contend)
else:
# 以.py结尾的则为动态的获取的页面
header = "HTTP:/1.1 200 OK\r\n"
header += "\r\n"
# body = "nihao : %s" % time.ctime()
body = mini_frame.login()
response = header + body
# 发送消息
new_socket.send(response.encode("utf-8"))
# 关闭套接字
new_socket.close()
def run_forerver(self):
"""使程序一直运行"""
while True:
# 等待客户端连接
new_client, addr = self.tcp_server.accept()
p = multiprocessing.Process(target=self.service_client, args=(new_client, ))
# 接受客户端的消息 回复客户端的消息
# service_client(new_client)
p.start()
new_client.close() # 多进程中会复制一份这个变量,所以要在主进程中也要关闭
self.tcp_server.close()
def main():
"""控制整体流程 --> 创建一个对象 --> 调用这个对象的run_forerver方法"""
wsgi_server = WSGIServer()
wsgi_server.run_forerver()
if __name__ == "__main__":
main()
mini_frame.py 框架代码
import time
def login():
return "welcom to login this time is : %s" % time.ctime()
import time
def login():
return "welcom to login this time is : %s" % time.ctime()
def register():
return "welcom to register this time is : %s" % time.ctime()
def profile():
return "welcom to profile this time is : %s" % time.ctime()
def application(file_name):
if file_name == "/login.py":
return login()
elif file_name == "/register.py":
return register()
elif file_name == "/profile.py":
return profile()
else:
return "no found file page time: %s" % time.ctime()
webserver.py
"""
使用面向对象的方法来做多进程的web server 继承了动态的解析功能
当请求文件结尾以.py结尾的为动态网页
"""
import socket
import re
import multiprocessing
import time
import mini_frame
class WSGIServer(object):
"""服务器对象"""
def __init__(self):
# 创建套接字
self.tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定ip和port
self.tcp_server.bind(("", 8080))
# 设置成监听模式
self.tcp_server.listen(128)
def service_client(self, new_socket):
# 接受数据
data = new_socket.recv(1024).decode("utf-8")
# print(data.decode("utf-8"))
data_list = data.splitlines()
# print(data_list[0])
# 正则匹配出文件名 'GET /img/home/tour8.jpg HTTP/1.1',
ret = re.match(r"[^/]+(/[^ ]*)",data_list[0])
print(ret)
file_name = ""
if ret:
file_name = ret.group(1)
print(file_name)
if file_name == "/":
file_name = "/index.html"
if not file_name.endswith('.py'):
try:
# 打开文件
f = open("..//..//static/html/Trave" + file_name, "rb")
except:
response = "HTTP/1.1 404 NOT FOUND\r\n"
response += "\r\n"
response += "Not Found"
# 发送文件 header
new_socket.send(response.encode("utf-8"))
else:
# 传递数据
response = "HTTP:/1.1 200 OK\r\n"
response += "\r\n"
data_contend = f.read()
f.close()
# 发送文件 header
new_socket.send(response.encode("utf-8"))
# 发送文件body
new_socket.send(data_contend)
else:
# 以.py结尾的则为动态的获取的页面
# body = "nihao : %s" % time.ctime()
envs = dict()
body = mini_frame.application(envs, self.set_response_header)
header = "HTTP:/1.1 %s\r\n" % self.status
for temp in self.hearers:
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.hearers = [("server:","mini_server v8.8")]
self.hearers += headers
def run_forerver(self):
"""使程序一直运行"""
while True:
# 等待客户端连接
new_client, addr = self.tcp_server.accept()
p = multiprocessing.Process(target=self.service_client, args=(new_client, ))
# 接受客户端的消息 回复客户端的消息
# service_client(new_client)
p.start()
new_client.close() # 多进程中会复制一份这个变量,所以要在主进程中也要关闭
self.tcp_server.close()
def main():
"""控制整体流程 --> 创建一个对象 --> 调用这个对象的run_forerver方法"""
wsgi_server = WSGIServer()
wsgi_server.run_forerver()
if __name__ == "__main__":
main()
mini_frame.py
import time
def application(environ, start_response):
start_response("200 OK", [('Content-Type', 'text/html;charset=utf-8')])
return ' 中国 hello word time: %s' % time.ctime()
webserver.py
"""
使用面向对象的方法来做多进程的web server 继承了动态的解析功能
当请求文件结尾以.py结尾的为动态网页
"""
import socket
import re
import multiprocessing
import time
import mini_frame
class WSGIServer(object):
"""服务器对象"""
def __init__(self):
# 创建套接字
self.tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定ip和port
self.tcp_server.bind(("", 8080))
# 设置成监听模式
self.tcp_server.listen(128)
def service_client(self, new_socket):
# 接受数据
data = new_socket.recv(1024).decode("utf-8")
# print(data.decode("utf-8"))
data_list = data.splitlines()
# print(data_list[0])
# 正则匹配出文件名 'GET /img/home/tour8.jpg HTTP/1.1',
ret = re.match(r"[^/]+(/[^ ]*)",data_list[0])
print(ret)
file_name = ""
if ret:
file_name = ret.group(1)
print(file_name)
if file_name == "/":
file_name = "/index.html"
if not file_name.endswith('.py'):
try:
# 打开文件
f = open("..//..//static/html/Trave" + file_name, "rb")
except:
response = "HTTP/1.1 404 NOT FOUND\r\n"
response += "\r\n"
response += "Not Found"
# 发送文件 header
new_socket.send(response.encode("utf-8"))
else:
# 传递数据
response = "HTTP:/1.1 200 OK\r\n"
response += "\r\n"
data_contend = f.read()
f.close()
# 发送文件 header
new_socket.send(response.encode("utf-8"))
# 发送文件body
new_socket.send(data_contend)
else:
# 以.py结尾的则为动态的获取的页面
# body = "nihao : %s" % time.ctime()
envs = dict()
envs["PATH_INFO"] = file_name
# print(envs)
# 传递一个字典{"PATH_INFO":file_name}
body = mini_frame.application(envs, self.set_response_header)
header = "HTTP:/1.1 %s\r\n" % self.status
for temp in self.hearers:
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.hearers = [("server:","mini_server v8.8")]
self.hearers += headers
def run_forerver(self):
"""使程序一直运行"""
while True:
# 等待客户端连接
new_client, addr = self.tcp_server.accept()
p = multiprocessing.Process(target=self.service_client, args=(new_client, ))
# 接受客户端的消息 回复客户端的消息
# service_client(new_client)
p.start()
new_client.close() # 多进程中会复制一份这个变量,所以要在主进程中也要关闭
self.tcp_server.close()
def main():
"""控制整体流程 --> 创建一个对象 --> 调用这个对象的run_forerver方法"""
wsgi_server = WSGIServer()
wsgi_server.run_forerver()
if __name__ == "__main__":
main()
mini_frame.py
import time
def index():
return "这里是首页,时间: %s" % time.ctime()
def login():
return "这里是登录页面,时间: %s" % time.ctime()
def application(environ, start_response):
start_response("200 OK", [('Content-Type', 'text/html;charset=utf-8')])
# print(environ)
file_name = environ["PATH_INFO"]
if file_name == "/index.py":
return index()
elif file_name == "/login.py":
return login()
else:
return ' 中国 hello word time: %s' % time.ctime()
将mini_frame.py放到dynamic文件夹中
目录结构 (html可以在网上下载一个就好了)
│ webserver.py
│
├─dynamic
│ │ mini_frame.py
│ │ __init__.py
│ │
│ └─__pycache__
│ mini_frame.cpython-37.pyc
│ __init__.cpython-37.pyc
│
├─static
│ ├─css
│ │ about.css
│ │ basic.css
│ │ home.css
│ │ information.css
│ │ order.css
│ │ preview.css
│ │
│ └─img
│ ├─about
│ │ trea1.png
│ │ trea2.png
│ │ trea3.png
│ │ trea4.png
│ │
│ ├─home
│ │ adver.jpg
│ │ logo.png
│ │ tour1.jpg
│ │ tour2.jpg
│ │ tour3.jpg
│ │ tour4.jpg
│ │ tour5.jpg
│ │ tour6.jpg
│ │ tour7.jpg
│ │ tour8.jpg
│ │ tour9.jpg
│ │
│ ├─information
│ │ disc.png
│ │ headline.jpg
│ │ hot1.jpg
│ │ hot2.jpg
│ │ hot3.jpg
│ │ hot4.jpg
│ │ hot5.jpg
│ │ hot6.jpg
│ │ hot7.jpg
│ │ hot8.jpg
│ │ logo.png
│ │ tour1.jpg
│ │ tour2.jpg
│ │ tour3.jpg
│ │ tour4.jpg
│ │ tour5.jpg
│ │ tour6.jpg
│ │ tour7.jpg
│ │ tour8.jpg
│ │ tour9.jpg
│ │
│ └─ticket
│ headline.jpg
│ hot1.jpg
│ hot2.jpg
│ hot3.jpg
│ hot4.jpg
│ hot5.jpg
│ hot6.jpg
│ hot7.jpg
│ hot8.jpg
│ logo.png
│
└─templates
about.html
index.html
information.html
order.html
preview.html
webserver.py
"""
使用面向对象的方法来做多进程的web server 继承了动态的解析功能
当请求文件结尾以.py结尾的为动态网页
"""
import socket
import re
import multiprocessing
import time
import dynamic.mini_frame
class WSGIServer(object):
"""服务器对象"""
def __init__(self):
# 创建套接字
self.tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定ip和port
self.tcp_server.bind(("", 8080))
# 设置成监听模式
self.tcp_server.listen(128)
def service_client(self, new_socket):
# 接受数据
data = new_socket.recv(1024).decode("utf-8")
# print(data.decode("utf-8"))
data_list = data.splitlines()
# print(data_list[0])
# 正则匹配出文件名 'GET /img/home/tour8.jpg HTTP/1.1',
ret = re.match(r"[^/]+(/[^ ]*)",data_list[0])
print(ret)
file_name = ""
if ret:
file_name = ret.group(1)
print(file_name)
if file_name == "/":
file_name = "/index.html"
if not file_name.endswith('.py'):
try:
# 打开文件
f = open("./static/" + file_name, "rb")
except:
response = "HTTP/1.1 404 NOT FOUND\r\n"
response += "\r\n"
response += "Not Found"
# 发送文件 header
new_socket.send(response.encode("utf-8"))
else:
# 传递数据
response = "HTTP:/1.1 200 OK\r\n"
response += "\r\n"
data_contend = f.read()
f.close()
# 发送文件 header
new_socket.send(response.encode("utf-8"))
# 发送文件body
new_socket.send(data_contend)
else:
# 以.py结尾的则为动态的获取的页面
# body = "nihao : %s" % time.ctime()
envs = dict()
envs["PATH_INFO"] = file_name
# print(envs)
# 传递一个字典{"PATH_INFO":file_name}
body = dynamic.mini_frame.application(envs, self.set_response_header)
header = "HTTP:/1.1 %s\r\n" % self.status
for temp in self.hearers:
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.hearers = [("server:","mini_server v8.8")]
self.hearers += headers
def run_forerver(self):
"""使程序一直运行"""
while True:
# 等待客户端连接
new_client, addr = self.tcp_server.accept()
p = multiprocessing.Process(target=self.service_client, args=(new_client, ))
# 接受客户端的消息 回复客户端的消息
# service_client(new_client)
p.start()
new_client.close() # 多进程中会复制一份这个变量,所以要在主进程中也要关闭
self.tcp_server.close()
def main():
"""控制整体流程 --> 创建一个对象 --> 调用这个对象的run_forerver方法"""
wsgi_server = WSGIServer()
wsgi_server.run_forerver()
if __name__ == "__main__":
main()
mini_frame.py
import time
def index():
with open("./templates/index.html", encoding='utf-8') as f:
return f.read()
def order():
with open("./templates/order.html", encoding='utf-8') as f:
return f.read()
def information():
with open("./templates/information.html", encoding='utf-8') as f:
return f.read()
def preview():
with open("./templates/preview.html", encoding='utf-8') as f:
return f.read()
def about():
with open("./templates/about.html", encoding='utf-8') as f:
return f.read()
def application(environ, start_response):
start_response("200 OK", [('Content-Type', 'text/html;charset=utf-8')])
# print(environ)
file_name = environ["PATH_INFO"]
if file_name == "/index.py":
return index()
elif file_name == "/order.py":
return order()
elif file_name == "/information.py":
return information()
elif file_name == "/preview.py":
return preview()
elif file_name == "/about.py":
return about()
else:
return ' 中国 hello word time: %s' % time.ctime()
修改webserver.py
"""
使用面向对象的方法来做多进程的web server 继承了动态的解析功能
当请求文件结尾以.py结尾的为动态网页
"""
import socket
import re
import multiprocessing
import time
# import dynamic.mini_frame
import sys
import re
class WSGIServer(object):
"""服务器对象"""
def __init__(self, port, app):
# 创建套接字
self.tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定ip和port
self.tcp_server.bind(("", port))
# 设置成监听模式
self.tcp_server.listen(128)
self.app = app
def service_client(self, new_socket):
# 接受数据
data = new_socket.recv(1024).decode("utf-8")
# print(data.decode("utf-8"))
data_list = data.splitlines()
# print(data_list[0])
# 正则匹配出文件名 'GET /img/home/tour8.jpg HTTP/1.1',
ret = re.match(r"[^/]+(/[^ ]*)",data_list[0])
print(ret)
file_name = ""
if ret:
file_name = ret.group(1)
print(file_name)
if file_name == "/":
file_name = "/index.html"
if not file_name.endswith('.py'):
try:
# 打开文件
f = open("./static/" + file_name, "rb")
except:
response = "HTTP/1.1 404 NOT FOUND\r\n"
response += "\r\n"
response += "Not Found"
# 发送文件 header
new_socket.send(response.encode("utf-8"))
else:
# 传递数据
response = "HTTP:/1.1 200 OK\r\n"
response += "\r\n"
data_contend = f.read()
f.close()
# 发送文件 header
new_socket.send(response.encode("utf-8"))
# 发送文件body
new_socket.send(data_contend)
else:
# 以.py结尾的则为动态的获取的页面
# body = "nihao : %s" % time.ctime()
envs = dict()
envs["PATH_INFO"] = file_name
# print(envs)
# 传递一个字典{"PATH_INFO":file_name}
# body = dynamic.mini_frame.application(envs, self.set_response_header)
body = self.app(envs, self.set_response_header)
header = "HTTP:/1.1 %s\r\n" % self.status
for temp in self.hearers:
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.hearers = [("server:","mini_server v8.8")]
self.hearers += headers
def run_forerver(self):
"""使程序一直运行"""
while True:
# 等待客户端连接
new_client, addr = self.tcp_server.accept()
p = multiprocessing.Process(target=self.service_client, args=(new_client, ))
# 接受客户端的消息 回复客户端的消息
# service_client(new_client)
p.start()
new_client.close() # 多进程中会复制一份这个变量,所以要在主进程中也要关闭
self.tcp_server.close()
def main():
"""控制整体流程 --> 创建一个对象 --> 调用这个对象的run_forerver方法"""
# 执行代码的操作 python server.py 7780 mini_frame:application -->端口名和框架中的函数
if len(sys.argv) == 3:
try:
port = int(sys.argv[1]) # 7780
frame_app_name = sys.argv[2] # mini_frame:application
except Exception as ret:
print("端口错误")
return
else:
print("请用以下方式执行程序:")
print("python m8-server.py 7780 mini_frame:application --> 程序后加入端口号和框架中的main函数名")
return # 结束函数
# mini_frame:application
ret = re.match(r"([^:]+):(.*)", frame_app_name)
if ret:
frame_name = ret.group(1) # mini_frame
app_name = ret.group(2) # application
else:
print("请用以下方式执行程序:")
print("python m8-server.py 7780 mini_frame:application --> 程序后加入端口号和框架中的main函数名")
return # 结束函数
sys.path.append("./dynamic")
# import frame_name --> 找的是 frame_name.py
frame = __import__(frame_name) # 导入函数 以变量名的函数 返回值标记了这个导入的模板
app = getattr(frame, app_name) # 此时app指向了./dynamic/mini_frame.application
wsgi_server = WSGIServer(port, app)
wsgi_server.run_forerver()
if __name__ == "__main__":
main()
现在webserver.py的同级目录下创建一个webserver.conf文件储存要配置的文件,文件中存放一下内容 html文件的存放路径和框架的存放路径
{
"static_path":"./static",
"dynamic_path":"./dynamic"
}
修改的webserver.py代码
"""
使用面向对象的方法来做多进程的web server 继承了动态的解析功能
当请求文件结尾以.py结尾的为动态网页
"""
import socket
import re
import multiprocessing
import time
# import dynamic.mini_frame
import sys
import re
class WSGIServer(object):
"""服务器对象"""
def __init__(self, port, app, static_path):
# 创建套接字
self.tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定ip和port
self.tcp_server.bind(("", port))
# 设置成监听模式
self.tcp_server.listen(128)
self.app = app
self.static_path = static_path
def service_client(self, new_socket):
# 接受数据
data = new_socket.recv(1024).decode("utf-8")
# print(data.decode("utf-8"))
data_list = data.splitlines()
# print(data_list[0])
# 正则匹配出文件名 'GET /img/home/tour8.jpg HTTP/1.1',
ret = re.match(r"[^/]+(/[^ ]*)",data_list[0])
print(ret)
file_name = ""
if ret:
file_name = ret.group(1)
print(file_name)
if file_name == "/":
file_name = "/index.html"
if not file_name.endswith('.py'):
try:
# 打开文件
# f = open("./static/" + file_name, "rb")
f = open(self.static_path + file_name, "rb")
except:
response = "HTTP/1.1 404 NOT FOUND\r\n"
response += "\r\n"
response += "Not Found"
# 发送文件 header
new_socket.send(response.encode("utf-8"))
else:
# 传递数据
response = "HTTP:/1.1 200 OK\r\n"
response += "\r\n"
data_contend = f.read()
f.close()
# 发送文件 header
new_socket.send(response.encode("utf-8"))
# 发送文件body
new_socket.send(data_contend)
else:
# 以.py结尾的则为动态的获取的页面
# body = "nihao : %s" % time.ctime()
envs = dict()
envs["PATH_INFO"] = file_name
# print(envs)
# 传递一个字典{"PATH_INFO":file_name}
# body = dynamic.mini_frame.application(envs, self.set_response_header)
body = self.app(envs, self.set_response_header)
header = "HTTP:/1.1 %s\r\n" % self.status
for temp in self.hearers:
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.hearers = [("server:","mini_server v8.8")]
self.hearers += headers
def run_forerver(self):
"""使程序一直运行"""
while True:
# 等待客户端连接
new_client, addr = self.tcp_server.accept()
p = multiprocessing.Process(target=self.service_client, args=(new_client, ))
# 接受客户端的消息 回复客户端的消息
# service_client(new_client)
p.start()
new_client.close() # 多进程中会复制一份这个变量,所以要在主进程中也要关闭
self.tcp_server.close()
def main():
"""控制整体流程 --> 创建一个对象 --> 调用这个对象的run_forerver方法"""
# 执行代码的操作 python server.py 7780 mini_frame:application -->端口名和框架中的函数
if len(sys.argv) == 3:
try:
port = int(sys.argv[1]) # 7780
frame_app_name = sys.argv[2] # mini_frame:application
except Exception as ret:
print("端口错误")
return
else:
print("请用以下方式执行程序:")
print("python m8-server.py 7780 mini_frame:application --> 程序后加入端口号和框架中的main函数名")
return # 结束函数
# mini_frame:application
ret = re.match(r"([^:]+):(.*)", frame_app_name)
if ret:
frame_name = ret.group(1) # mini_frame
app_name = ret.group(2) # application
else:
print("请用以下方式执行程序:")
print("python m8-server.py 7780 mini_frame:application --> 程序后加入端口号和框架中的main函数名")
return # 结束函数
# 读取配置文件中的信息
# {
# "static_path":"./static",
# "dynamic_path":"./dynamic"
# }
with open("./web_server.conf") as f:
conf_info = eval(f.read())
# print(conf_info)
sys.path.append(conf_info["dynamic_path"])
# import frame_name --> 找的是 frame_name.py
frame = __import__(frame_name) # 导入函数 以变量名的函数 返回值标记了这个导入的模板
app = getattr(frame, app_name) # 此时app指向了./dynamic/mini_frame.application
wsgi_server = WSGIServer(port, app, conf_info["static_path"])
wsgi_server.run_forerver()
if __name__ == "__main__":
main()
再写一个程序执行文的操作
运行web服务器时指定端口和框架
运行方式: python webserver.py port frame:app
举例: python webserver.py 8080 mini_frame:application
首先要配置web_server.conf中的文件路径