繁体   English   中英

python中的gevent和snmp

[英]gevent and snmp in python

我想在python中做一个snmpget而不阻塞。 我不想使用线程,我真的很喜欢gevent库,但是我以前没有使用过它,所以不确定从哪里开始。 我查看了他们的示例,并了解了如何使用猴子补丁插槽。 如果我猴子修补套接字并使用pysnmp这样的模块,执行非阻塞查询就足够了吗?

另外,由于我将在Linux机器上,所以我可以访问snmpget命令行实用程序,因此我可以使用gevent.subprocess来调用它们,该版本在1.0版中可用,这也可以使这些查询成为非阻塞形式。

与使用命令行实用程序相比,我更喜欢使用python模块进行snmp获取,但是,如果第二个选项更易于使用,则我不介意采用这种方法。

任何提示/方向将不胜感激。 谢谢!

更新:

我采用了pysnmp_eventlet模块,并尝试采用带eventlet的Twisted示例。 我不确定为什么我的回调函数没有被调用。 我可以在tcpdump中看到SNMP请求和响应。 但是我的回调函数(cbFun)没有被调用。 我想念什么吗?

from pysnmp_eventlet.carrier.eventlet.dispatch import EventletDispatcher
from pysnmp_eventlet.carrier.eventlet.dgram import udp

from pysnmp.entity.rfc3413 import cmdgen
from pysnmp.entity import engine, config


# Create SNMP engine instance

snmpEngine = engine.SnmpEngine()
dispatcher = EventletDispatcher()
snmpEngine.registerTransportDispatcher(dispatcher)



# SecurityName <-> CommunityName mapping
config.addV1System(snmpEngine, 'my-area', 'public')

# Specify security settings per SecurityName (SNMPv1 - 0, SNMPv2c - 1)
config.addTargetParams(snmpEngine, 'my-creds', 'my-area', 'noAuthNoPriv', 1)


# UDP/IPv4
config.addSocketTransport(
    snmpEngine,
    udp.domainName,
    udp.UdpEventletTransport().openClientMode()
)
config.addTargetAddr(
    snmpEngine,
    'my-router',
    udp.domainName,
    ('127.0.0.1', 161),
    'my-creds',
    timeout=300,  # in 1/100 sec
    retryCount=1
)

def cbFun(cbCtx):
    (errorIndication, errorStatus, errorIndex, varBinds) = cbCtx

    if errorIndication:
        print(errorIndication)
    elif errorStatus:
        print('%s at %s' % (
                errorStatus.prettyPrint(),
                errorIndex and varBinds[int(errorIndex)-1][0] or '?'
            )
        )
    else:
        for oid, val in varBinds:
            print('%s = %s' % (oid.prettyPrint(), val.prettyPrint()))




cmdGen = cmdgen.GetCommandGenerator()
cmdGen.sendReq(
    snmpEngine,
    'my-router',
    ( ('1.3.6.1.2.1.1.1.0', None), ),
    cbFun
)

pysnmp的一个补丁可以使它与eventlet一起运行:

https://bitbucket.org/flub/pysnmp_eventlet

在上面的代码中,您仍然需要运行eventlet的调度程序来处理传入的数据包:

while True:
    eventlet.sleep(dispatcher.getTimerResolution())
    try:
        dispatcher.handleTimerTick(time.time())
    except Exception:
        print 'Error while handling dispatcher tick!'
        raise

通常,您会在一个greenlet中生成它,然后将其忽略(或者可能对其执行一些有序的关闭)。

(我将来会在pysnmp_eventlet中添加适当的示例。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM