众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端
SOCKET实现
_author__ = "Burgess Zheng"
import socket
def handle_request(client):
buf = client.recv(1024) #接收请求
client.send(bytes("HTTP/1.1 200 OK\r\n\r\n",encoding='utf-8'))
client.send(bytes("Hello,Seven",encoding='utf-8'))
#发送请求
#bytes():转换成bytes类型
#当然直接encoding不用谢bytes也行,但是按照标准比较不会出错
#相当于 str(1)转换字符串
#相当于list((111,))转换成列表
#相当于bytes('sdfsd',)转换成bytes
def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#创建socket服务端
sock.bind(('0.0.0.0', 8000))#监听端口
sock.listen(5)#最大连接数
while True: #循环
connection, address = sock.accept() #只要有人连接获取该连接
# connection:链接标记位, address:对方的地址
handle_request(connection)#执行handle_reques处理函数
connection.close()#连接断开 #也就是有人访问了该服务端,服务端返回数据后自动断开
if __name__ == '__main__':
main() #执行该函数
执行结果:
上述通过socket来实现了其本质,而对于真实开发中的python web程序来说,一般会分为两部分:服务器程序和应用程序。服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的各种数据进行整理。应用程序则负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的Web框架,例如:Django、Flask、web.py 等。不同的框架有不同的开发方式,但是无论如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。这样,服务器程序就需要为不同的框架提供不同的支持。这样混乱的局面无论对于服务器还是框架,都是不好的。对服务器来说,需要支持各种不同框架,对框架来说,只有支持它的服务器才能被开发出的应用使用。这时候,标准化就变得尤为重要。我们可以设立一个标准,只要服务器程序支持这个标准,框架也支持这个标准,那么他们就可以配合使用。一旦标准确定,双方各自实现。这样,服务器可以支持更多支持标准的框架,框架也可以使用更多支持标准的服务器。
WSGI(Web Server Gateway Interface)是一种规范,它定义了使用python编写的web app与web server之间接口格式,实现web app与web server间的解耦。
python标准库提供的独立WSGI服务器称为wsgiref。
试验调用Python的wsgiref模块创建socket服务端
整个生命周期简单理解:
1.用户访问指定IP端口
2.服务端接收从头部信息提取出访问的url进行判断是否有效
3.访问的url有效就调用对应函数处理
4.处理函数二进制打开本地html文件进行赋值返回给用户(如果html内容需要替换也可以替换以后进行返回给用户)
main_wsgiref(wsgiref模块实现服务端)
__author__ = "Burgess Zheng"
from wsgiref.simple_server import make_server
# 导入了WSGI socket模块
from Controller import account
#导入自定义的account函数模块
ULR_DICT = {
"/index": account.handle_index,
"/date": account.handle_date,
}
# 字典模式:字符串:函数执行的结果
# account.handle_index 获取account模块里面的handle_index函数
def RunServer(environ, start_response):
# emvorpn:封装了客户端发来的所有的数据
#start_response 封装要返回给用户的数据、响应头状态
print(1)
start_response('200 OK', [('Content-Type', 'text/html')])
#返回给用户的响应头状态
current_url = environ['PATH_INFO']
#获取用户的想要访问的url,赋值到current_url
func = None
# 默认func =None
if current_url in ULR_DICT:
# 假如用户访问的url存在于ULR_DICT字典内,执行下面操作
func = ULR_DICT[current_url] #获取了相应返回用户数据
if func: #如果func获取到了,执行下面返回给用户数据
return func()
else: #否则报错
return['<h1>404</h1>'.encode('utf-8')]
#这样如果新增用户访问路径的话就无需再更改该地方了
if __name__ == '__main__':
httpd = make_server('', 8000, RunServer)
# 创建WIGI服务端 3个形参 分别是:监听的IP,端口,处理函数
print("Serving HTTP on port 8000...")
httpd.serve_forever()
# 运行该服务端
# 运行以后,1帮你创建一个socket服务端,2.客户连接上以后就会触发RunServer函数
Controller/account.py(用户请求进行处理)
__author__ = "Burgess Zheng"
def handle_index():
import time #引入时间模块
v = str(time.time()) #获取当前时间
f = open('View/index.html',mode='rb')
#二进制读取打开View目录的index.html文件,
data = f.read()
# 读取该文件内容,然后内容赋值给data
f.close()#关闭该文件
data = data.replace(b'@uuuuu',v.encode('utf-8'))
# data.replace替换内容 内容@uuuuu 替换成 二进制当前时间(v)
return [data,]
#返回该data数据
def handle_date():
f = open('View/date.html', mode='rb')
data = f.read()
f.close()
return [data,]
View/date.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Date</h1>
</body>
</html>
View/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Index @uuuuu</h1>
</body>
</html>
启动main_wsgiref:
浏览器访问: