多线程Python静态web服务器

1. 导入必要的模块,如socket、threading、os等。

2. 创建一个HTTP服务器类,继承BaseHTTPServer.BaseHTTPRequestHandler,并实现do_GET()方法来响应GET请求。

3. 在do_GET()方法中,解析请求的路径和参数,获取请求文件的绝对路径。

4. 如果文件不存在,返回404错误;如果文件存在且可读,设置响应头部并把文件内容返回给客户端;否则返回500错误。

5. 在HTTP服务器类中添加一个start()方法,用于启动服务器。

6. 在start()方法中,创建一个监听socket,绑定到指定的端口和IP地址,开始监听客户端连接。

7. 当有客户端连接时,创建一个新的线程来处理该连接,调用HTTP服务器类的handle_request()方法处理请求。

8. 在handle_request()方法中,调用do_GET()来处理GET请求,并发送响应给客户端。

9. 在每个线程中,处理完请求后,关闭连接,并结束线程

import socket

import threading

import os

class HTTPServer(threading.Thread):

    def __init__(self, ip, port, document_root):

        threading.Thread.__init__(self)

        self.ip = ip

        self.port = port

        self.document_root = document_root

    def run(self):

        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)

        server_socket.bind((self.ip, self.port))

        server_socket.listen(5)

        print(f"Listening on {self.ip}:{self.port}")

        while True:

            client_socket, client_address = server_socket.accept()

            print(f"Client connected from {client_address}")

            t = threading.Thread(target=self.handle_request, args=(client_socket,))

            t.start()

    def handle_request(self, client_socket):

        request_data = client_socket.recv(1024)

        request_lines = request_data.split(b"\r\n")

        first_line = request_lines[0].decode("utf-8")

        method, path, protocol = first_line.split()

        # construct file path

        file_path = os.path.join(self.document_root, path.strip("/"))

        if not os.path.isfile(file_path):

            # file not found

            status_line = "HTTP/1.1 404 Not Found\r\n"

            response_body = b"404 Not Found"

        elif not os.access(file_path, os.R_OK):

            # file not readable

            status_line = "HTTP/1.1 500 Internal Server Error\r\n"

            response_body = b"500 Internal Server Error"

        else:

            # read file and send response

            with open(file_path, "rb") as f:

                file_data = f.read()

            status_line = "HTTP/1.1 200 OK\r\n"

            headers = f"Content-Length: {len(file_data)}\r\n\r\n"

            response_body = file_data

        response = f"{status_line}{headers}".encode("utf-8") + response_body

        client_socket.sendall(response)

        client_socket.close()

if __name__ == "__main__":

    server = HTTPServer("localhost", 8080, "/path/to/document/root")

    server.start()

    server.join()

在这个例子中,我们创建了一个HTTPServer类,它继承了threading.Thread类,以便我们可以在单独的线程上运行它。当运行start()方法时,它将创建一个套接字,将其绑定到指定的IP地址和端口,并开始侦听客户端连接。当有新的客户端连接时,它将在一个新的线程中处理连接并发送响应。

handle_request()方法在连接上收到请求时被调用。它首先解析请求并构造出请求的文件路径。如果文件不存在,它将返回一个404错误;如果文件存在但不可读,它将返回一个500错误;否则,它将读取文件内容并将其作为响应发送给客户端。

注意,在这个示中,我们使用了简单的文件路径构造方法,可能存在一些安全漏洞,因此在实际应用中需要进行更严格的路径检查和验证。此外,还需要考虑其他类型的HTTP请求,如POST和PUT等。

猜你喜欢

转载自blog.csdn.net/2201_75480526/article/details/129319115