You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Socket实现HTTP服务器时浏览器连接报错问题求助

Socket实现HTTP服务器报错WinError10053的解决办法

问题情况

用Socket手写HTTP服务器,之前运行正常,现在浏览器连接时触发如下错误,尝试删除部分代码、调整time.sleep()无效:

Traceback (most recent call last):
File "C:/Users/Михаил Балошко/Downloads/dz/test_ekrana.py", line 16, in 
conn.sendall('Server : pythonsite/0.0.1 \n'.encode('UTF-8'))
ConnectionAbortedError: [WinError 10053] 你的主机中的软件中止了一个已建立的连接

原代码

import socket
import time

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

s.bind(('127.0.0.1', 5000)) 
s.listen(9000) 
conn, addr = s.accept() 

data = conn.recv(1024) 
print(f'Received: \n {data.decode()}')
time.sleep(10)
conn.sendall('HTTP/1.1 201 Created \n'.encode('UTF-8'))
time.sleep(2)
conn.sendall('Server : pythonsite/0.0.1 \n'.encode('UTF-8'))
conn.sendall('Date: \n'.encode('UTF-8'))
conn.sendall('Content-Type: application/octet-stream \n'.encode('UTF-8'))
conn.sendall('Content-Length: 7 \n'.encode('UTF-8'))
conn.sendall('Last-Modified: \n'.encode('UTF-8'))
conn.sendall('Connection: keep-alive \n'.encode('UTF-8'))
conn.sendall('Accept-Ranges: bytes \n'.encode('UTF-8'))
conn.sendall('\n'.encode('UTF-8'))
conn.sendall('\n'.encode('UTF-8'))
conn.sendall('<html>\n'.encode('UTF-8'))
conn.sendall('<head>\n'.encode('UTF-8'))
conn.sendall('<title>pythonserv!</title>\n'.encode('UTF-8'))
conn.sendall('</head>\n'.encode('UTF-8'))
conn.sendall('<body>\n'.encode('UTF-8'))
conn.sendall('<p>this is python web!!!</p>\n'.encode('UTF-8'))
conn.sendall('</body>\n'.encode('UTF-8'))
conn.sendall('</html>\n'.encode('UTF-8'))
time.sleep(3)
data = conn.recv(1024)
time.sleep(8)
print(f'Received: \n {data.decode()}')
    
conn.close()

问题根源

  1. 浏览器超时断开:接收请求后time.sleep(10)让服务器停顿10秒才发响应,浏览器默认等待响应的超时时间远短于10秒,会主动断开连接,导致后续发送数据时触发连接中止错误。
  2. HTTP响应格式不规范:
    • 状态码用了201 Created,但这里是返回网页内容,应该用200 OK;
    • Content-Type设为application/octet-stream,但实际返回HTML,应该用text/html;
    • Content-Length写的7,和实际HTML内容字节数严重不符;
    • HTTP协议要求响应头每行结尾用\r\n(CRLF),而不是\n,响应头和正文之间只需要一个空行(\r\n\r\n);
  3. 多余的recv操作:发送完响应后还尝试接收数据,此时浏览器可能已经关闭连接,会导致异常。

修复后的代码

import socket

def main():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('127.0.0.1', 5000))
    s.listen(5)  # 监听队列设为合理值即可,不用9000
    
    print("服务器启动,等待连接...")
    conn, addr = s.accept()
    print(f"来自 {addr} 的连接")
    
    # 接收请求数据
    data = conn.recv(1024)
    print(f'Received: \n {data.decode()}')
    
    # 构造HTML正文
    html_content = """<html>
<head>
<title>pythonserv!</title>
</head>
<body>
<p>this is python web!!!</p>
</body>
</html>"""
    
    # 计算正文字节长度(UTF-8编码)
    content_length = len(html_content.encode('utf-8'))
    
    # 构造符合HTTP规范的响应头
    response_headers = (
        f"HTTP/1.1 200 OK\r\n"
        f"Server: pythonsite/0.0.1\r\n"
        f"Content-Type: text/html; charset=utf-8\r\n"
        f"Content-Length: {content_length}\r\n"
        f"Connection: close\r\n"  # 告诉浏览器发送完响应后关闭连接
        f"\r\n"  # 响应头结束标记
    )
    
    # 发送响应头+正文
    conn.sendall(response_headers.encode('utf-8'))
    conn.sendall(html_content.encode('utf-8'))
    
    # 关闭连接
    conn.close()
    s.close()

if __name__ == "__main__":
    main()

修复说明

  • 移除了所有不必要的time.sleep(),避免浏览器超时;
  • 修正了HTTP状态码、Content-Type、Content-Length等响应头;
  • 严格按照HTTP协议用\r\n分隔响应头,用\r\n\r\n分隔响应头和正文;
  • 设置Connection: close,明确告知浏览器响应完成后关闭连接,避免后续不必要的接收操作;
  • 把代码整理成函数结构,更清晰易维护。

内容的提问来源于stack exchange,提问作者mihail989

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 14:20:23