如何配置Python标准HTTPServer以支持HTTP持久连接?
解决Python HTTPServer支持持久连接(Keep-Alive)的问题
你的问题根源很明确:你自定义的请求处理器里,do_GET和do_POST方法没有正确发送Keep-Alive相关的响应头,导致客户端的requests.Session无法维持持久连接,每次请求后都会触发连接重置。
你已经写了_set_response方法来设置必要的头,但在实际处理GET和POST请求时,并没有调用这个方法,而是直接调用send_response和end_headers,这就跳过了Keep-Alive头的设置。
修改后的服务器代码
from http.server import HTTPServer, BaseHTTPRequestHandler from io import BytesIO import datetime import logging class SimpleHTTPRequestHandler(BaseHTTPRequestHandler): def _set_response(self): self.send_response(200) self.send_header('Content-type', 'application/json') # 建议改成JSON类型,匹配你返回的响应格式 self.send_header("Connection", "keep-alive") self.send_header("Keep-Alive", "timeout=5, max=30") # 规范写法用大写开头的头名称 self.end_headers() def do_GET(self): self._set_response() # 调用统一的响应头设置方法 self.wfile.write(b'Hello, world!') def do_POST(self): content_length = int(self.headers['Content-Length']) body = self.rfile.read(content_length) curr_time = datetime.datetime.now() data = ('{"msgid":"0x0002", "timestamp": "'+ str(curr_time) +'", "message":"Test http response from Raspberry Pi HTTP server"}').encode() self._set_response() # 替换手动设置响应头的逻辑 response = BytesIO() response.write(data) self.wfile.write(response.getvalue()) print("Simple HTTP Server running...") logging.basicConfig(level=logging.DEBUG) httpd = HTTPServer(('', 8000), SimpleHTTPRequestHandler) httpd.serve_forever()
关键修改点说明
- 在
do_GET和do_POST中,替换掉手动的send_response和end_headers,改为调用你已经写好的_set_response方法,确保每次响应都携带Connection: keep-alive和Keep-Alive参数头。 - 将
Content-type改为application/json更合理,因为你返回的是JSON格式数据,能让客户端更准确地解析响应。 - 调整
Keep-Alive头的名称为规范的大写开头写法,虽然HTTP头不区分大小写,但规范写法能避免潜在的兼容性问题。
为什么这样能解决问题?
当服务器返回Connection: keep-alive头时,requests.Session会识别到这个连接可以复用,不会在每次请求后主动关闭连接。而之前的代码没有发送这个头,客户端会默认使用Connection: close,导致每次请求后连接被断开,下次请求需要重新建立,也就出现了你看到的Resetting dropped connection日志。
另外,BaseHTTPRequestHandler本身支持Keep-Alive机制,只要你正确设置响应头,它就会保持连接打开,等待客户端的下一个请求,直到超时或者达到max指定的请求次数。
测试修改后的代码,你会发现客户端日志里不再出现连接重置的提示,10次POST请求都会复用同一个TCP连接。
内容的提问来源于stack exchange,提问作者user3034017




