首页 > 编程语言 >关于python http.server 开启多线程并发的问题

关于python http.server 开启多线程并发的问题

时间:2023-12-18 12:14:25浏览次数:25  
标签:http python self send server print path 多线程 sfc

问题描述

thon中的http.server模块是单线程的,这意味着它一次只能处理一个请求,而其他请求必须等待。

为了解决这个问题,您可以考虑使用多线程或异步处理来处理并发请求。您可以使用Python的ThreadingMixIn来创建一个支持多线程的HTTP服务器,或者考虑使用异步框架如asyncio来处理请求。

另外,您还可以考虑使用更高级的Web框架,如Flask、Django或Tornado,它们提供了更多的功能和性能优化,能够更好地处理并发请求。

如果您需要关于如何实现多线程或异步处理的具体代码示例,或者有其他问题需要解决,请随时告诉我,我会尽力帮助您。

# -*- coding: utf-8 -*-
from http.server import HTTPServer, BaseHTTPRequestHandler
import os
import urllib
from http import HTTPStatus
import re
import glob
import xml.etree.ElementTree as ET
from html import escape
#ip, port config
host = ('0.0.0.0', 8890)
base_path=os.getcwd().replace("\\",'/')
print(f"根目录{base_path}")
class Resquest(BaseHTTPRequestHandler):
    def do_GET(self):
        # print(self.path)
        if self.path == '/':
            self.send_response(200)
            self.end_headers()
            f = open("index.html", 'r',encoding='UTF-8')
            #读html然后用正则替换
            content = f.read()
            ##
            newest_sfc,newest_advance_sfc=self.report_latest()
            content=re.sub(r"sfc_report",newest_sfc,content)
            content=re.sub(r"advance_sfcreport",newest_advance_sfc,content)
            self.wfile.write(content.encode())
        else:
            if self.path.endswith('.svg'):
                try:
                    with open(self.path[1:], 'rb') as f:
                        self.send_response(200)
                        self.send_header('Content-type', 'image/svg+xml')
                        self.end_headers()
                        self.wfile.write(f.read())
                except FileNotFoundError:
                    self.send_response(404)
                    self.end_headers()
                    self.wfile.write(b'File not found')
            elif self.path.endswith('.html'):
                try:
                    with open(self.path[1:], 'rb') as f:
                        self.send_response(200)
                        self.send_header('Content-type', 'text/html')
                        self.end_headers()
                        self.wfile.write(f.read())
                except FileNotFoundError:
                    self.send_response(404)
                    self.end_headers()
                    self.wfile.write(b'File not found')
            # 把所有得siderbar 定位到根目录
            # elif self.path.endswith('_siderbar.md'):
            #     pass
            else:
                current=base_path+ self.path
                print(f"base_path:{base_path}当前路径{current}")
                if os.path.isdir(current):
                    print("文件夹")
                    self.send_response(200)
                    self.end_headers()

                    content ="<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><title>Directory listing</title></head>"+'</body>'+self.get_directory("."+self.path) + '</body>'+"</html>"
                    # 里面需要传入二进制数据,用encode()函数转换为二进制数据
                    #写到wfile这个对象才能变成网页展示
                    self.wfile.write(content.encode())
                    # self.get_directory("."+self.path)
                else:
                    try:
                        path = urllib.parse.unquote(self.path[1:])
                        f = open(path, 'rb')
                        self.send_response(200)
                        self.end_headers()
                        self.wfile.write(f.read())
                    except FileNotFoundError:
                        self.send_response(404)
                        self.end_headers()
                        self.wfile.write(b'<h1>File Not Found</h1>')


    def parse_query(self):
        self.queryString = urllib.parse.unquote(self.path.split('?', 1)[1])
        self.queries = urllib.parse.parse_qs(self.queryString)
        print(self.queries)
    def report_latest(self):
        # 获取当前文件夹下的所有文件
        # files=glob.glob("*")
        files = os.listdir("./report")
        print("listfile",files)
        # 获取文件的修改时间
        # sfc报告
        file_times = [(f, os.path.getmtime(os.path.join("report/",f))) for f in files if f.startswith("sfc")]
        # 根据修改时间排序文件
        file_times.sort(key=lambda x: x[1])
        # 获取最新的文件
        newest_sfc = file_times[-1][0]
        # advance_sfc报告
        file_times = [(f, os.path.getmtime(os.path.join("report/",f))) for f in files if f.startswith("advan")]
        # 根据修改时间排序文件
        file_times.sort(key=lambda x: x[1])
        # 获取最新的文件
        newest_advance_sfc = file_times[-1][0]
        print("The newest file in the current directory is:", newest_sfc,newest_advance_sfc)
        return (newest_sfc,newest_advance_sfc)

    def get_directory(self, path) -> str:
        if path==".":
            path="/"
        try:
            list = os.listdir(path)
        except OSError:
            self.send_error(
                HTTPStatus.NOT_FOUND,
                "No permission to list directory")
            return None
        list.sort(key=lambda a: a.lower())
        r = []
        displaypath = os.path.abspath(path)
        title = 'Directory listing for %s' % displaypath
        r.append('<h1>%s</h1>' % title)

        for name in list:
            fullname = os.path.join(path, name).replace("\\",'/')
            print("完整路径:",fullname)
            displayname = linkname = name
            # Append / for directories or @ for symbolic links
            if os.path.isdir(fullname):

                displayname = name +"/"
                linkname = fullname +"/"
                print("文件夹",linkname)
            if os.path.isfile(fullname):
                linkname = fullname

                displayname = name
                print("单文件",linkname)
                # Note: a link to a directory displays with @ and links with /
            r.append('<li><a href="%s">%s</a></li>' % (linkname, displayname))
        # print(''.join(r))
        return ''.join(r)


if __name__ == '__main__':


    server = HTTPServer(host, Resquest)
    print("Starting server, listen at: %s:%s" % host)
    server.serve_forever()

python httpsever 如何实现多并发

要在Python中实现多并发的HTTP服务器,您可以使用http.server模块的ThreadingHTTPServersocketserver.ThreadingMixIn。这将允许服务器在多个线程中处理并发请求。

下面是一个简单的示例代码,演示了如何使用ThreadingHTTPServer创建一个多线程的HTTP服务器:

from http.server import ThreadingHTTPServer, BaseHTTPRequestHandler

class MyHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        self.wfile.write(b"Hello, world")

if __name__ == '__main__':
    server_address = ('', 8000)
    httpd = ThreadingHTTPServer(server_address, MyHandler)
    print('Starting server, listen at: %s:%s' % server_address)
    httpd.serve_forever()

在这个示例中,我们使用ThreadingHTTPServer创建了一个多线程的HTTP服务器,并指定了处理请求的处理程序MyHandler。这样,服务器就能够在多个线程中处理并发请求了。

请注意,尽管多线程可以提高服务器的并发处理能力,但也需要注意线程安全性和资源竞争的问题。确保您的处理程序是线程安全的,并且适当地处理共享资源和状态。

希望这可以帮助您实现多并发的HTTP服务器。如果您有其他问题或需要进一步的帮助,请随时告诉我。

标签:http,python,self,send,server,print,path,多线程,sfc
From: https://www.cnblogs.com/codedingzhen/p/17910838.html

相关文章

  • python动态规划求解最长回文子串
    回文是什么,回文是正着读和反着读都是一样的字符叫着回文。 如‘aba’,‘aa’,‘b’,这些都是回文classSolution:deflongestPalindrome(self,s:str)->str:n=len(s)dp=[[False]*nfor_inrange(n)]ans=""forlinrange(n):......
  • python递归求解青蛙跳台阶问题
    一只青蛙一次可以跳上1级台阶,也可以跳上2级。请问该青蛙跳上一个n级的台阶总共有多少种跳法。输入台阶数,输出一共有多少种跳法。defjump1(n):ifn==1:return1elifn==2:return2else:returnjump1(n-1)+jump1(n-2)x=eval(input())pr......
  • python回溯求解电话号码组合
    给定一个仅包含数字2-9的字符串,返回所有它能表示的字母组合。答案可以按任意顺序返回。给出数字到字母的映射如下(与电话按键相同)。注意1不对应任何字母。输入:digits="23"输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]示例2:......
  • python回溯法n皇后问题
    classSolution:defsolveNQueens(self,n:int):defgenerateBoard():board=list()foriinrange(n):row[queens[i]]="Q"board.append("".join(row))......
  • Wasserstein距离的python代码实现scipy.stats.wasserstein_distance解释
    在官方文档scipy.stats.wasserstein_distance—SciPyv1.8.0.dev0+1869.838cfbeManual(osgeo.cn)页面中scipy.stats.wasserstein_distance(u_values,v_values,u_weights=None,v_weights=None)对参数u_values,v_value,u_weights,v_weights解释不清晰。通过看文章Wassers......
  • maturin 方便发布基于rust 的python 包工具
    maturin是PyO3团队开发的,方便我们开发基于rust的python包,比如PyO3的使用文档中就使用了此工具安装&使用安装(可选,可以基于venv安装)可以基于pip以及pipx pipxinstallmaturin创建一个简单项目python-mvenv.venvsource.venv......
  • 【python】浏览器自动化Selenium安装WebDriver最新Chrome驱动
    selenium 是浏览器自动化测试框架,原本被用于网页测试。但到了爬虫领域,它又成为了爬虫的好帮手。selenium 可以控制你的浏览器,模仿人浏览网页,从而获取数据,自动操作等。首先打开 Chrome浏览器,依次点击浏览器右上角的 三个点 - 帮助 - 关于GoogleChrome查看浏览器版本信......
  • Python定位错误:段错误 (核心已转储)
    技术背景在各种编程语言中都有可能会遇到这样一个报错:“段错误(核心已转储)”。显然是编写代码的过程中有哪里出现了问题,但是这个报错除了这几个字以外没有任何的信息,我们甚至不知道是哪一行的代码出现了这个问题。解决方案在python中可以引用一个faulthandler的函数,就可以显......
  • 多线程+信号量同步线程
    实现场景:多线程+信号量实现线程同步执行线程在创建的时候并不能保证优先顺序,是异步的,如果想按照自己指定的顺序先后执行的话,可以使用一些互斥或者同步的方式;以下我是通过信号量来实现同步:信号量的类型是sem_t,需要的头文件是 #include<semaphore.h>,主要是方法是sem_init......
  • python的orjson
    简介首先我们先来了解下orjson的优缺点:可以将datetime、date和time实例序列化为RFC3339格式,例如:"2022-06-12T00:00:00+00:00"序列化numpy.ndarray实例的速度比其他库快4-12倍,但使用的内存更少,约为其他库的1/3左右输出速度是标准库的10到20倍序列化的结果是bytes类型,而不是......