aiohttp触发OSError: [WinError 10022]错误,请求数次后循环报错求助
环境信息
- Aiohttp版本:最新版
- Python版本:最新版
- 系统:Windows Server 2019 Datacenter x64
问题描述
发送5-10次请求后触发错误,程序陷入报错循环,需要修复该问题。
代码示例
import aiohttp import asyncio async def test(): async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False)) as idk: while True: async with idk.get(f"mywebsite.com/endpoint") as gg: if gg.status == 404: exit() else: print(f" {gg.status} error.") loop = asyncio.get_event_loop() loop.run_until_complete(test())
错误日志
_ProactorBasePipeTransport._call_connection_lost(SSLError(1, '..._ssl.c:2685)'))
handle: <Handle _ProactorBasePipeTransport._call_connection_lost(SSLError(1, '..._ssl.c:2685)'))>
回溯(最近的调用最后):
文件 "C:\Users\nomik\AppData\Local\Programs\Python\Python312\Lib\asyncio\events.py", 第84行, 在 _run中
self._context.run(self._callback, *self._args)
文件 "C:\Users\nomik\AppData\Local\Programs\Python\Python312\Lib\asyncio\proactor_events.py", 第165行, 在 _call_connection_lost中
self._sock.shutdown(socket.SHUT_RDWR)
OSError: [WinError 10022] 参数无效
回溯(最近的调用最后):
文件 "C:\Users\nomik\Desktop\x.py", 第52行, 在中
loop.run_until_complete(check_vanity())
文件 "C:\Users\nomik\AppData\Local\Programs\Python\Python312\Lib\asyncio\base_events.py", 第671行, 在 run_until_complete中
self.run_forever()
文件 "C:\Users\nomik\AppData\Local\Programs\Python\Python312\Lib\asyncio\windows_events.py", 第321行, 在 run_forever中
super().run_forever()
文件 "C:\Users\nomik\AppData\Local\Programs\Python\Python312\Lib\asyncio\base_events.py", 第638行, 在 run_forever中
self._run_once()
文件 "C:\Users\nomik\AppData\Local\Programs\Python\Python312\Lib\asyncio\base_events.py", 第1933行, 在 _run_once中
event_list = self._selector.select(timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
文件 "C:\Users\nomik\AppData\Local\Programs\Python\Python312\Lib\asyncio\windows_events.py", 第444行, 在 select中
self._poll(timeout)
文件 "C:\Users\nomik\AppData\Local\Programs\Python\Python312\Lib\asyncio\windows_events.py", 第769行, 在 _poll中
status = _overlapped.GetQueuedCompletionStatus(self._iocp, ms)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
修复方案
这个错误是Windows Proactor事件循环与aiohttp的兼容性问题,高频循环请求时连接关闭的socket操作触发了无效参数错误,可通过以下方式修复:
1. 切换到Selector事件循环
Windows默认的Proactor循环存在场景兼容性问题,强制使用Selector循环可解决该问题:
import asyncio # 放在代码最开头 asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
2. 调整TCP连接池参数
限制连接池大小并启用keep-alive,避免连接复用异常:
connector=aiohttp.TCPConnector( ssl=False, limit=5, # 限制连接池最大数量 keepalive_timeout=30, # 启用TCP长连接 force_close=True # 请求结束后强制关闭连接 )
3. 添加异常捕获与重试逻辑
避免程序直接崩溃,同时添加请求间隔防止高频触发限制:
async def test(): async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False)) as idk: while True: try: # 补充URL协议头(http/https) async with idk.get(f"https://mywebsite.com/endpoint") as gg: if gg.status == 404: return # 用return替代exit(),退出更优雅 else: print(f"请求状态码: {gg.status}") await asyncio.sleep(1) # 添加请求间隔 except Exception as e: print(f"请求出错: {e}") await asyncio.sleep(2) # 出错后延迟重试
4. 修正URL格式
原代码中URL缺少http/https协议头,这会导致aiohttp连接处理异常,务必补充完整。
内容的提问来源于stack exchange,提问作者ylmhs4

