1

我希望我的代码能够接收 SNMP 警报。我正在使用pysnmppython模块。我正在为陷阱侦听器创建一个新进程。我正在使用multiprocessing模块。陷阱侦听器接收 snmp 警报消息并将其发送到我的主进程,该进程将对它们进行一些计算。但是如何将该消息数据传递给我的父进程?我想创建一个队列。但由于函数正在接收 snmp 数据,cbFun()我不知道如何将其传递给trapReceiver(). 一个简单的返回函数是行不通的。

我想我可以让队列成为一个全局变量。这是一个好主意吗?

我的另一种选择是在我的主进程中写入文件cbFun并从中读取。

解决这个问题的最佳方法是什么?

当我执行下面给出的代码时,子进程正在打印接收到的 snmp 消息,但我无法从父进程打印它。我究竟做错了什么?

from pysnmp.entity import engine, config
from pysnmp.carrier.asynsock.dgram import udp, udp6
from pysnmp.entity.rfc3413 import ntfrcv
from multiprocessing import Process
import Queue

q = Queue.Queue()

def trapListener():
    # Create SNMP engine with autogenernated engineID and pre-bound
    # to socket transport dispatcher

    snmpEngine = engine.SnmpEngine()

    # Transport setup

    # UDP over IPv4
    config.addSocketTransport(
        snmpEngine,
        udp.domainName,
        udp.UdpTransport().openServerMode(('10.94.175.171', 162))
    )

    # SNMPv1/2c setup

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


    # Register SNMP Application at the SNMP engine
    ntfrcv.NotificationReceiver(snmpEngine, cbFun)

    snmpEngine.transportDispatcher.jobStarted(1) # this job would never finish

    # Run I/O dispatcher which would receive queries and send confirmations
    try:
        snmpEngine.transportDispatcher.runDispatcher()
    except:
        snmpEngine.transportDispatcher.closeDispatcher()
        raise
# Callback function for receiving notifications

def cbFun(snmpEngine,stateReference,
              contextEngineId, contextName,
              varBinds,
              cbCtx):
    (transportDomain, transportAddress ) = snmpEngine.msgAndPduDsp.getTransportInfo(stateReference)

    f=open('eventDescriptions.txt','r')
    print('Notification from %s, ContextEngineId "%s", ContextName "%s"' % (
                transportAddress, contextEngineId.prettyPrint(),
                contextName.prettyPrint()))

    for name, val in varBinds:
        if name.prettyPrint()=="1.3.6.1.4.1.674.10892.5.3.1.2.0":
            print('child: %s' % (val.prettyPrint()))
            q.put(val.prettyPrint())

if __name__=="__main__":
    p=Process(target=trapListener, args=(child_conn,))
    p.start()
    print "parent: ", q.get()
    p.join()
4

2 回答 2

1

您可以尝试使用闭包将 Queue 对象传递给 cbFun。像这样的东西:

def getCbFun(queue): # closure
    def cbFun(snmpEngine,stateReference,
          contextEngineId, contextName,
          varBinds,
          cbCtx):
        ...
        queue.add(varBinds)
        ...
    return cbFun

...

# Shared queue object
queue = Queue()

# Register SNMP Application at the SNMP engine
ntfrcv.NotificationReceiver(snmpEngine, getCbFun(queue))

...

因此,如果 cbFun() 将使用来自非全局 getCbFun() 本地范围的队列对象的想法。

于 2014-02-28T05:58:18.497 回答
0

我不确定,但也许使用 subprocess 模块会更简单。您可以使用 subprocess.Popen 创建一个新进程,然后使用通信方法将数据发送到该进程。

于 2014-02-27T11:44:03.770 回答