问题描述
我正在尝试使用aiosnmp / asyncio轮询大量设备。我不确定自己在做什么错。我想将IP子网列表提供给“ loop_over_ips”功能。然后,使用ip地址模块遍历每个IP地址,并将该异步“轮询”功能添加到asyncio.gather池中。
似乎我在这里有两个问题。 第一个问题是我没有得到任何回应。即使此范围内的设备应响应,“ res.value”也将返回为“无”。 第二个问题是,在某个时刻,应用程序会抛出一个运行时错误,提示“无法重用已经等待的协程”。
然后有两个问题,我该如何重写这些功能以避免重复使用等待的协程?我是否正确编写了这些功能,导致没有设备响应?就我的代码而言,它是否正在轮询这些设备?
import asyncio
import aiosnmp
import ipaddress
async def loop_over_ips(ip_addr_list: list) -> asyncio.gather():
tasks = []
for ip_addr in ip_addr_list:
subnet = ipaddress.ip_network(ip_addr)
for ip in subnet:
ip = str(ip)
tasks.append(poll(ip))
await asyncio.gather(*tasks)
async def poll(ip: str):
with aiosnmp.Snmp(host=ip,community="Mycommunity") as snmp:
try:
for res in await snmp.get(".3.6.1.2.1.1.1.0"):
# for res in await snmp.walk():
print(res.oid,res.value)
except Exception:
# print("Device did not respond")
pass
if __name__ == "__main__":
infra_subnets = [
"10.204.88.0/21","10.201.7.0/24","172.30.200.0/23","172.30.210.0/23","10.0.48.0/24","10.1.20.0/24","10.1.30.0/24","10.1.32.0/24","10.19.1.0/24","10.98.1.0/24",]
asyncio.run(loop_over_ips(infra_subnets))
解决方法
aiosnmp 维护者在这里,抱歉我没有注意到您的问题,但无论如何都会回答,请参阅我在下面代码中的评论
import asyncio
import aiosnmp
import ipaddress
async def loop_over_ips(ip_addr_list: list) -> None:
tasks = [] # you should move tasks below first for loop
for ip_addr in ip_addr_list:
subnet = ipaddress.ip_network(ip_addr)
for ip in subnet:
ip = str(ip)
tasks.append(poll(ip))
await asyncio.gather(*tasks) # or move gather outside first loop,it caused RuntimeError
async def poll(ip: str):
async with aiosnmp.Snmp(host=ip,community="Mycommunity") as snmp: # in the recent version it should be async with
try:
for res in await snmp.get(".1.3.6.1.2.1.1.1.0"): # oid should start with .1 or 1,not 3
print(res.oid,res.value)
except Exception:
pass
if __name__ == "__main__":
infra_subnets = [
"10.204.88.0/21","10.201.7.0/24","172.30.200.0/23","172.30.210.0/23","10.0.48.0/24","10.1.20.0/24","10.1.30.0/24","10.1.32.0/24","10.19.1.0/24","10.98.1.0/24",]
asyncio.run(loop_over_ips(infra_subnets))