如何修复asyncio中出现的Unclosed connection错误?
修复aiohttp未关闭连接错误
相关代码文件
fuzzer.py
import aiohttp import asyncio async def get_page(url=None, extensions=None): with open("wordlist.txt") as file: directories = file.readlines() data = [] async with aiohttp.ClientSession() as session: for directory in directories: response = await session.get(url=f"{url}/{directory}") data.append([f"{url}/{directory}", response.status, response.content_length]) for extension in extensions: response = await session.get(url=f"{url}/{directory}.{extension}") data.append([f"{url}/{directory}.{extension}", response.status, response.content_length]) return data async def main(): await get_page() if __name__ == "__main__": asyncio.run(main())
main.py
from fuzzer import get_page @dp.message_handler() async def fuzzer(message: types.Message, state: FSMContext): await state.update_data(ex=message.text.split(',')) data = await state.get_data() fuzz_data = await get_page(url=data['url'], extensions=data['ex']) cur_time = datetime.datetime.now().strftime('%d_%m_%Y_%H_%M') async with aiofiles.open(f"{data['url'][8:]}_{cur_time}.csv", 'w') as file: writer = AsyncWriter(file) await writer.writerow( [ 'URL', 'Код статуса', 'Длина контента' ] ) await writer.writerows( fuzz_data ) await state.finish()
错误日志
2022-07-18 04:11:47,729 - ERROR - asyncio - Unclosed connection
client_connection: Connection<ConnectionKey(host='google.com', port=443, is_ssl=True, ssl=None, proxy=None, proxy_auth=None, proxy_headers_hash=None)>
修复方案
该错误的核心原因是:获取aiohttp响应后未正确释放响应对象,导致底层连接无法被回收复用。
修改fuzzer.py中的get_page函数,采用async with语法管理每个请求的响应对象,这样代码块结束时会自动关闭响应、释放连接,同时顺便修复readlines()保留换行符导致的URL格式错误:
async def get_page(url=None, extensions=None): with open("wordlist.txt") as file: # 去除每行末尾的换行符,避免URL拼接后包含无效字符 directories = [dir.strip() for dir in file.readlines()] data = [] async with aiohttp.ClientSession() as session: for directory in directories: # 用async with管理响应,自动释放连接 async with session.get(url=f"{url}/{directory}") as response: data.append([f"{url}/{directory}", response.status, response.content_length]) for extension in extensions: async with session.get(url=f"{url}/{directory}.{extension}") as response: data.append([f"{url}/{directory}.{extension}", response.status, response.content_length]) return data
如果不想使用async with,也可以在获取响应后手动调用await response.release()来释放连接,但async with是更简洁、安全的写法。
内容的提问来源于stack exchange,提问作者spot
相关产品推荐
相关产品推荐

