mini web框架示例
web框架:
使用web框架专门负责处理用户的动态资源请求,这个web框架其实就是一个为web服务器提供服务的应用程序
什么是路由?
路由就是请求的url到处理函数的映射,也就是说提前把请求的URL和处理函数关联好
管理路由可以使用一个路由列表进行管理
web.py文件:
importsocketimportosimportthreadingimportsysimportframework#http协议的web服务器类classHttpWebServer(object):def__init__(self,port):#创建tcp服务端套接字tcp_server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#设置端口号复用,程序退出端口号立即释放tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)#绑定端口号tcp_server_socket.bind(("",port))#设置监听tcp_server_socket.listen(128)#把tcp服务器的套接字作为web服务器对象的属性self.tcp_server_socket=tcp_server_socket#处理客户端请求@staticmethoddefhandle_client_request(new_socket):#接收客户端的请求信息recv_data=new_socket.recv(4096)#判断接收的数据长度是否为0iflen(recv_data)==0:new_socket.close()return#对二进制数据进行解码recv_content=recv_data.decode("utf-8")print(recv_content)#对数据按照空格进行分割request_list=recv_content.split("",maxsplit=2)#获取请求的资源路径request_path=request_list[1]print(request_path)#判断请求的是否是根目录,如果是根目录设置返回的信息ifrequest_path=="/":request_path="/index.html"#判断是否是动态资源请求,以后把后缀是.html的请求任务是动态资源请求ifrequest_path.endswith(".html"):"""动态资源请求"""#动态资源请求找web框架进行处理,需要把请求参数给web框架#准备给web框架的参数信息,都要放到字典里面env={"request_path":request_path,#传入请求头信息,额外的参数可以在字典里面在进行添加}#使用框架处理动态资源请求,#1.web框架需要把处理结果返回给web服务器,#2.web服务器负责把返回的结果封装成响应报文发送给浏览器status,headers,response_body=framework.handle_request(env)print(status,headers,response_body)#响应行response_line="HTTP/1.1%s\r\n"%status#响应头response_header=""forheaderinheaders:response_header+="%s:%s\r\n"%header#响应报文response_data=(response_line+response_header+"\r\n"+response_body).encode("utf-8")#发送响应报文数据给浏览器new_socket.send(response_data)#关闭连接new_socket.close()else:"""静态资源请求"""#1.os.path.exits#os.path.exists("static/"+request_path)#2.try-excepttry:#打开文件读取文件中的数据,提示:这里使用rb模式,兼容打开图片文件withopen("static"+request_path,"rb")asfile:#这里的file表示打开文件的对象file_data=file.read()#提示:withopen关闭文件这步操作不用程序员来完成,系统帮我们来完成exceptExceptionase:#代码执行到此,说明没有请求的该文件,返回404状态信息#响应行response_line="HTTP/1.1404NotFound\r\n"#响应头response_header="Server:PWS/1.0\r\n"#读取404页面数据withopen("static/error.html","rb")asfile:file_data=file.read()#响应体response_body=file_data#把数据封装成http响应报文格式的数据response=(response_line+response_header+"\r\n").encode("utf-8")+response_body#发送给浏览器的响应报文数据new_socket.send(response)else:#代码执行到此,说明文件存在,返回200状态信息#响应行response_line="HTTP/1.1200OK\r\n"#响应头response_header="Server:PWS/1.0\r\n"#响应体response_body=file_data#把数据封装成http响应报文格式的数据response=(response_line+response_header+"\r\n").encode("utf-8")+response_body#发送给浏览器的响应报文数据new_socket.send(response)finally:#关闭服务于客户端的套接字new_socket.close()#启动服务器的方法defstart(self):#循环等待接受客户端的连接请求whileTrue:#等待接受客户端的连接请求new_socket,ip_port=self.tcp_server_socket.accept()#代码执行到此,说明连接建立成功sub_thread=threading.Thread(target=self.handle_client_request,args=(new_socket,))#设置成为守护主线程sub_thread.setDaemon(True)#启动子线程执行对应的任务sub_thread.start()defmain():##获取终端命令行参数#params=sys.argv#iflen(params)!=2:#print("执行的命令格式如下:python3xxx.py9000")#return#####判断第二个参数是否都是由数字组成的字符串#ifnotparams[1].isdigit():#print("执行的命令格式如下:python3xxx.py9000")#return#####代码执行到此,说明命令行参数的个数一定2个并且第二个参数是由数字组成的字符串#port=int(params[1])#创建web服务器web_server=HttpWebServer(8000)#启动服务器web_server.start()#判断是否是主模块的代码if__name__=='__main__':main()framework.py文件:"""web框架的职责专门负责处理动态资源请求"""importtimeroute_list=[]#定义带有参数的装饰器defroute(path):defdecorator(func):#装饰器执行的时候就需要把路由添加到路由列表里route_list.append((path,func))definner():result=func();returnresultreturninnerreturndecorator#获取首页数据@route("/index.html")defindex():#状态信息status="200OK"#响应头信息response_header=[("Server","PWS/1.1")]#1.打开指定模板文件,读取模板文件中的数据withopen("template/index.html","r",encoding='utf-8')asfile:file_data=file.read()#2.查询数据库,模板里面的模板变量替换成以后从数据库里查询的数据#web框架处理后的数据#获取当前时间,模拟数据库内容data=time.ctime()response_body=file_data.replace("{%content%}",data)#这里返回的是元组returnstatus,response_header,response_body#获取个人中心数据@route("/center.html")defcenter():#状态信息status="200OK"#响应头信息response_header=[("Server","PWS/1.1")]#1.打开指定模板文件,读取模板文件中的数据withopen("template/center.html","r",encoding='utf-8')asfile:file_data=file.read()#2.查询数据库,模板里面的模板变量替换成以后从数据库里查询的数据#web框架处理后的数据#获取当前时间,模拟数据库内容data=time.ctime()response_body=file_data.replace("{%content%}",data)#这里返回的是元组returnstatus,response_header,response_body#处理没有找到的动态资源defnot_found():#状态信息status="404NotFound"#响应头信息response_header=[("Server","PWS/1.1")]#web框架处理后的数据data="notfound"#这里返回的是元组returnstatus,response_header,data#处理动态资源请求defhandle_request(env):#获取动态的请求资源路径request_path=env["request_path"]print("动态资源请求的地址:",request_path)#判断请求的动态资源路径,选择指定的函数处理对应的动态资源请求forpath,funcinroute_list:ifrequest_path==path:result=func()returnresultelse:result=not_found()returnresult#ifrequest_path=="/index.html":##获取首页数据#result=index()##把处理后的结果返回给web服务器使用,让web服务器拼接响应报文时使用#returnresult#elifrequest_path=="/center.html":##个人中心#result=center()#returnresult#else:##没有动态资源数据,返回404状态信息#result=not_found()##把处理后的结果返回给web服务器使用,让web服务器拼接响应报文时使用#returnresultif__name__=="__main__":print(route_list)
framework.py文件:
"""web框架的职责专门负责处理动态资源请求"""
import time
route_list=[]
#定义带有参数的装饰器
def route(path):def decorator(func):#装饰器执行的时候就需要把路由添加到路由列表里route_list.append((path, func))def inner():result=func();return resultreturn innerreturn decorator# 获取首页数据
@route("/index.html")
def index():# 状态信息status = "200 OK"# 响应头信息response_header = [("Server", "PWS/1.1")]# 1.打开指定模板文件,读取模板文件中的数据with open("template/index.html","r",encoding='utf-8') as file:file_data=file.read()# 2.查询数据库,模板里面的模板变量替换成以后从数据库里查询的数据# web框架处理后的数据# 获取当前时间,模拟数据库内容data = time.ctime()response_body=file_data.replace("{%content%}",data)# 这里返回的是元组return status, response_header, response_body#获取个人中心数据
@route("/center.html")
def center():# 状态信息status = "200 OK"# 响应头信息response_header = [("Server", "PWS/1.1")]# 1.打开指定模板文件,读取模板文件中的数据with open("template/center.html","r",encoding='utf-8') as file:file_data=file.read()# 2.查询数据库,模板里面的模板变量替换成以后从数据库里查询的数据# web框架处理后的数据# 获取当前时间,模拟数据库内容data = time.ctime()response_body=file_data.replace("{%content%}",data)# 这里返回的是元组return status, response_header, response_body# 处理没有找到的动态资源
def not_found():# 状态信息status = "404 Not Found"# 响应头信息response_header = [("Server", "PWS/1.1")]# web框架处理后的数据data = "not found"# 这里返回的是元组return status, response_header, data# 处理动态资源请求
def handle_request(env):# 获取动态的请求资源路径request_path = env["request_path"]print("动态资源请求的地址:", request_path)# 判断请求的动态资源路径,选择指定的函数处理对应的动态资源请求for path, func in route_list:if request_path == path:result = func()return resultelse:result = not_found()return result# if request_path == "/index.html":# # 获取首页数据# result = index()# # 把处理后的结果返回给web服务器使用,让web服务器拼接响应报文时使用# return result# elif request_path=="/center.html":# #个人中心# result=center()# return result# else:# # 没有动态资源数据, 返回404状态信息# result = not_found()# # 把处理后的结果返回给web服务器使用,让web服务器拼接响应报文时使用# return result
if __name__=="__main__":print(route_list)
相关文章:

mini web框架示例
web框架: 使用web框架专门负责处理用户的动态资源请求,这个web框架其实就是一个为web服务器提供服务的应用程序 什么是路由? 路由就是请求的url到处理函数的映射,也就是说提前把请求的URL和处理函数关联好 管理路由可以使用一个…...

基于C#开发web网页管理系统模板流程-主界面统计功能完善
点击返回目录-> 基于C#开发web网页管理系统模板流程-总集篇-CSDN博客 前言 紧接上篇->基于C#开发web网页管理系统模板流程-主界面管理员入库和出库功能完善_c#web程序设计-CSDN博客 统计功能是管理系统很常见的功能,例如仓库管理系统要统计某时间段的出入库以…...
chromedriver114以后版本下载地址汇总chromedriver所有版本下载地址汇总国内源下载
谷歌浏览器版本经常会升级,chromedriver 也得下载匹配的版本 chromedriver 114以前版本下载地址https://registry.npmmirror.com/binary.html?pathchromedriver/ 但是自从115版本及其以后网站就找不到了,因此整理了截止2024年6月16日前所有在windows x6…...
x86计算机的启动初期流程 Linux 启动流程
x86计算机的启动初期流程 CPU: step1,加点开机,cpu自己初始化 step2,cpu 从物理地址 0xFFFFFFF0h 取指令执行;此处存放BIOS代码,这些代码可以是由主板自动从 EEPROM中拷贝至此内存地址处;即下…...

P450Rdb: CYP450数据库--地表最强系列--文献精读24
P450Rdb: A manually curated database of reactions catalyzed by cytochrome P450 enzymes P450Rdb: 一个人工整理的细胞色素P450酶催化反应数据库 http://www.cellknowledge.com.cn/p450rdb/ 还有一篇类似CYP450综述-20年-地表最强系列-文献精读-4 要点: P450…...

ubuntu 22.04下载和安装
ubuntu镜像: https://www.releases.ubuntu.com/22.04/ 然后下载vmwareworkstation16 密钥 ZF3R0-FHED2-M80TY-8QYGC-NPKYF...

Fegin如何传参form-data文件
Form-data传输file参数,这个大家都比较清楚,那么针对于Fegin参数file参数该如何操作呢!下面截图来找到对应的参数关系。 一、之前我们在postMan中是这种传参的,那么如果使用Feigin来传输文件File 二、在Fegin中传form-data参数&a…...

解决 Visual C++ 17.5 __cplusplus 始终为 199711L 的问题
目录 软件环境问题描述查阅资料解决问题参考文献 软件环境 Visual Studio 2022, Visual C, Version 17.5.4 问题描述 在应用 https://github.com/ToniLipponen/cpp-sqlite 的过程中,发现源代码文件 sqlite.hpp 中,有一处宏,和本项目的 C L…...

Mac M3 Pro安装Hadoop-3.3.6
1、下载Hadoop安装包 可以到官方网站下载,也可以使用网盘下载 官网下载地址:Hadoop官网下载地址 网盘地址:https://pan.baidu.com/s/1p4BXq2mvby2B76lmpiEjnA?pwdr62r提取码: r62r 2、解压并添加环境变量 # 将安装包移动到指定目录 mv …...

mac下Xcode在iphone真机上测试运行iOS软件
最近一个需求需要在iPhone真机上测试一个视频直播的项目。 需要解决如何将项目 app 安装到真机上 在进行真机调试。 安装Xcode 直接在App Store上搜索Xcode安装即可。 关键是要安装Simulator。项目需要安装iOS17.5但是由于安装包太大,并且网络不稳定的原因。在Xco…...

Mysql(一):深入理解Mysql索引底层数据结构与算法
众所众知,MySql的查询效率以及查询方式,基本上和索引息息相关,所以,我们一定要对MySql的索引有一个具体到数据底层上的认知。 这一次也是借着整理的机会,和大家一起重新复习一下MySql的索引底层。 本节也主要有一下的…...

WebMvcConfigurer配置不当导致鉴权失败
最近同事说他们有个新需求,需要对接口进行加解密,所以他给项目配置了一个拦截器,但这个拦截器直接导致了所有接口鉴权失败,每次调用接口都是提示没有session信息。 公司内的所有java项目是公用同一套基础依赖,所以我也…...

微信小程序毕业设计-实验室管理系统项目开发实战(附源码+论文)
大家好!我是程序猿老A,感谢您阅读本文,欢迎一键三连哦。 💞当前专栏:微信小程序毕业设计 精彩专栏推荐👇🏻👇🏻👇🏻 🎀 Python毕业设计…...

C#:lock锁与订单号(或交易号)的生成
在弄电商类网站的时候,往往是根据年月日时分秒的格式生成订单号(yyyyMMddHHmmss),为了解决并发性,就直接在生成订单号的区域块加上lock。 static void Main(string[] args){for(int i0; i<100; i){//GetRandomTime(…...

计算机图形学入门11:图形管线与着色器
1.什么是图形管线 把场景中的物体经过一系列的处理,最后一张图像的形式在屏幕上显示出来,这一系列过程就是图形管线(Graphics Pipeline),也叫实时渲染管线(Real-time Rendering Pipeline)。如下图所示,为整个渲染管线的过程。 渲染…...

正解 x86 Linux 内存管理
1,机器解析的思路 发现网络上大量的教程,多是以讹传讹地讲解 Linux 内存管理; 都是在讲: 逻辑地址 -> 线性地址 -> 物理地址 这个转换关系是怎么发生的。 上面这个过程确实是程序运行时地址的翻译顺序; …...
springboot读取配置时,读取到了系统环境变量
在Spring Boot应用中,读取配置通常通过application.properties或application.yml文件进行。不过,Spring Boot也支持从系统环境变量读取配置,这使得应用可以在不同的环境中灵活配置。下面详细介绍如何在Spring Boot中读取系统环境变量。 1. 配…...
平均召回(Average Recall,AR)概述
平均召回(Average Recall,AR)概述 在深度学习中,平均召回(Average Recall, AR)是一个衡量模型在不同阈值下的召回率的综合指标,特别常用于目标检测任务。召回率(Recall)…...

WWDC 2024 回顾:Apple Intelligence 的发布与解析
一年一度的苹果全球开发者大会(WWDC)如期而至,2024 年的 WWDC 再次成为科技界的焦点。本次发布会中,苹果正式推出了他们在 AI 领域的全新战略——Apple Intelligence。这一全新概念旨在为用户打造“强大、易用、全面、个性化、注重…...

[Cloud Networking] SPDY 协议
文章目录 1. 背景2. SPDY 之前3. SPDY 项目目标4. SPDY 功能特点4.1 SPDY基本功能4.2 SPDY高级功能 1. 背景 TCP是通用的、可靠的传输协议,提供保证交付、重复抑制、按顺序交付、流量控制、拥塞避免和其他传输特性。 HTTP是提供基本请求/响应语义的应用层协议。 不…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...

C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...