2012-07-17 3 views
0

트리 시스템의 상태를 확인하고 싶습니다. 다음 코드를 사용하고 있습니다.하지만 시간 초과 문제가 있습니다. 예를 들어 시스템이 다음 시스템보다 다운되었을 때 시간이 초과되었습니다. .pySNMP 타임 아웃을 지우려면 어떻게해야합니까?

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  

답변

1

당신은 채무 불이행 방법 매개 변수로 startedAt 변수를 초기화합니다. 이는 모듈 런타임에서 한 번만 발생하며 클래스 다시 인스턴스화시 반복되지 않습니다. 따라서 모든 쿼리 타이밍은 초기 staredAt 값과 비교하여 측정됩니다. 따라서 startedAt + 30을 (를) 지나서 발생한 모든 쿼리는 즉시 시간 초과됩니다.

관련 문제