0

我想检查树系统的状态,我正在使用以下代码,但是我遇到了超时问题,例如,当其中一个系统关闭而不是下一个系统时,我也会超时。

try:
    snmp = pySNMPCom( ip="192.168.0.1", 23434, 30 )
    """It's hangig 30 seconds that is the timeout"""            
    data = snmp.emite_command( command )
    snmp.destroye()                
except:  
    """Smtp timeout"""
    snmp.destroye()  

try:
    snmp = pySNMPCom( ip="192.168.0.2", 23434, 30 )
    """It's going to the exception immediately, it suppose to hung 30 seconds...""" 
    data = snmp.emite_command( command )
    snmp.destroye()                
except:  
    """Smtp timeout"""
    snmp.destroye()  

班上:

# -*- coding: utf-8 -*-
from pysnmp.carrier.asynsock.dispatch import AsynsockDispatcher
from pysnmp.carrier.asynsock.dgram import udp
from pyasn1.codec.ber import encoder, decoder
from pysnmp.proto import api
from time import time


class pySNMPCom():

    def __init__( self, ip, port, timeout ):
        self.__host = ip
        self.__port = port
        self.__timeout = timeout

    def set_cmd( self, cmd ):
        self.cmd = cmd

    def __set_message( self ):
        self.__pMod = api.protoModules[api.protoVersion1]

        self.__reqPDU = self.__pMod.GetRequestPDU()
        self.__pMod.apiPDU.setDefaults( self.__reqPDU )
        self.__pMod.apiPDU.setVarBinds( 
            self.__reqPDU, ( ( self.cmd, self.__pMod.Null( '' ) ),
                )
            )
        # Build message
        self.__reqMsg = self.__pMod.Message()
        self.__pMod.apiMessage.setDefaults( self.__reqMsg )
        self.__pMod.apiMessage.setCommunity( self.__reqMsg, 'public' )
        self.__pMod.apiMessage.setPDU( self.__reqMsg, self.__reqPDU )

    def __cbTimerFun( self, timeNow, startedAt = time() ):
        if timeNow - startedAt > self.__timeout:
            raise "Request timed out"

    def __cbRecvFun( self, transportDispatcher, transportDomain, transportAddress, wholeMsg, reqPDU = '' ):
        if not reqPDU:
            reqPDU = self.__reqPDU
        self.ret = ''
        while wholeMsg:
            rspMsg, wholeMsg = decoder.decode( wholeMsg, asn1Spec = self.__pMod.Message() )
            rspPDU = self.__pMod.apiMessage.getPDU( rspMsg )
            # Match response to request
            if self.__pMod.apiPDU.getRequestID( reqPDU ) == self.__pMod.apiPDU.getRequestID( rspPDU ):
                # Check for SNMP errors reported
                errorStatus = self.__pMod.apiPDU.getErrorStatus( rspPDU )
                if errorStatus:
                    print errorStatus.prettyPrint()
                else:
                    for oid, val in self.__pMod.apiPDU.getVarBinds( rspPDU ):                        
                        self.ret = val

                transportDispatcher.jobFinished( 1 )

    def emite_command( self, cmd = '' ):
        if not cmd:
            cmd = self.cmd
        self.set_cmd( cmd )
        self.__set_message()        

        transportDispatcher = AsynsockDispatcher()
        transportDispatcher.registerTransport( 
            udp.domainName, udp.UdpSocketTransport().openClientMode()
            )
        transportDispatcher.registerRecvCbFun( self.__cbRecvFun )
        transportDispatcher.registerTimerCbFun( self.__cbTimerFun )
        transportDispatcher.sendMessage( 
            encoder.encode( self.__reqMsg ), udp.domainName, ( self.__host, self.__port )
            )
        transportDispatcher.jobStarted( 1 )
        transportDispatcher.runDispatcher()
        transportDispatcher.closeDispatcher()

        return self.ret

    def destroye( self ):
        del self      
4

1 回答 1

1

您将 startedAt 变量初始化为默认方法参数。这只会在模块运行时发生一次,并且不会在类重新实例化时重复。因此,您的所有查询时间都是根据初始的 staredAt 值来衡量的。因此,在startedAt + 30 之后发生的所有查询都将立即超时。

于 2012-07-17T21:10:44.230 回答