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等。