pysnmp v1arch.asyncio SnmpDispatcher无超时错误且代码卡住求助
解决pysnmp v1arch.asyncio get_cmd超时无响应问题
问题原因
pysnmp v1arch的异步API默认未内置超时终止机制,当目标代理无效或不存在时,get_cmd会持续等待响应,导致代码卡住;而pysnmp v3arch的SnmpEngine自带超时处理逻辑,会正常抛出「No SNMP response received before timeout」错误。
解决方案一:用asyncio.wait_for添加通用超时控制
通过asyncio.wait_for为get_cmd调用设置超时阈值,超过时间未收到响应则主动抛出超时异常,避免代码无限等待。
修改后的代码
import asyncio from pysnmp.hlapi.v1arch.asyncio import * async def run(): try: # 设置5秒超时,可根据业务需求调整时长 errorIndication, errorStatus, errorIndex, varBinds = await asyncio.wait_for( get_cmd( SnmpDispatcher(), CommunityData("public"), await UdpTransportTarget.create(("172.80.23.23", 161)), ObjectType(ObjectIdentity("SNMPv2-MIB", "sysDescr", 0)), ), timeout=5 ) print(errorIndication, errorStatus, errorIndex, varBinds) except asyncio.TimeoutError: print("No SNMP response received before timeout") asyncio.run(run())
解决方案二:配置SnmpDispatcher底层超时参数
通过SnmpDispatcher的API设置协议层面的超时和重试规则,更贴合SNMP的通信逻辑,同时需注意使用后关闭Dispatcher释放资源。
修改后的代码
import asyncio from pysnmp.hlapi.v1arch.asyncio import * from pysnmp.carrier.asyncio.dispatch import AsyncioDispatcher async def run(): # 初始化Dispatcher并配置超时、重试参数 dispatcher = AsyncioDispatcher() # 设置单次请求超时(单位:秒) dispatcher.setTransportDispatcherTimeout(5) # 设置重试次数(0表示不重试) dispatcher.setTransportDispatcherRetries(0) try: errorIndication, errorStatus, errorIndex, varBinds = await get_cmd( dispatcher, CommunityData("public"), await UdpTransportTarget.create(("172.80.23.23", 161)), ObjectType(ObjectIdentity("SNMPv2-MIB", "sysDescr", 0)), ) print(errorIndication, errorStatus, errorIndex, varBinds) except Exception as e: print(f"Error: {e}") finally: # 关闭Dispatcher释放网络资源 dispatcher.closeDispatcher() asyncio.run(run())
两种方案对比
- 方案一:通用异步超时控制,实现简单,快速解决代码卡住问题。
- 方案二:SNMP协议层面的精细控制,可自定义重试次数,适合对SNMP通信有更严格要求的场景。
内容的提问来源于stack exchange,提问作者Eagleto
相关产品推荐
相关产品推荐

