Python静态web服务器实战

news2024/10/7 4:51:28

准备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_data
      
        response = response_line + response_header + "\r\n" + response_body
        
        response_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.html

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)
        # 判断接受的数据长度是否为0
        if 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_data
      
        response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
        
        new_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)
        # 判断接受的数据长度是否为0
        if 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_data
        
            response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
            
            new_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_data
        
            response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
            
            new_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)

        # 判断接受的数据长度是否为0
    if 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_data
    
        response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
        
        new_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_data
    
        response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
        
        new_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 threading

class 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页面
    # 解决多线程访问
    @staticmethod
    def handle_client_reques(new_socket):
        recv_data = new_socket.recv(4096)

            # 判断接受的数据长度是否为0
        if 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_data
        
            response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
            
            new_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_data
        
            response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
            
            new_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 sys

class 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页面
    # 解决多线程访问
    @staticmethod
    def handle_client_reques(new_socket):
        recv_data = new_socket.recv(4096)

            # 判断接受的数据长度是否为0
        if 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_data
        
            response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
            
            new_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_data
        
            response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
            
            new_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.argv
    if len(params) !=2:
        print("请输入如下格式: python3xxx.py 8000")
        return
    if not params[1].isdigit():
        print("请输入如下格式: python3xxx.py 8000")
        return
    port = int(params[1])
     
    #  创建web服务器
    web_server = HttpWebServer(port)
    #  启动服务器
    web_server.start()      


                   

if __name__== '__main__':
   main()

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

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

相关文章

怎么将word转换成pdf?一步到位,轻松搞定!

怎么将word转换成pdf?在数字时代,我们经常需要将文档转换为PDF格式,以便在不同的设备和平台上共享和查看。然而,许多人对如何将Word转换成PDF感到困惑。本文将为你详细介绍将Word转换成PDF的步骤,让你轻松掌握这一技能…

php+Layui开发的网站信息探针查询源码

信息探针是一款基于layui开发的专业查询好友个人信息的程序。 自定义设置探针页面,探针功能,QQ分享,通知邮箱等功能。 生成页面链接好友点击会出现好友ip 位置信息,手机型号ua头浏览器等信息 gps需要注册百度地图开发者才可以使用…

【RabbitMQ】延迟队列之死信交换机

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《RabbitMQ实战》。🎯🎯 &am…

代码随想录算法训练营第31天(贪心算法01 | ● 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和

贪心算法01 理论基础455.分发饼干解题思路 376. 摆动序列解题思路拓展 53. 最大子序和解题思路常见误区注意点 贪心算法其实就是没有什么规律可言,所以大家了解贪心算法 就了解它没有规律的本质就够了。 不用花心思去研究其规律, 没有思路就立刻看题解。…

mysql入门到精通002--基础篇

1、基础篇课程内容 2、MySQL概述 2.1 数据库相关概念 2.1.1、数据库 存储数据的仓库 2.1.2、SQL 操作关系型数据库的一套标准语言,定义了一套关系型数据库的统一标准。 2.1.3、关系型数据库管理系统 2.2 mysql数据库 2.2.1 安装与使用 下载地址:…

婴幼儿营养之道:新生儿补充磷脂酰丝氨酸的关键

引言: 磷脂酰丝氨酸是一种对于新生儿神经系统发育和整体健康至关重要的成分。在新生儿成长的早期阶段,科学合理的补充磷脂酰丝氨酸有助于促进大脑和神经系统的发育,为宝宝的智力和身体健康奠定坚实基础。本文将深入探讨磷脂酰丝氨酸的作用、…

24.1.25 DAY2 C++

思维导图: 2.题目: 自己封装一个矩形类(Rect),拥有私有属性:宽度(width)、高度(height), 定义公有成员函数: 初始化函数:void init(int w, int h) 更改宽度的函数:set_w(int w) 更改高度的函数:set_h(int h) 输出该矩形的周…

Android串口通讯 报错 NO_READ_WRITE_PERMISSION

在调试Android串口通讯的时候,特别是串口连接使用的usb接口作为物理介质的时候,报错 NO_READ_WRITE_PERMISSION ,一个很容易忽略的问题就是串口地址错误 因为每个机器都有自己的串口地址名称定义方式。 解决办法:1、通过cmd sh…

Google Chrome RCE漏洞 CVE-2020-6507 和 CVE-2024-0517的简单分析

本文深入研究了两个在 Google Chrome 的 V8 JavaScript 引擎中发现的漏洞,分别是 CVE-2020-6507 和 CVE-2024-0517。这两个漏洞都涉及 V8 引擎的堆损坏问题,允许远程代码执行。通过EXP HTML部分的内存操作、垃圾回收等流程方式实施利用攻击。 CVE-2020-…

查询机器近期的重启记录

打开Command Prompt命令行,运行下面命令: systeminfo | find "System Boot Time:" 如图,这台设备上一次重启时间是1月21日。

Ant Design Vue详解a-tree-select使用树形选择器,递归渲染数据,点击选项回显,一二级菜单是否可选等问题

后台给的树形数据: {"code": 200,"data": [{"code": "jsd","children": [{"code": "hx","children": [],"name": "航向","id": 8,"libTable…

YOLOv8改进 | Conv篇 | 利用DualConv二次创新C2f提出一种轻量化结构(轻量化创新)

一、本文介绍 本文给大家带来的改进机制是利用DualConv改进C2f提出一种轻量化的C2f,DualConv是一种创新的卷积网络结构,旨在构建轻量级的深度神经网络。它通过结合33和11的卷积核处理相同的输入特征映射通道,优化了信息处理和特征提取。DualConv利用组卷积技术高效排列卷积…

【AI】Chinese-LLaMA-Alpaca-2 7B llama.cpp 量化方法选择及推理速度测试 x86_64 RTX 2060 6G 显存太小了

环境 操作系统 CPU 内存 生成量化版本模型 转换出q4_0 q4_k q6_k q8_0模型 cd ~/Downloads/ai/llama.cpp sourvce venv/bin/activate ~/Downloads/ai/llama.cpp/quantize /home/yeqiang/Downloads/ai/chinese-alpaca-2-7b/ggml-model-f16.gguf /home/yeqiang/Downloads/ai/ch…

mapstruct自定义转换,怎样将String转化为List

源码&#xff1a;https://gitee.com/cao_wen_bin/test 最近在公司遇到了这样一个为题&#xff0c;前端传过来的是一个List<Manager>,往数据库中保存到时候是String&#xff0c;这个String使用谷歌的json转化器。 当查询的时候在将这个数据库中String的数据以List<Mana…

Leetcode—29. 两数相除【中等】

2023每日刷题&#xff08;九十四&#xff09; Leetcode—29. 两数相除 叛逆期实现代码 class Solution { public:int divide(int dividend, int divisor) {if(dividend INT_MIN && divisor -1) {return INT_MAX;} return dividend / divisor;} };运行结果 倍增算法…

牛客NC222104重排字符串(C++)

题目链接 实现方法 统计各字符出现的次数&#xff1b;判断是否能实现重排&#xff08;根据出现次数最多的字符数量ma和字符总长度n判断&#xff09;&#xff1b;依次输出出现次数最多的两个字符&#xff0c;直到出现次数最多的字符和次多的字符数量相同&#xff1b;依次输出…

代码随想录算法训练营第30天 | 回溯总结 + 3道Hard题目

今日任务 332.重新安排行程 51. N皇后 37. 解数独 总结 总结 回溯总结&#xff1a;代码随想录 回溯是递归的副产品&#xff0c;只要有递归就会有回溯&#xff0c;所以回溯法也经常和二叉树遍历&#xff0c;深度优先搜索混在一起&#xff0c;因为这两种方式都是用了递归。 …

redis排序

文章目录 简介SORT命令的实现ALPHA选项的实现ASC和DESCBYLIMITGET命令 类似映射STORE选项的实现多个命令的执行顺序 简介 Redis的SORT命令可以对列表键、集合键或者有序集合键的值进行排序。 SORT命令的实现 服务器执行SORT numbers 命令的详细步骤如下&#xff1a; 1&#…

一、MongoDB、express的安装和基本使用

数据库【Sqlite3、MongoDB、Mysql】简介&小记 Sqlite3&#xff1a; SQLite3是一个轻量级的数据库系统&#xff0c;它被设计成嵌入式数据库。这意味着它是一个包含在应用程序中的数据库&#xff0c;而不是独立运行的系统服务。适用场景&#xff1a;如小型工具、游戏、本地…

DevSecOps 参考模型介绍

目录 一、参考模型概述 1.1 概述 二、参考模型分类 2.1 DevOps 组织型模型 2.1.1 DevOps 关键特性 2.1.1.1 模型特性图 2.1.1.2 特性讲解 2.1.1.2.1 自动化 2.1.1.2.2 多边协作 2.1.1.2.3 持续集成 2.1.1.2.4 配置管理 2.1.2 DevOps 生命周期 2.1.2.1 研发过程划分…