使用asyncio的sock_connect方法出现连接超时问题求助
问题原因
socks.socksocket是对标准socket的封装,它的connect/connect_ex方法会先建立到代理服务器的连接,再通过代理转发请求到目标地址。而asyncio的sock_connect是直接调用底层socket的系统级connect接口,完全绕过了socks库的代理逻辑——相当于直接尝试连接目标地址,没有走代理,自然会超时。
Windows下的proactor_events实现不影响这个核心问题,不管是selector还是proactor事件循环,sock_connect都不会识别socksocket的代理配置。
解决方案
方案一:用run_in_executor执行同步的socks连接
把socks的同步连接操作放到线程池里执行,既保留代理逻辑,又不阻塞asyncio事件循环:
import asyncio import socks from _socket import AF_INET, SOCK_STREAM async def conn(): parsed = (3, 'localhost', 7890, True, None, None) timeout = 10 address = ('149.154.167.51', 443) sock = socks.socksocket(AF_INET, SOCK_STREAM) sock.set_proxy(*parsed) sock.settimeout(timeout) # 使用线程池执行同步的connect_ex loop = asyncio.get_running_loop() status = await loop.run_in_executor( None, # 使用默认线程池 sock.connect_ex, address ) print('connect status: ', status) # 后续可将socket包装成asyncio流进行读写 reader, writer = await asyncio.open_connection(sock=sock) # 这里可继续处理读写操作,比如发送HTTPS请求等 if __name__ == '__main__': asyncio.run(conn())
方案二:改用异步代理库
如果项目允许,直接使用支持异步的代理库,比如aiohttp_socks,它原生适配asyncio,无需手动处理socket:
import asyncio from aiohttp_socks import ProxyConnector, ClientSession async def conn(): connector = ProxyConnector.from_url('socks5://localhost:7890') async with ClientSession(connector=connector) as session: async with session.get('https://149.154.167.51') as response: print(response.status) if __name__ == '__main__': asyncio.run(conn())
注意事项
- 不要混用
socks的同步socket和asyncio的sock_connect,两者逻辑不兼容 - 若必须使用
socks库,一定要用run_in_executor把同步操作异步化,避免阻塞事件循环
内容的提问来源于stack exchange,提问作者yanlin Zhu
相关产品推荐
相关产品推荐

