Python静态web服务器实战

准备html页面,包含两个页面(index.html, index2.html)和一个404(404html)页面,目录示意:

1.返回固定页面

with open("website/index.html","r") as file:

import socket# # 返回固定的页面 website/index.html
if __name__== '__main__':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(("",8000))tcp_server_socket.listen(128)#  循环等待接受客户端的连接请求while True:new_socket,ip_port = tcp_server_socket.accept()recv_data = new_socket.recv(4096)print(recv_data)with open("website/index.html","r") as file:file_data = file.read()# 把数据封装成http响应报文格式的数据# 响应行response_line = "HTTP/1.0 200 OK\r\n"# 响应头response_header = "Server:PWS/1.0\r\n"# 空行# 响应体response_body = file_dataresponse = response_line + response_header + "\r\n" + response_bodyresponse_data = response.encode("utf-8")new_socket.send(response_data)new_socket.close()

2.返回指定页面代码,动态指定request path

with open("website"+request_path,"rb") as file:

import socket# 返回指定的页面 website/index.htmldef pages():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(("",8000))tcp_server_socket.listen(128)#  循环等待接受客户端的连接请求while True:new_socket,ip_port = tcp_server_socket.accept()recv_data = new_socket.recv(4096)# 判断接受的数据长度是否为0if len(recv_data)==0:new_socket.close()return# 对二进制数据进行解码recv_content = recv_data.decode("utf-8")request_list = recv_content.split(" ",maxsplit=2)request_path = request_list[1]print(request_path)if request_path=="/":request_path = "/index.html"with open("website"+request_path,"rb") as file:file_data = file.read()# 把数据封装成http响应报文格式的数据# 响应行response_line = "HTTP/1.0 200 OK\r\n"# 响应头response_header = "Server:PWS/1.0\r\n"# 空行# 响应体response_body = file_dataresponse = (response_line + response_header + "\r\n").encode("utf-8") + response_bodynew_socket.send(response)new_socket.close()if __name__== '__main__':pages()

3.如果页面不存在返回404页面

with open("website/404.html","rb") as file:

import socket# 解决404页面def pages():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(("",8000))tcp_server_socket.listen(128)#  循环等待接受客户端的连接请求while True:new_socket,ip_port = tcp_server_socket.accept()recv_data = new_socket.recv(4096)# 判断接受的数据长度是否为0if len(recv_data)==0:new_socket.close()return# 对二进制数据进行解码recv_content = recv_data.decode("utf-8")request_list = recv_content.split(" ",maxsplit=2)request_path = request_list[1]print(request_path)if request_path=="/":request_path = "/index.html"try:with open("website"+request_path,"rb") as file:file_data = file.read()except Exception as e:with open("website/404.html","rb") as file:file_data = file.read()# 响应行response_line = "HTTP/1.0 404 Not Found\r\n"# 响应头response_header = "Server:PWS/1.0\r\n"# 空行# 响应体response_body = file_dataresponse = (response_line + response_header + "\r\n").encode("utf-8") + response_bodynew_socket.send(response)else:# 把数据封装成http响应报文格式的数据# 响应行response_line = "HTTP/1.0 200 OK\r\n"# 响应头response_header = "Server:PWS/1.0\r\n"# 空行# 响应体response_body = file_dataresponse = (response_line + response_header + "\r\n").encode("utf-8") + response_bodynew_socket.send(response)finally:new_socket.close()if __name__== '__main__':pages()

3.1 拓展,如果服务端有error

 except Exception as e:print(f"Error: {e}")response_line = "HTTP/1.0 500 Internal Server Error\r\n"response_header = "Server:PWS/1.0\r\n"response_body = b"Internal Server Error"response = (response_line + response_header + "\r\n").encode("utf-8") + response_body

4.多任务运行,threading

import socket
import threading# 解决404页面
# 解决多线程访问
def handle_client_reques(new_socket):recv_data = new_socket.recv(4096)# 判断接受的数据长度是否为0if len(recv_data)==0:new_socket.close()return# 对二进制数据进行解码recv_content = recv_data.decode("utf-8")request_list = recv_content.split(" ",maxsplit=2)request_path = request_list[1]print(request_path)if request_path=="/":request_path = "/index.html"try:with open("website"+request_path,"rb") as file:file_data = file.read()except Exception as e:with open("website/404.html","rb") as file:file_data = file.read()# 响应行response_line = "HTTP/1.0 404 Not Found\r\n"# 响应头response_header = "Server:PWS/1.0\r\n"# 空行# 响应体response_body = file_dataresponse = (response_line + response_header + "\r\n").encode("utf-8") + response_bodynew_socket.send(response)else:# 把数据封装成http响应报文格式的数据# 响应行response_line = "HTTP/1.0 200 OK\r\n"# 响应头response_header = "Server:PWS/1.0\r\n"# 空行# 响应体response_body = file_dataresponse = (response_line + response_header + "\r\n").encode("utf-8") + response_bodynew_socket.send(response)finally:new_socket.close()def pages():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(("",8000))tcp_server_socket.listen(128)#  循环等待接受客户端的连接请求while True:new_socket,ip_port = tcp_server_socket.accept()sub_threading = threading.Thread(target=handle_client_reques,args=(new_socket,))sub_threading.setDaemon(True)sub_threading.start()if __name__== '__main__':pages()

5.面向对象版

import socket
import threadingclass HttpWebServer(object):def __init__(self):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(("",8000))tcp_server_socket.listen(128)self.tcp_server_socket = tcp_server_socket# 解决404页面# 解决多线程访问@staticmethoddef handle_client_reques(new_socket):recv_data = new_socket.recv(4096)# 判断接受的数据长度是否为0if len(recv_data)==0:new_socket.close()return# 对二进制数据进行解码recv_content = recv_data.decode("utf-8")request_list = recv_content.split(" ",maxsplit=2)request_path = request_list[1]print(request_path)if request_path=="/":request_path = "/index.html"try:with open("website"+request_path,"rb") as file:file_data = file.read()except Exception as e:with open("website/404.html","rb") as file:file_data = file.read()# 响应行response_line = "HTTP/1.0 404 Not Found\r\n"# 响应头response_header = "Server:PWS/1.0\r\n"# 空行# 响应体response_body = file_dataresponse = (response_line + response_header + "\r\n").encode("utf-8") + response_bodynew_socket.send(response)else:# 把数据封装成http响应报文格式的数据# 响应行response_line = "HTTP/1.0 200 OK\r\n"# 响应头response_header = "Server:PWS/1.0\r\n"# 空行# 响应体response_body = file_dataresponse = (response_line + response_header + "\r\n").encode("utf-8") + response_bodynew_socket.send(response)finally:new_socket.close()def start(self):#  循环等待接受客户端的连接请求while True:new_socket,ip_port = self.tcp_server_socket.accept()sub_threading = threading.Thread(target=self.handle_client_reques,args=(new_socket,))sub_threading.setDaemon(True)sub_threading.start()def main(): #  创建web服务器web_server = HttpWebServer()#  启动服务器web_server.start()      if __name__== '__main__':main()

6.命令行启动动态绑定端口号

params = sys.argv

import socket
import threading
import sysclass HttpWebServer(object):def __init__(self,port):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)self.tcp_server_socket = tcp_server_socket# 解决404页面# 解决多线程访问@staticmethoddef handle_client_reques(new_socket):recv_data = new_socket.recv(4096)# 判断接受的数据长度是否为0if len(recv_data)==0:new_socket.close()return# 对二进制数据进行解码recv_content = recv_data.decode("utf-8")request_list = recv_content.split(" ",maxsplit=2)request_path = request_list[1]print(request_path)if request_path=="/":request_path = "/index.html"try:with open("website"+request_path,"rb") as file:file_data = file.read()except Exception as e:with open("website/404.html","rb") as file:file_data = file.read()# 响应行response_line = "HTTP/1.0 404 Not Found\r\n"# 响应头response_header = "Server:PWS/1.0\r\n"# 空行# 响应体response_body = file_dataresponse = (response_line + response_header + "\r\n").encode("utf-8") + response_bodynew_socket.send(response)else:# 把数据封装成http响应报文格式的数据# 响应行response_line = "HTTP/1.0 200 OK\r\n"# 响应头response_header = "Server:PWS/1.0\r\n"# 空行# 响应体response_body = file_dataresponse = (response_line + response_header + "\r\n").encode("utf-8") + response_bodynew_socket.send(response)finally:new_socket.close()def start(self):#  循环等待接受客户端的连接请求while True:new_socket,ip_port = self.tcp_server_socket.accept()sub_threading = threading.Thread(target=self.handle_client_reques,args=(new_socket,))sub_threading.setDaemon(True)sub_threading.start()def main(): params = sys.argvif len(params) !=2:print("请输入如下格式: python3xxx.py 8000")returnif not params[1].isdigit():print("请输入如下格式: python3xxx.py 8000")returnport = int(params[1])#  创建web服务器web_server = HttpWebServer(port)#  启动服务器web_server.start()      if __name__== '__main__':main()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/649751.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

arcgis 计算面积(计算经纬度、算数等同理)

arcgis 计算面积 先定义一个新的变量,例如:area 选中,右击,选择“打开属性表格”,在打开的属性表格中单击最左边的按钮,选择“添加字段” 定义新的字段为浮点型变量,定义变量名为area&#xff…

访问者模式-C#实现

该实例基于WPF实现,直接上代码,下面为三层架构的代码。 一 Model using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace 设计模式练习.Model.访问者模式 {public class Com…

网络安全全栈培训笔记(58-服务攻防-应用协议设备KibanaZabbix远控向日葵VNCTV)

第58天 服务攻防-应用协议&设备Kibana&Zabbix&远控向日葵&VNC&TV 知识点: 1、远程控制第三方应用安全 2、三方应用-向日葵&VNC&TV 3、设备平台-Zabbix&Kibanai漏洞 章节内容: 常见版务应用的安全测试: 1…

[蓝桥杯]真题讲解:冶炼金属(暴力+二分)

蓝桥杯真题视频讲解&#xff1a;冶炼金属&#xff08;暴力做法与二分做法&#xff09; 一、视频讲解二、暴力代码三、正解代码 一、视频讲解 视频讲解 二、暴力代码 //暴力代码 #include<bits/stdc.h> #define endl \n #define deb(x) cout << #x << &qu…

Flink面试题

0. 思维导图 1. 简单介绍一下Flink♥♥ Flink是一个分布式的计算框架&#xff0c;主要用于对有界和无界数据流进行有状态计算&#xff0c;其中有界数据流就是值离线数据&#xff0c;有明确的开始和结束时间&#xff0c;无界数据流就是指实时数据&#xff0c;源源不断没有界限&a…

【c语言】详解操作符(上)

1. 操作符的分类 2. 原码、反码、补码 整数的2进制表示方法有三种&#xff0c;即原码、反码、补码 有符号整数的三种表示方法均有符号位和数值位两部分&#xff0c;2进制序列中&#xff0c;最高位的1位是被当做符号位其余都是数值位。 符号位都是用0表示“正”&#xff0c;用…

JavaScript高级:闭包

1 概念 一个函数对周围状态的引用&#xff0c;捆绑在一起&#xff0c;内层函数中可以访问到外层函数的作用域。 简单理解&#xff1a;闭包 内层函数 外层函数的变量 先看个简单的代码&#xff1a; function outer() {let a 1function inner() {console.log(a)} } outer(…

Mysql-日志介绍 日志配置

环境部署 docker run -d -p 3306:3306 --privilegedtrue -v $(pwd)/logs:/var/lib/logs -v $(pwd)/conf:/etc/mysql/conf.d -v $(pwd)/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD654321 --name mysql mysql:5.7运行指令的目录下新建好这些文件&#xff1a; 日志类型 日…

顶顶通呼叫中心中间件机器人压力测试配置(mod_cti基于FreeSWITCH)

介绍 顶顶通呼叫中心中间件机器人压力测试(mod_cit基于FreeSWITCH) 一、配置acl.conf 打开ccadmin-》点击配置文件-》点击acl.conf-》我这里是已经配置好了的&#xff0c;这里的192.168.31.145是我自己的内网IP&#xff0c;你们还需要自行修改 二、配置线路 打开ccadmin-&g…

mac/macos上编译electron源码

官方教程&#xff1a;Build Instructions | Electron 准备工作这里不写了&#xff0c;参考官方文档&#xff0c;还有上一篇windows编译electron electron源码下载及编译-CSDN博客 差不多步骤&#xff0c;直接来 网络记得使用魔法 下载编译步骤 0. 选择目录很重要&#xff0…

Mac网线上网绿联扩展坞连接网线直接上网-无脑操作

声明&#xff1a;博主使用的绿联扩展坞 以下为绿联扩展坞Mac网线使用方法 1.首先需要下载电脑对应版本的驱动 直接点击即可下载 2. 下载好以后 解压 点进去 对应版本 博主直接使用最新的12-14 3. 安装包好了以后 会提示重启电脑 此时拔掉扩展坞 再重启动 拔掉扩展坞 再重启…

HttpHeaders 源码中headers成员变量为什么声明为final

源码如下 public class HttpHeaders implements MultiValueMap<String, String>, Serializable {private final Map<String, List<String>> headers;public String getFirst(String headerName) {List<String> headerValues (List)this.headers.get(…

2024最新版Visual Studio Code安装使用指南

2024最新版Visual Studio Code安装使用指南 Installation and Usage Guide for the Latest Visual Studio Code in 2024 By JacksonML Visual Studio Code最新版1.85已经于2023年11月由其官网 https://code.visualstudio.com正式发布&#xff0c;这是微软公司2024年发行的的最…

Android App开发基础(1)—— App的开发特点

本文介绍基于Android系统的App开发常识&#xff0c;包括以下几个方面&#xff1a;App开发与其他软件开发有什么不一样&#xff0c;App工程是怎样的组织结构又是怎样配置的&#xff0c;App开发的前后端分离设计是如何运作实现的&#xff0c;App的活动页面是如何创建又是如何跳转…

TensorFlow2实战-系列教程3:猫狗识别1

&#x1f9e1;&#x1f49b;&#x1f49a;TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 1、项目介绍 基本流程&#xff1a; 数据预处理&#xff1a;图像数据处理&#xff0c…

Web3:B站chainlink课程Lesson5遇到的小坑汇总

ethers代码 我用的ethers.js 6 &#xff0c;和视频里一样用的是5的不用看代码部分 ethers.providers.JsonRpcProvider("server") //无了 ethers.JsonRpcProvider("server") //现在的wallet.getTransactionCount() //无了 wallet.getNonce() //现在的Big…

已解决:安卓,怎么优雅接入科大讯飞语音评测功能?

写在前面&#xff1a; 网上关于讯飞接入的博客都很少&#xff0c;按说讯飞都是业界翘楚&#xff0c;不知为何&#xff0c;很少搜索到精品&#xff0c;一搜就是一个要求开会员的博客&#xff0c;我也是醉了。讯飞提供的文档也是不清晰&#xff0c;我是摸着石头过河&#xff0c;…

java集合ArrayList和HashSet的fail-fast与fail-safe以及ConcurrentModificationException

在 java 的集合工具类中&#xff0c;例如对 ArrayList 或者 HashSet 进行删除元素后再遍历元素时&#xff0c;会抛出 ConcurrentModificationException 异常。 fail-fast ArrayList public class TestList {public static void main(String[] args) {ArrayList<Integer>…

【iOS ARKit】BlendShapes

BlendShapes 基础介绍 利用前置摄像头采集到的用户面部表情特征&#xff0c;ARKit 提供了一种更加抽象的表示面部表情的方式&#xff0c;这种表示方式叫作 BlendShapes,BlendShapes 可以翻译成形状融合&#xff0c;在3ds Max 中也叫变形器&#xff0c;这个概念原本用于描述通过…

Ubuntu18编译jdk8源码

环境 系统 ubuntu18 Linux ubuntu 5.4.0-150-generic #167~18.04.1-Ubuntu SMP Wed May 24 00:51:42 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux jdk源码openjdk-8u41-src-b04-14_jan_2020.zip bootJdk jdk-8u391-linux-x64.tar.gz ps -e|grep ssh sudo apt-get install ssh…