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

如何解决Windows下Python代码的WinError 10048套接字错误?

Windows下Python网络请求WinError 10048问题解决

问题背景

Ubuntu上运行正常的Python网络请求代码,迁移到Windows后反复抛出错误:OSError: [WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted。

已尝试的方法

  • 常规requests.post写法:
    response = requests.post(url_get, headers=headers, json=data)
    
  • Stream模式requests.post写法:
    with requests.post(url_get, headers=headers, json=data, stream=True) as r:
        response = r
    
  • 使用http.client.HTTPSConnection:
    http.client.HTTPSConnection(url)
    
  • 带timeout参数的HTTPSConnection写法:
    http.client.HTTPSConnection(url, timeout=10)
    
  • 配置重试适配器:
    session = requests.Session()
    retry = Retry(connect=8, backoff_factor=2)
    adapter = HTTPAdapter(max_retries=retry)
    session.mount('https://', adapter)
    

解决方案

Windows对套接字地址复用的限制比Linux严格,默认TIME_WAIT状态的端口不会快速释放,短时间大量请求会耗尽可用端口。以下是无需sleep、额外timeout或过度重试的解决方法:

自定义套接字适配器实现地址复用

通过修改requests的底层连接池,强制开启套接字地址复用选项,同时优化连接管理:

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
import socket
from urllib3.connection import HTTPConnection
from urllib3.connectionpool import HTTPConnectionPool

class ReusableHTTPConnection(HTTPConnection):
    def connect(self):
        super().connect()
        # 开启地址复用,允许重用TIME_WAIT状态的端口
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        try:
            # 尝试开启端口复用(部分Windows环境支持)
            self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
        except AttributeError:
            pass

class ReusableHTTPConnectionPool(HTTPConnectionPool):
    ConnectionCls = ReusableHTTPConnection

class ReusableHTTPAdapter(HTTPAdapter):
    def init_poolmanager(self, connections, maxsize, block=False, **pool_kwargs):
        self.poolmanager = requests.packages.urllib3.poolmanager.PoolManager(
            num_pools=connections,
            maxsize=maxsize,
            block=block,
            connection_pool_class=ReusableHTTPConnectionPool,
            **pool_kwargs
        )

# 初始化session并挂载适配器
session = requests.Session()
# 配置合理的重试策略(避免过度重试)
retry = Retry(
    connect=3,
    read=2,
    backoff_factor=1,
    allowed_methods=["POST"]
)
adapter = ReusableHTTPAdapter(max_retries=retry)
session.mount('https://', adapter)
session.mount('http://', adapter)

# 使用session发起请求
response = session.post(url_get, headers=headers, json=data)

额外优化建议

  • 调整连接池maxsize参数:根据请求频率设置合理值(如10-20),避免短时间创建过多连接
  • 确保请求完成后正确释放资源:使用session.close()或上下文管理器with requests.Session() as session:管理session生命周期

内容的提问来源于stack exchange,提问作者anon.for

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 08:32:38