上一篇
http服务器编写
- 行业动态
- 2025-05-01
- 2024
HTTP服务器编写需创建监听套接字,接收请求并解析,生成响应后返回,支持并发
环境准备
- 编程语言: Python(版本3.6+)
- 核心模块:
socket
(网络通信)、threading
(并发处理) - 工具: 浏览器(如Chrome)、
curl
命令行工具
核心功能实现
创建TCP服务器
import socket # 创建套接字对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设置地址复用 server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 绑定IP和端口 server_socket.bind(("0.0.0.0", 8080)) # 监听连接 server_socket.listen(5) print("HTTP服务器已启动,监听端口8080")
处理HTTP请求
while True: # 接受客户端连接 client_socket, addr = server_socket.accept() # 接收请求数据 request = client_socket.recv(1024).decode() print(f"收到请求: {request}") # 解析HTTP请求(简单处理GET方法) if request.startswith("GET"): # 构造HTTP响应 response = "HTTP/1.1 200 OK Content-Type: text/html " response += "<h1>Hello, HTTP Server!</h1>" client_socket.send(response.encode()) # 关闭连接 client_socket.close()
多线程支持(并发处理)
代码改进
from threading import Thread def handle_client(client_socket): request = client_socket.recv(1024).decode() print(f"收到请求: {request}") if request.startswith("GET"): response = "HTTP/1.1 200 OK Content-Type: text/html " response += "<h1>Hello, Multi-threaded HTTP Server!</h1>" client_socket.send(response.encode()) client_socket.close() while True: client_socket, addr = server_socket.accept() # 为每个请求创建新线程 Thread(target=handle_client, args=(client_socket,)).start()
静态文件服务
文件路径解析与响应
import os # 定义静态文件根目录 STATIC_ROOT = "./static" def handle_static_file(request): # 解析请求路径(如:GET /index.html HTTP/1.1) path = request.split(" ")[1] file_path = os.path.join(STATIC_ROOT, path.lstrip("/")) # 检查文件是否存在 if os.path.isfile(file_path): with open(file_path, "rb") as f: content = f.read() # 猜测MIME类型 mime_type = "application/octet-stream" if file_path.endswith(".html"): mime_type = "text/html" elif file_path.endswith(".css"): mime_type = "text/css" elif file_path.endswith(".js"): mime_type = "application/javascript" response = f"HTTP/1.1 200 OK Content-Type: {mime_type} " return response.encode() + content else: # 返回404响应 return b"HTTP/1.1 404 Not Found Content-Type: text/html <h1>404 Not Found</h1>"
MIME类型对照表
文件后缀 | MIME类型 |
---|---|
.html | text/html |
.css | text/css |
.js | application/javascript |
.png | image/png |
.jpg | image/jpeg |
.gif | image/gif |
测试方法
- 启动服务器:运行Python脚本,确保端口8080未被占用。
- 浏览器访问:在地址栏输入
http://localhost:8080
,应显示HTML内容。 - 命令行测试:
curl http://localhost:8080 curl http://localhost:8080/nonexistent.html
常见问题与解决方案
问题 | 解决方案 |
---|---|
浏览器显示空白 | 检查服务器是否监听正确端口,确认响应内容符合HTTP协议格式(包含头部和正文)。 |
静态文件无法加载 | 确保文件路径正确,检查STATIC_ROOT 目录是否存在目标文件,MIME类型是否正确。 |
并发请求导致卡顿 | 使用多线程或异步IO(如asyncio )处理请求,避免单线程阻塞。 |
相关问题与解答
问题1:如何支持POST请求?
解答:
POST请求需要处理请求体(如表单数据),修改请求解析逻辑,读取Content-Length
指定的长度,并提取请求体。
if request.startswith("POST"): content_length = int(request.split(" ")[0].split(" ")[-1]) post_data = client_socket.recv(content_length).decode() # 处理post_data(如解析表单参数)
问题2:如何为服务器添加HTTPS支持?
解答:
需使用ssl
模块包裹套接字,并提供证书文件,示例:
import ssl # 创建SSL上下文 context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) context.load_cert_chain(certfile="server.crt", keyfile="server.key") # 包裹套接字 ssl_socket = context.wrap_socket(server_socket, server_side=True) ssl_socket.listen(5)
需提前生成自签名证书(如使用OpenSSL)。