1

ブロックせずにPythonでsnmpgetを実行したいと思います。私はスレッドを使いたくありません。gevent ライブラリが本当に好きですが、これまで使用したことがないので、どこから始めればよいかわかりません。私は彼らの例を見て、どのようにソケットにパッチを当てることができるかを理解しました。ソケットにパッチを適用して pysnmp のようなモジュールを使用すると、ノンブロッキング クエリを実行するのに十分でしょうか?

また、Linux ボックスをsnmpget使用するので、コマンド ライン ユーティリティにアクセスできるので、バージョン 1.0 で利用可能な gevent.subprocess を使用してそれらを呼び出すことができます。これにより、これらのクエリもノンブロッキングにすることができます。

コマンド ライン ユーティリティを使用するよりも、python モジュールを使用して snmp get を実行することをお勧めします。

ヒント/指示をいただければ幸いです。ありがとう!

アップデート:

私は pysnmp_eventlet モジュールを使用して、イベントレットで Twisted の例を採用しようとしました。コールバック関数が呼び出されない理由がわかりません。SNMP 要求と応答が tcpdump に戻ってくるのを確認できます。ただし、コールバック関数 (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
)
4

2 に答える 2

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 に将来追加する予定です。)

于 2013-10-28T22:33:38.983 に答える
1

eventlet で実行する pysnmp へのパッチがあります。

https://bitbucket.org/flub/pysnmp_eventlet

于 2013-09-30T06:38:49.587 に答える