【问题标题】:gevent and snmp in pythonpython中的gevent和snmp
【发布时间】:2013-09-28 20:22:18
【问题描述】:

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

此外,由于我将使用 linux 机器,我可以访问 snmpget 命令行实用程序,因此我可以使用 1.0 版中提供的 gevent.subprocess 调用它们,这也可以使这些查询也非阻塞。

与使用命令行实用程序相比,我更喜欢使用 python 模块来执行 snmp get,但是如果第二个选项更容易开始工作,那么我不介意采用这种方法。

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

更新:

我采用了 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
)

【问题讨论】:

    标签: python snmp gevent pysnmp


    【解决方案1】:

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

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

    您通常会在 greenlet 中生成它并忘记它(或者可能对其进行一些有序的关闭)。

    (我会在未来的某个时间向 pysnmp_eventlet 添加适当的示例。)

    【讨论】:

    • 添加一些示例会很棒 - 一旦我在项目中掌握了基础知识,我也可以为您提供帮助。
    • 你的补丁现在合并到pysnmp主干了吗?在 Google 上找不到任何合并版本的文档
    • 恐怕没有,这似乎已经从待办事项列表中掉了下来。不过应该不会太难,只需要腾出时间。
    【解决方案2】:

    pysnmp 有一个补丁可以让它与 eventlet 一起运行:

    https://bitbucket.org/flub/pysnmp_eventlet

    【讨论】:

    • 能否请您总结一下那个链接的内容,以防将来会变成404?
    • 是的,我们在 python 2.7 的生产环境中使用它。对于其他 python 版本,您可能需要等到它被合并到 pysnmp 中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-30
    • 1970-01-01
    • 1970-01-01
    • 2018-07-18
    • 2020-09-10
    • 1970-01-01
    相关资源
    最近更新 更多