当前位置: 首页 > news >正文

【Python使用】嘿马python高级进阶全体系教程第10篇:静态Web服务器-返回固定页面数据,1. 开发自己的静态Web服务器【附代码文档】

本教程的知识点为:操作系统 1. 常见的操作系统 4. 小结 ls命令选项 2. 小结 mkdir和rm命令选项 1. mkdir命令选项 压缩和解压缩命令 1. 压缩格式的介绍 2. tar命令及选项的使用 3. zip和unzip命令及选项的使用 4. 小结 编辑器 vim 1. vim 的介绍 2. vim 的工作模式 3. vim 的末行模式命令 4. vim 的常用命令 获取进程编号 1. 获取进程编号的目的 2. 获取当前进程编号 3. 获取当前父进程编号 4. 小结 线程执行带有参数的任务 1. 线程执行带有参数的任务的介绍 2. args参数的使用 3. kwargs参数的使用 4. 小结 1. s锁的概念 2. s锁示例 3. 避免s锁 4. 小结 端口和端口号的介绍 1. 问题思考 2. 什么是端口 3. 什么端口号 4. 端口和端口号的关系 HTTP 协议 1. HTTP 协议的介绍 2. HTTP 协议的作用 3. 浏览器访问web服务器的通信过程 4. 小结 静态Web服务器-返回固定页面数据 1. 开发自己的静态Web服务器 2. 静态Web服务器-返回固定页面数据的示例代码 3. 小结 静态Web服务器-返回指定页面数据 静态Web服务器-面向对象开发 1. 以面向对象的方式开发静态Web服务器 2. 静态Web服务器-面向对象开发的示例代码 3. 小结 静态Web服务器-命令行启动动态绑定端口号 修改闭包内使用的外部变量 1. 修改闭包内使用的外部变量 2. 小结 装饰器 1. 装饰器的定义 property属性 1. property属性的介绍 2. 装饰器方式 3. 类属性方式 4. 小结 深拷贝和浅拷贝 1. 浅拷贝 2. 深拷贝 3. 浅拷贝和深拷贝的区别 4. 总结 匹配多个字符 1. 匹配多个字符 示例1:* 示例2:+ 示例3:?

完整笔记资料代码:https://gitee.com/yinuo112/Backend/tree/master/Python/嘿马python高级进阶全体系教程/note.md

感兴趣的小伙伴可以自取哦~


全套教程部分目录:


部分文件图片:

静态Web服务器-返回固定页面数据

学习目标

  • 能够写出组装固定页面数据的响应报文

1. 开发自己的静态Web服务器

实现步骤:

  1. 编写一个TCP服务端程序
  2. 获取浏览器发送的http请求报文数据
  3. 读取固定页面数据,把页面数据组装成HTTP响应报文数据发送给浏览器。
  4. HTTP响应报文数据发送完成以后,关闭服务于客户端的套接字。

2. 静态Web服务器-返回固定页面数据的示例代码

import socketif __name__ == '__main__':# 创建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(("", 9000))# 设置监听tcp_server_socket.listen(128)while True:# 等待接受客户端的连接请求new_socket, ip_port = tcp_server_socket.accept()# 代码执行到此,说明连接建立成功recv_client_data = new_socket.recv(4096)# 对二进制数据进行解码recv_client_content = recv_client_data.decode("utf-8")print(recv_client_content)with open("static/index.html", "rb") as file:# 读取文件数据file_data = file.read()# 响应行response_line = "HTTP/1.1 200 OK\r\n"# 响应头response_header = "Server: PWS1.0\r\n"# 响应体response_body = file_data# 拼接响应报文response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body# 发送数据new_socket.send(response_data)# 关闭服务与客户端的套接字new_socket.close()

3. 小结

  1. 编写一个TCP服务端程序
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 循环接受客户端的连接请求while True:conn_socket, ip_port = tcp_server_socket.accept()
  1. 获取浏览器发送的http请求报文数据
client_request_data = conn_socket.recv(4096)
  1. 读取固定页面数据,把页面数据组装成HTTP响应报文数据发送给浏览器。
response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body
conn_socket.send(response_data)
  1. HTTP响应报文数据发送完成以后,关闭服务于客户端的套接字。
conn_socket.close()

静态Web服务器-返回指定页面数据

学习目标

  • 能够写出组装指定页面数据的响应报文

1. 静态Web服务器的问题

问题

目前的Web服务器,不管用户访问什么页面,返回的都是固定页面的数据,接下来需要根据用户的请求返回指定页面的数据

返回指定页面数据的实现步骤:

  1. 获取用户请求资源的路径
  2. 根据请求资源的路径,读取指定文件的数据
  3. 组装指定文件数据的响应报文,发送给浏览器
  4. 判断请求的文件在服务端不存在,组装404状态的响应报文,发送给浏览器

2. 静态Web服务器-返回指定页面数据的示例代码

import socketdef main():# 创建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(("", 9000))# 设置监听tcp_server_socket.listen(128)while True:# 等待接受客户端的连接请求new_socket, ip_port = tcp_server_socket.accept()# 代码执行到此,说明连接建立成功recv_client_data = new_socket.recv(4096)if len(recv_client_data) == 0:print("关闭浏览器了")new_socket.close()return# 对二进制数据进行解码recv_client_content = recv_client_data.decode("utf-8")print(recv_client_content)# 根据指定字符串进行分割, 最大分割次数指定2request_list = recv_client_content.split(" ", maxsplit=2)# 获取请求资源路径request_path = request_list[1]print(request_path)# 判断请求的是否是根目录,如果条件成立,指定首页数据返回if request_path == "/":request_path = "/index.html"try:# 动态打开指定文件with open("static" + request_path, "rb") as file:# 读取文件数据file_data = file.read()except Exception as e:# 请求资源不存在,返回404数据# 响应行response_line = "HTTP/1.1 404 Not Found\r\n"# 响应头response_header = "Server: PWS1.0\r\n"with open("static/error.html", "rb") as file:file_data = file.read()# 响应体response_body = file_data# 拼接响应报文response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body# 发送数据new_socket.send(response_data)else:# 响应行response_line = "HTTP/1.1 200 OK\r\n"# 响应头response_header = "Server: PWS1.0\r\n"# 响应体response_body = file_data# 拼接响应报文response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body# 发送数据new_socket.send(response_data)finally:# 关闭服务与客户端的套接字new_socket.close()if __name__ == '__main__':main()

3. 小结

  1. 获取用户请求资源的路径
request_list = client_request_conent.split(” ”,  maxsplit=2)request_path = request_list[1]
  1. 根据请求资源的路径,读取请求指定文件的数据
with open("static" + request_path, "rb") as file:file_data = file.read()
  1. 组装指定文件数据的响应报文,发送给浏览器
response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_bodyconn_socket.send(response_data)
  1. 判断请求的文件在服务端不存在,组装404状态的响应报文,发送给浏览器
try:# 打开指定文件,代码省略...except Exception as e:conn_socket.send(404响应报文数据)

静态Web服务器-多任务版

学习目标

  • 能够写出多线程版的多任务web服务器程序

1. 静态Web服务器的问题

目前的Web服务器,不能支持多用户同时访问,只能一个一个的处理客户端的请求,那么如何开发多任务版的web服务器同时处理 多个客户端的请求?

可以使用多线程,比进程更加节省内存资源。

多任务版web服务器程序的实现步骤:

  1. 当客户端和服务端建立连接成功,创建子线程,使用子线程专门处理客户端的请求,防止主线程阻塞。

  2. 把创建的子线程设置成为守护主线程,防止主线程无法退出。

2. 静态Web服务器-多任务版的示例代码

import socket
import threading# 处理客户端的请求def handle_client_request(new_socket):# 代码执行到此,说明连接建立成功recv_client_data = new_socket.recv(4096)if len(recv_client_data) == 0:print("关闭浏览器了")new_socket.close()return# 对二进制数据进行解码recv_client_content = recv_client_data.decode("utf-8")print(recv_client_content)# 根据指定字符串进行分割, 最大分割次数指定2request_list = recv_client_content.split(" ", maxsplit=2)# 获取请求资源路径request_path = request_list[1]print(request_path)# 判断请求的是否是根目录,如果条件成立,指定首页数据返回if request_path == "/":request_path = "/index.html"try:# 动态打开指定文件with open("static" + request_path, "rb") as file:# 读取文件数据file_data = file.read()except Exception as e:# 请求资源不存在,返回404数据# 响应行response_line = "HTTP/1.1 404 Not Found\r\n"# 响应头response_header = "Server: PWS1.0\r\n"with open("static/error.html", "rb") as file:file_data = file.read()# 响应体response_body = file_data# 拼接响应报文response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body# 发送数据new_socket.send(response_data)else:# 响应行response_line = "HTTP/1.1 200 OK\r\n"# 响应头response_header = "Server: PWS1.0\r\n"# 响应体response_body = file_data# 拼接响应报文response_data = (response_line + response_header + "\r\n").encode("utf-8") + response_body# 发送数据new_socket.send(response_data)finally:# 关闭服务与客户端的套接字new_socket.close()# 程序入口函数def main():# 创建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(("", 9000))# 设置监听tcp_server_socket.listen(128)while True:# 等待接受客户端的连接请求new_socket, ip_port = tcp_server_socket.accept()print(ip_port)# 当客户端和服务器建立连接程,创建子线程sub_thread = threading.Thread(target=handle_client_request, args=(new_socket,))# 设置守护主线程sub_thread.setDaemon(True)# 启动子线程执行对应的任务sub_thread.start()if __name__ == '__main__':main()

3. 小结

  1. 当客户端和服务端建立连接成功,创建子线程,使用子线程专门处理客户端的请求,防止主线程阻塞。
while True:conn_socket, ip_port = tcp_server_socket.accept()# 开辟子线程并执行对应的任务sub_thread = threading.Thread(target=handle_client_request, args=(conn_socket,))
  1. 把创建的子线程设置成为守护主线程,防止主线程无法退出。
# 开辟子线程并执行对应的任务sub_thread = threading.Thread(target=handle_client_request, args=(conn_socket,))sub_thread.setDaemon(True) # 设置守护主线程sub_thread.start()

相关文章:

【Python使用】嘿马python高级进阶全体系教程第10篇:静态Web服务器-返回固定页面数据,1. 开发自己的静态Web服务器【附代码文档】

本教程的知识点为:操作系统 1. 常见的操作系统 4. 小结 ls命令选项 2. 小结 mkdir和rm命令选项 1. mkdir命令选项 压缩和解压缩命令 1. 压缩格式的介绍 2. tar命令及选项的使用 3. zip和unzip命令及选项的使用 4. 小结 编辑器 vim 1. vim 的介绍 2. vim 的工作模式 …...

软件测试面试题和简历模板(面试前准备篇)

一、问题预测 1、让简单介绍下自己(这个不用说了每次面试开场) 面试官,你好,我叫xxx,xx年本科毕业,从事软件测试将近3年的时间。在此期间做过一些项目也积累过一些经验,能够独立地完成软件测试…...

Linux 基本使用和程序部署

1. Linux 环境搭建 1.1 环境搭建方式 主要有 4 种: 直接安装在物理机上。但是Linux桌面使用起来非常不友好,所以不建议。[不推荐]。使用虚拟机软件,将Linux搭建在虚拟机上。但是由于当前的虚拟机软件(如VMWare之类的)存在一些bug&#xff…...

uniapp微信小程序,使用fastadmin完成一个一键获取微信手机号的功能

前端部分 点击按钮&#xff0c;获取手机号 <button open-type"getPhoneNumber" getphonenumber"bindGetPhoneNumber" hover-class"none"class"btn-purity">一键获取</button> 传入openid和code bindGetPhoneNumber(e) …...

CSS系列(27)- 图形与滤镜详解

前端技术探索系列&#xff1a;CSS 图形与滤镜详解 &#x1f3a8; 致读者&#xff1a;探索CSS的艺术表现力 &#x1f44b; 前端开发者们&#xff0c; 今天我们将深入探讨 CSS 图形和滤镜效果&#xff0c;学习如何创建引人注目的视觉效果。 基础图形 &#x1f680; 几何形状…...

Docker 技术系列之安装多版本Mysql5.6和Mysql5.7

image 大家好&#xff0c;后面的就不是关于MAC专有的内容&#xff0c;基本是跟Java环境&#xff0c;基础技术方面有关。所以这个教程对于在linux系统还是macOS都是通用的&#xff0c;不用担心。 上一篇&#xff0c;我们安装好对应的Docker之后&#xff0c;感受到了它的便利。接…...

理解并使用Linux 内核中的 Tracepoint

理解并使用Linux 内核中的 Tracepoint 1. 引言 1.1 为什么需要 Tracepoint&#xff1f; 在内核调试与性能分析中&#xff0c;传统的 printk 方法虽然简单直接&#xff0c;但存在几个显著的局限性&#xff1a; 日志噪音&#xff1a;printk 会将所有输出无差别地记录到系统日…...

centos7中Gbase8s数据库安装,以及数据导入遇到的一系列问题

centos7中Gbase8s数据库安装&#xff0c;以及遇到的一系列问题 以下是我在centos7上安装gbase8s数据库遇到的一系列问题&#xff0c;包括数据库安装&#xff0c;数据导入&#xff0c;数据连接&#xff0c;不能完全作为标准&#xff0c;只可作为类似问题参考&#xff0c;有问题…...

AW36518芯片手册解读(3)

接前一篇文章&#xff1a;AW36518芯片手册解读&#xff08;2&#xff09; 二、详述 3. 功能描述 &#xff08;1&#xff09;上电复位 当电源电压VIN降至预定义电压VPOR&#xff08;典型值为2.0V&#xff09;以下时&#xff0c;该设备会产生复位信号以执行上电复位操作&#x…...

MySQL的REPEATABLE READ事务隔离级别

本文隔离级别&#xff1a; T1内读T2的update数据 首先开两个事务&#xff08;左二&#xff09; 事务1修改成李四,提交 事务2再读还是张三&#xff0c;也就是说&#xff0c;记录的数据从事务开始时一直到结束&#xff0c;读的都是同一个版本,读不到T2未提交的此条记录修改&…...

sqoop的参数有哪些?

Sqoop 是一款用于在 Hadoop 与关系型数据库之间进行数据传输的工具&#xff0c;它有很多参数&#xff0c;可分为通用参数、导入参数和导出参数等&#xff0c;以下是一些常见的参数介绍&#xff1a; 通用参数 --connect 说明&#xff1a;指定要连接的关系型数据库的 JDBC URL。…...

动态规划<四> 回文串问题(含对应LeetcodeOJ题)

目录 引例 其余经典OJ题 1.第一题 2.第二题 3.第三题 4.第四题 5.第五题 引例 OJ 传送门Leetcode<647>回文子串 画图分析&#xff1a; 使用动态规划解决 原理&#xff1a;能够将所有子串是否是回文的信息保存在dp表中 在使用暴力方法枚举出所有子串&#xff0c;是…...

跨模态知识迁移:基于预训练语言模型的时序数据建模

在NLP和CV领域&#xff0c;通常通过在统一的预训练模型上进行微调&#xff0c;能够在各自领域的下游任务中实现SOTA&#xff08;最先进&#xff09;的结果。然而&#xff0c;在时序预测领域&#xff0c;由于数据量相对较少&#xff0c;难以训练出一个统一的预训练模型来覆盖所有…...

重温设计模式--职责链模式

文章目录 职责链模式的详细介绍C 代码示例C示例代码2 职责链模式的详细介绍 定义与概念 职责链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为型设计模式&#xff0c;它旨在将请求的发送者和多个接收者解耦&#xff0c;让多个对象都有机会处理请求&a…...

git冲突解决

git冲突解决 最近遇到了一次git冲突的问题 起因是因为最近公司数据推送部分重构&#xff0c;负责重构的同事就改动了我的一小部分推送的代码&#xff0c;然后等我开发完合并到远程master的时候&#xff0c;报了merge冲突。我对于git工具确实不是很熟练&#xff0c;只是学习了…...

Java学习笔记(14)--面向对象编程

面向对象基础 学习资料来自多态 - Java教程 - 廖雪峰的官方网站 目录 面向对象基础 Override 多态 举个例子 覆写Object方法 调用super final 练习 小结 Override 在继承关系中&#xff0c;子类如果定义了一个与父类方法签名完全相同的方法&#xff0c;被称为覆写&…...

《Swift 字面量》

《Swift 字面量》 介绍 在 Swift 编程语言中&#xff0c;字面量是一种表示源代码中固定值的表达方式。字面量可以直接表示数字、字符串、布尔值等基本数据类型&#xff0c;为编程提供了简洁和直观的方式。Swift 支持多种类型的字面量&#xff0c;包括整数字面量、浮点数字面量…...

数据库 SQL 常用语句全解析

数据库 SQL 常用语句全解析 在数据库领域&#xff0c;SQL&#xff08;Structured Query Language&#xff09;作为标准语言&#xff0c;掌控着数据的查询、插入、更新与删除等关键操作。无论是新手入门数据库&#xff0c;还是经验丰富的开发者日常工作&#xff0c;熟练掌握 SQ…...

SQLite 命令

关于《SQLite 命令》的文章&#xff0c;我可以为您概述一些关键点。SQLite是一个轻量级的数据库管理系统&#xff0c;它被广泛用于各种应用程序中。SQLite命令主要分为两类&#xff1a;一类是SQL命令&#xff0c;另一类是SQLite特定的点命令。 SQL命令&#xff1a;这些命令用于…...

本地如何启动casdoor

1、下载代码 GitHub - casdoor/casdoor at v1.777.0 下载对应tag的代码&#xff0c;我这里选择的时v1.777.0版本 通过网盘分享的文件&#xff1a;casdoor-1.777.0.zip 链接: https://pan.baidu.com/s/1fPNqyJYeyfZnem_LtEc0hw 提取码: avpd 2、启动后端 1、使用goland编译…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

代码随想录刷题day30

1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释

以Module Federation 插件详为例&#xff0c;Webpack.config.js它可能的配置和含义如下&#xff1a; 前言 Module Federation 的Webpack.config.js核心配置包括&#xff1a; name filename&#xff08;定义应用标识&#xff09; remotes&#xff08;引用远程模块&#xff0…...