一、虚拟环境
二、web架构
三、http协议
四、原生socket
五、http协议socket原理
六、响应路由原理
七、响应框架演变
八、项目演变模板渲染
一、虚拟环境
什么是虚拟环境?
对真实的python解释器的一个拷贝版本
是事实有效的,可以独立运行解释python代码
可以在计算机上拷贝多个虚拟环境
为什么要用虚拟环境?
保证真实环境的纯净性
框架的多版本共存
方便做框架的版本迭代
降低多框架共存的维护成本
安装虚拟环境步骤:
1.通过pip3安装虚拟环境:
--pip3 install virtualenv
2.前往目标文件夹:
--cd 目标文件夹(D:\viryualenv)
3.创建纯净虚拟环境:
--virtualenv 虚拟环境名(py3-env1)
4.终端启动虚拟环境:
--cd py3-env1\Scripts
--activate
5.进入虚拟环境下的python开发环境
--python3
6.关闭虚拟环境
--deactivate
7.PyCharm的开发配置
添加:创建项目 -> Project Interpreter -> Existing interpreter -> Virtualenv Environment | System Interpreter -> 目标路径下的python.exe
删除:Setting -> Project -> Project Interpreter -> Show All
二、web架构
web应用 架构
C/S 架构 | B/S架构
client server :客户端服务器架构,C++
browser server:浏览器服务器架构,Java、Python
三、http协议
什么是http协议
http协议(Hyper Text Tranport Protocol)是超文本传输协议
基于TCP/IP协议基础上的应用层协议,底层实现仍为socket
基于请求-响应模式:通信一定是从客户端开始,服务端接受到客户端一定会做出对应响应
无状态:协议不对任何一次通信状态和任何数据做保存
无连接:一次链接只完成一次请求-响应,请求-响应完毕后立即断开连链接
http工作原理(事务)
一次http操作称之为一个事务,工作过程可分为四步
1.客户端服务器建立连接
2.客户发送一个http协议指定格式的请求
3.服务器接受请求后,回应一个http协议指定格式的响应
4.客户端将服务器的响应显示展现给用户
状态码
1打头:消息通知
2打头:请求成功
3打头:重定向
4打头:客户端错误
5打头:服务器端错误
四、原生socket
关注服务器
# 完成B/S架构项目的设计 # Borwser已经完成 # Server需要手动书写socket,以http协议方式完成响应 import socket # 设置响应头(包含响应行) RESP_HEADER = b'HTTP/1.1 200 OK\r\nContent-type:text/html;charset=utf-8\r\n\r\n' # 设置服务器socket相关信息 server = socket.socket() server.bind(('localhost', 8808)) server.listen(5) print("服务: http://localhost:8808") while True: # 获取B以http协议发来的请求 client, address = server.accept() data = client.recv(1024) # 数据报文 包含 请求行 请求头 请求体 print(data) # 手动以http协议完成响应 # 数据报文 包含 响应行 响应头 响应体 client.send(RESP_HEADER) # /index => 响应主页 # /login => 登录页面 # 错误 => 404 # 数据data, 字节形式 => 字符串形式 strData = str(data, encoding='utf-8') # 解析请求的数据, 分析得到路由 my_route = strData.split('\r\n')[0].split(' ')[1] # 后台没有设置的路由,统统以404来处理 dt = b'404' # 设置的路由返回响应的页面文件 if my_route == '/index': with open('02_index.html', 'rb') as f: dt = f.read() if my_route == '/login': with open('02_login.html', 'rb') as f: dt = f.read() # /favicon.ico该请求是往后台请求标签图标 if my_route == '/favicon.ico': with open('favicon.ico', 'rb') as f: dt = f.read() # 响应体 client.send(dt) # 一次循环,代表一次响应,也就是一次事务的完成, 要关闭http请求连接 client.close()
五、http协议socket原理
client
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>模拟请求</title> </head> <body> <form action="http://localhost:8801" method="post"> <input type="text" name="usr"> <input type="password" name="pwd"> <input type="submit" value="提交"> </form> </body> </html>
server
import socket # 创建服务器socket对象 server = socket.socket() # 绑定IP:端口 server.bind(('localhost', 8801)) # 设置监听 server.listen(5) print("服务: http://localhost:8801") while True: client, address = server.accept() data = client.recv(1024) print(data) # 完成响应 # 响应要遵循http协议, http协议用响应行规定 # 返回相应行 client.send(b'HTTP/1.1 200 OK\r\n') # 返回相应头 client.send(b'\r\n') # 结束响应头 # 返回响应体(数据) client.send(b'hello web socket') # 一次 请求-响应 结束后(事务完成后), 要将连入的客户端断开 client.close() ''' part1 # 接收请求并相应 # 阻塞监听客户端连接 client, address = server.accept() # 接收客户端数据 data = client.recv(1024) # 打印数据 print(data) # 相应 client.send(b'hello web socket') # 报错 ==> localhost 发送的响应无效。 # 原因: 响应不满足http协议 ''' ''' GET / HTTP/1.1\r\n Host: localhost:8801\r\n Connection: keep-alive\r\n Cache-Control: max-age=0\r\n Upgrade-Insecure-Requests: 1\r\n User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36\r\n Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n Accept-Encoding: gzip, deflate, br\r\n Accept-Language: zh-CN,zh;q=0.9\r\n Cookie: Pycharm-f94859b8=6ca1fc7e-fcb7-405e-bb84-891b2957fcce\r\n \r\n '''
六、响应路由原理
server
import socket # 创建服务器socket对象 server = socket.socket() # 绑定IP:端口 server.bind(('localhost', 8801)) # 设置监听 server.listen(5) print("服务: http://localhost:8801") while True: client, address = server.accept() data = client.recv(1024) print(data) # 完成响应 # 响应要遵循http协议, http协议用响应行规定 # 返回相应行 client.send(b'HTTP/1.1 200 OK\r\n') # 返回相应头 client.send(b'\r\n') # 结束响应头 # 返回响应体(数据) client.send(b'hello web socket') # 一次 请求-响应 结束后(事务完成后), 要将连入的客户端断开 client.close() ''' part1 # 接收请求并相应 # 阻塞监听客户端连接 client, address = server.accept() # 接收客户端数据 data = client.recv(1024) # 打印数据 print(data) # 相应 client.send(b'hello web socket') # 报错 ==> localhost 发送的响应无效。 # 原因: 响应不满足http协议 ''' ''' GET / HTTP/1.1\r\n Host: localhost:8801\r\n Connection: keep-alive\r\n Cache-Control: max-age=0\r\n Upgrade-Insecure-Requests: 1\r\n User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36\r\n Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n Accept-Encoding: gzip, deflate, br\r\n Accept-Language: zh-CN,zh;q=0.9\r\n Cookie: Pycharm-f94859b8=6ca1fc7e-fcb7-405e-bb84-891b2957fcce\r\n \r\n '''
index、login页面
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>主页</title> <style> h1 { color: red; } </style></head><body> <h1>这是主页</h1></body></html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>登录</title> </head> <body> <h1>登录页面</h1> </body> </html>
七、响应框架演变
manage.py
import socket RESP_HEADER = b'HTTP/1.1 200 OK\r\nContent-type:text/html;charset=utf-8\r\n\r\n' # 处理路由的响应函数 def index(response): with open('index.html', 'rb') as f: dt = f.read() response.send(dt) def login(response): pass def error(response): response.send(b'404') # 设置路由 urls = { '/index': index, '/login': login, 'error': error } # 启动服务 def run(host, port): server = socket.socket() server.bind((host, port)) server.listen(5) while True: client, address = server.accept() data = client.recv(1024) data = str(data, encoding='utf-8') print(data) # 解析data分析出路由 route = data.split('\r\n')[0].split(' ')[1] # 分离路由 client.send(RESP_HEADER) if route in urls: urls[route](client) else: urls['error'](client) client.close() if __name__ == '__main__': run('localhost', 8802)
index
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>主页</title> </head> <body> <h1>主页</h1> </body> </html>
八、项目演变模板渲染
start
# 已经帮我们封装好了socket from wsgiref.simple_server import make_server from urls import urls def app(env, response): print(env) route = env['PATH_INFO'] # 设置状态码与响应头 response("200 OK", [('Content-type', 'text/html')]) data = urls['error']() if route in urls: data = urls[route]() # 返回二进制响应体 return [data] if __name__ == "__main__": # 创建服务器对象 server = make_server('localhost', 8808, app) print("服务: http://localhost:8808") # 服务保持运行状态 server.serve_forever()
urls
# 设置路由 # 请求路径与响应函数的对应关系 from views import * urls = { '/index': index, 'error': error }
views
# 处理请求的功能函数(处理结果返回的都是页面 => views) # 利用jinja2来渲染模板,将后台数据传给前台 from jinja2 import Template def index(): with open('templates/index.html', 'r') as f: dt = f.read() tem = Template(dt) # 将后台数据通过模板渲染功能渲染给前台页面 resp = tem.render(name=["主页", "附页"]) return resp.encode('utf-8') # def ico(): # with open('favicon.ico', 'rb') as f: # dt = f.read() # return dt def error(): return b'404'
来源:https://www.cnblogs.com/wuzhengzheng/p/10273628.html