2012-08-09 92 views
0

我正在使用C++ builderXE與Indy 10.5.7,並試圖從另一個代理snmp接收陷阱。如何使用indy TidSNMP組件陷阱

我沒有介紹如何做接收陷阱的程序的信息。

下面你可以找到我正在嘗試使用的代碼片段。

ReceiveTrap()方法總是返回0,這意味着收到非數據。

我用幾年前使用備用API製作的另一個程序測試了PC配置,並且收到了陷阱,所以我不這樣做,它應該是配置問題。

你有一些帽子的建議我在例行下面錯了嗎? 最好的問候,恩佐

void __fastcall TForm1::LabelReceiveTrapClick(TObject * Sender) 
{ 
    static bool status = false; 
    int ists; 
    String Fun   = "[SimpleReceiveTrap] "; 
    TSNMPInfo * infoSnmp = 0; 

    try 
    { 
     status = !status; 

     if (status) 
     { 
      std::auto_ptr<TIdSNMP>clientSnmp(new TIdSNMP(NULL)); 
      clientSnmp->Community  = "public"; 
      clientSnmp->ReceiveTimeout = 1000; 
      clientSnmp->Binding->Port = 162; 
      while (status) 
      { 
       Application->ProcessMessages(); 
       ists = clientSnmp->ReceiveTrap(); 
       Mylog(L"%s ReceiveTrap status = [%d]", Fun.c_str(), ists); 
       if (ists > 0) 
       { 
        infoSnmp = clientSnmp->Trap; 
       } 
      } 
     } 
    } 
    catch (Exception & ex) 
    { 
     Mylog(L"%s ERROR", Fun.c_str(), ex.Message.c_str()); 
    } 
} 

回答

1

那是不是設置的監聽端口接收陷阱的正確方法。讀取Binding屬性使用TIdSNMP::BoundIPTIdSNMP::BoundPort屬性分配並將套接字綁定到本地IP /端口。您已經綁定後不能更改該套接字的本地Port,因此您的Binding->Port屬性的分配實際上是無效的。

對於這個問題,無論如何你都試圖操縱錯誤的插座。 Binding套接字用於向遠程SNMP系統發送查詢。 TIdSNMP使用一個單獨的插座來接收陷阱。 TIdSNMP具有單獨的TrapPort屬性,用於指定該套接字的偵聽端口。當訪問Binding時,陷阱套接字被分配並綁定到Binding->IPTIdSNMP::TrapPort。該TrapPort屬性默認爲162

std::auto_ptr<TIdSNMP>clientSnmp(new TIdSNMP(NULL)); 
clientSnmp->Community = "public"; 
clientSnmp->ReceiveTimeout = 1000; 
clientSnmp->TrapPort = 162; // <-- 
... 
ists = clientSnmp->ReceiveTrap(); 

看着Indy的更新日誌,出現了一些陷阱相關更改監聽套接字,因爲10.5.7發佈,所以你可能需要升級到一個新的印版獲得錯誤修復。或者,您可以下載最新版本,然後直接將IdSNMP.pas直接添加到您的項目中。

0

只使用悠組件我無法讀取陷阱轉2C 但我發現使用TWSocket和TSNMPInfo的解決方案,這似乎運作良好

Belowe我使用的代碼:

要獲得數據我用TWSocket來回FPiette組件套件:

void __fastcall TForm1::LabelStartServerTracSnmpClick(TObject * Sender) 
{ 
    String Fun = "[LabelStartServerTracSnmp] "; 
    try 
    { 
     if (WSocket1->State == wsClosed) 
     { 
      WSocket1->Proto = "udp"; 
      WSocket1->Addr = "0.0.0.0"; 
      WSocket1->Port = 162; 
      WSocket1->Listen(); 
     } 
     else 
     { 
      WSocket1->Close(); 
     } 
    } 
    catch (Exception & ex) 
    { 
     Mylog(L"%s ERROR: [%s]", Fun.c_str(), ex.Message.c_str()); 
    } 
} 

分析接收到的數據我用的是印地

void __fastcall TForm1::WSocket1DataAvailable(TObject * Sender, WORD ErrCode) 
{ 
    char buffer[1024]; 
    int len, cnt, srcLen; 
    TSockAddrIn srcSocket; 
    String rcvmsg, remHost, s1, s2, Fun = "[WSocket1DataAvailable] "; 
    TIdSNMP * clientSnmp = NULL; 
    TSNMPInfo * infoSnmp = NULL; 
    try 
    { 
     srcLen = sizeof(srcSocket); 
     len = WSocket1->ReceiveFrom(buffer, sizeof(buffer), srcSocket, srcLen); 
     if (len >= 0) 
     { 
      buffer[len] = 0; 
      rcvmsg  = String(buffer, len); 

      __try 
      { 
       clientSnmp = new TIdSNMP(NULL); 
       infoSnmp = new TSNMPInfo(clientSnmp); 
       infoSnmp->DecodeBuf(rcvmsg); 
       cnt = infoSnmp->ValueCount; 
       if (cnt > 0) 
       { 
        // --------------------------------------------------- 
        for (int idx = 0; idx < cnt; ++idx) 
        { 
         s1 = infoSnmp->ValueOID[idx]; 
         s2 = infoSnmp->Value[idx]; 
         Mylog(L"[%s] Trap : [%s] => [%s]", s1.c_str(), s2.c_str()); 
        } 
       } 
      } 
      __finally 
      { 
       if (infoSnmp) 
       { 
        delete infoSnmp; 
        infoSnmp = 0; 
       } 
       if (clientSnmp) 
       { 
        delete clientSnmp; 
        clientSnmp = 0; 
       } 
      } 
     } 
    } 
    catch (Exception & ex) 
    { 
     Mylog(L"%s ERROR", Fun.c_str(), ex.Message.c_str()); 
    } 

}