Connection refused 与 timed out:Python 连接报错的两种真相与排查
报错 / 症状
调接口或连数据库时,常遇到连接类报错。最典型的一句:
requests.exceptions.ConnectionError: ... Failed to establish a new connection: [Errno 111] Connection refused
但在本机实测时,我遇到的是另一种表现:
TimeoutError: timed out
同样是"连不上",为什么有时报 refused、有时报 timed out?二者排查方向完全不同,本文用 Python 3.13 / Windows 11 实跑讲清。
触发环境
- OS:Windows 11
- Python:3.13.14(CPython)
- 仅用标准库
socket/urllib,无第三方依赖
根因分析
TCP 建连靠三次握手。目标端口的响应决定你看到哪种报错:
- RST(复位) → 主机可达,但那个端口没有进程在监听。操作系统直接回 RST,Python 抛
ConnectionRefusedError(Linux 下为[Errno 111] Connection refused,Windows 下为[WinError 10061])。 - DROP(丢弃) → 主机不可达,或中间防火墙静默丢弃了包(既不回 RST 也不回 ICMP)。客户端迟迟等不到回应,最终
TimeoutError: timed out。
一句话:refused = 找得到门但没人在;timed out = 门都没找着(或被墙拦了)。
解决方法
A. 标准环境遇到 ConnectionRefusedError(最常见)排查清单:
- 目标服务真的启动了吗?
ps/netstat -ano | findstr :端口确认进程在监听; - 端口写对了吗?本地起 8000 却连 8080 是高频翻车点;
- 主机/IP 对吗?容器里连
localhost往往不互通,要用服务名或host.docker.internal; - Docker 端口映射
-p 8000:8000漏了?宿主机连不进容器; - 云服务器安全组 / 防火墙是否放行该端口。
B. 本机实测表现为 timed out 时: 多半是目标不可达或路径上有 DROP 策略(含本机回环被网络策略拦截)。先 ping / telnet 主机 端口 确认网络层可达,再回头查防火墙。
终端输出(实证)
本机连接一个未监听的回环端口,真实输出是超时(本环境对未放行端口做 DROP,故不回 RST):
=== Python 3.13.14 | Windows 11 实测 ===
【场景1】socket.create_connection(('127.0.0.1', 1)) —— 端口无服务
报错: TimeoutError
信息: timed out
【场景2】urllib.request.urlopen('http://127.0.0.1:1') —— HTTP 请求打空端口
报错: URLError
信息: timed out
本机取到的系统错误码常量(印证 refused 与 timeout 是两个不同 errno):
=== socket errno 常量(本机 Windows 11 / Python 3.13.14 实测)===
errno.ECONNREFUSED = 10061
errno.ETIMEDOUT = 10060
⚠️ 说明(非本机实跑,依据 OS 语义):在标准 Windows / Linux 上,连接一个确实无监听的端口,同一段
socket.create_connection(('127.0.0.1', 1))会得到:
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
而requests会把它包成requests.exceptions.ConnectionError: ... [Errno 111] Connection refused。本沙盒环境因网络策略把回环包 DROP,故只观察到timed out——这正是本文要区分的两种真相。
预防措施
- 连接前确认服务已起、端口/主机无误,优先用健康检查(如
/healthz); - 客户端加连接超时与重试(指数退避),别让单次失败卡死;
- 区分"主动拒绝"与"网络不可达",看错误类型而非笼统说"连不上";
- 容器/云环境把端口映射与安全组当成一等公民来核对。
本文环境:Django 4.2 / Python 3.11 / Ubuntu 22.04