原题图:
参考代码:
learn_28_web_tcpserver_html_multipro_2.py
# 将web服务器和逻辑处理的代码分开
# 面对对象的方式
# 多进程实现
# 补充知识点:F5是刷新(不过很多时候都是用的浏览器缓存);用ctrl+r 强制刷新。
import socket, re
import multiprocessing
import time
import learn_28_web_miniframe_2
class WSGIServer(object):
def __init__(self):
""" 初始化服务器的各项内容 """
# 1. 创建监听套接字
self.tcp_socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#此处可以加一句,资源立即释放的语句(略)
# 2.绑定信息
local_ip = ""
local_port = 5000
local_addr = (local_ip, local_port)
self.tcp_socket_server.bind(local_addr)
# 3.设置为监听模式
self.tcp_socket_server.listen(128)
# 给新连接进来的客户端返回一个html页面
def communicate(self, new_socket, client_addr):
# (1).将收到的客户端请求先解码,以便后续代码中提取想要的具体请求页面
request = new_socket.recv(1024).decode('utf-8')
print(request," [from:{}".format(client_addr))
# (2).将已经解码变为字符串的request进行切割
request_lines = request.splitlines()
# print(request_lines)
# (3).从列表中取得想要的东西,浏览器想要的文件名
# GET /index.html HTTP/1.1
# 这个正则又看不懂了。得查。
# ^ :不是后面的字符
# 把需要的用括号括起来
# 防止没有flie_name ,先设为空字符串
file_name = ""
print(">>>>>>",request_lines)
if request_lines:
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'
# 返回http格式的数据,给浏览器
# 如果请求的资源不是以.py结尾,那么就认为是静态资源(html/css/js/png,JPG等)
if not file_name.endswith('.py'):
# 打开请求的文件, 由于不一定有文件,所以用try except
try:
f = open("./MyWeb2" + file_name, 'rb')
except:
response = "HTTP/1.1 404 NOT FOUND\r\n"
response += "\r\n"
response += "-----no page-----"
new_socket.send(response.encode('utf-8'))
else:
html_content = f.read()
f.close()
# 准备要发送给浏览器的数据
response = "HTTP/1.1 200 ok\r\n"
response += "\r\n"
new_socket.send(response.encode('utf-8')) # 发送head
new_socket.send(html_content) #
else:
# 如果是以.py结尾,那么就认为是动态资源的请求
header = "HTTP/1.1 200 OK\r\n"
header += "\r\n"
# 此处模拟动态
# body = learn_28_web_miniframe.login()
body = learn_28_web_miniframe_2.application(file_name)
response = header + body
#发送response给浏览器
new_socket.send(response.encode('utf-8'))
new_socket.close()
# 充当http server
def fun_forever(self):
# 4.准备接客
while True:
print("等待连接...")
# (1) accept等待连接,等待到连接后返回新创建的套接字和连接进来的客户端地址
new_socket, client_addr = self.tcp_socket_server.accept()
# (2) (使用多进程的方式)调用communicate(返回给连接进来的客户端一个html页面)
p = multiprocessing.Process(target=self.communicate, args=(new_socket, client_addr))
p.start()
# 注!为什么这里要用new_socket.close(),因为在用多进程去实现时,子进程是复制了父进程的资源
new_socket.close()
# 6.正常的程序流程要关闭套接字
self.tcp_socket_server.close()
def main():
""" 控制整体, 创建一个web服务器对象,然后调用这个对象的run_forever方法运行 """
wsgiserver = WSGIServer()
wsgiserver.fun_forever()
if __name__ == "__main__":
main()
learn_28_web_miniframe_2.py
import time
def login():
return "login:welcome to our website.....time:%s" %time.ctime()
def register():
return "register:welcome to our website.....time:%s" %time.ctime()
def profile():
return "profile:welcome to our website.....time:%s" %time.ctime()
def application(filename):
if filename == '/login.py':
return login()
elif filename == '/register.py':
return register()
else:
return "not found"