一、介绍
- 说明
①浏览器中输入网址url,服务端会接收到浏览器发送的数据
②服务器通过判断浏览器请求是否为静/动态资源,选择是否直接从服务器中查找并返回数据,还是调用mini_web框架
静态资源: 当浏览器请求的是静态资源(html,css,png,js等),服务器在本地查找资源并整合通过http协议返回给浏览器
动态资源;当浏览器请求的文件是以py结尾(假如py代表请求动态资源),则浏览器就会调用mini_web框架,即自动调用web框架中的application函数
def application(env,function_name):
#需要两个参数,第一个参数为字典,第二个参数为函数名
function_name(*args,**kwargs) #调用服务器中的某个函数
return body
③通过调用mini_web框架中的application函数,进而调用服务器中的某个函数,向服务器返回头部信息,最后将body返回给服务器
④服务器整合mini_web框架返回的数据,再按照http协议将数据返回给浏览器
- 作用
达到了动/静请求数据的目的
#web_sever.py
#服务器端
import socket
import re
import multiprocessing
import mini_web2
class WebServer():
def __init__(self):
#创建套接字
self.tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 解决因服务器先关闭而导致服务器端口被占用而不能访问的问题
self.tcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
#绑定本地信息
self.tcp_socket.bind(('192.168.8.14',7788))
#设置模式为被动接听模式
self.tcp_socket.listen(128)
def handle(self,client_socket):
#发送消息
recv_data = client_socket.recv(1024).decode('utf-8')
#print(recv_data)
recv_data_list = recv_data.splitlines()
# print(recv_data_list)
filename = ''
# 获取客户端需要请求的文件名
ret =re.match(r"[^/]+(/[^ ]*)",recv_data_list[0])
if ret:
filename = ret.group(1) # 文件路径
if filename == '/':
filename = '/index.html'
print(filename)
send_data_header = "HTTP/1.1 200 OK \r\n\r\n"
# 如果浏览器请求的是静态资源(html,css,js,img,png等.直接读取发送)
if not filename.endswith('py'):
try:
#读取客户端要请求的页面并发送
f = open('./html' + filename,'rb')
except:
send_data_header = 'HTTP/1.1 404 \r\n\r\n'
send_data = '404,file not found'
else:
html_data = f.read()
f.close()
#print('读取成功')
client_socket.send(send_data_header.encode('utf-8'))
client_socket.send(html_data)
else:
#如果浏览器请求的文件是以py结尾,即请求动态数据
env = dict()
body = mini_web2.application(env,self.start_response_header) #body为application的返回值
header = 'HTTP/1.1 %s\r\n'%self.status
for temp in self.header:
header +='%s:%s\r\n'%(temp[0],temp[1])
header +='\r\n'
response = header + body
client_socket.send(response.encode('utf-8'))
#关闭套接字
client_socket.close()
def start_response_header(self,status,header):
self.status = status #字符串
self.header = header #列表
def run_forever(self):
while True:
#等待客户端连接
client_socket,client_addr = self.tcp_socket.accept()
#创建多进程
p = multiprocessing.Process(target=self.handle,args = (client_socket,))
p.start()
client_socket.close()
self.tcp_socket.close()
if __name__ == '__main__':
web_sever = WebServer()
web_sever.run_forever()
# mini_web2.py
#mini_web框架
def application(environ,start_response_header):
start_response_header('200 OK',[('Content-Type','text/html;charset=utf-8')]) # 调用服务器端的函数,返回头信息
return 'Hello World! 我爱你中国...' #返回简单的body
- 总结
1.在原有的TCP服务端的基础上加上一个请求资源的判断,即判断是否是动态资源;
2.如果是动态资源,就将动态资源的请求路径发送给框架,
3.框架在进行判断,如果动态资源是模版那就读出模版的数据并返回给服务器,最后再由服务器拼接响应报文给客户端,
4.如果动态资源请求的是数据,那么框架就回到数据库中将数据查询出来,并且拼接成JSON数据格式的字符串,再将JSON数据格式的字符串转换成JSON数据,最后在返回给服务器,最后再由服务器拼接响应报文并发送给客户端。