【问题标题】:How get trap with indy TidSNMP component如何使用 indy TidSNMP 组件获取陷阱
【发布时间】:2012-08-09 08:37:43
【问题描述】:

我正在使用带有 Indy 10.5.7 的 c++builderXE,我正在尝试从另一个代理 snmp 接收陷阱。

我没有任何信息描述如何执行接收陷阱的程序。

您可以在下面找到我现在尝试使用的代码的 sn-p。

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());
    }
}

【问题讨论】:

    标签: c++builder snmp indy snmp-trap


    【解决方案1】:

    这不是设置接收陷阱的侦听端口的正确方法。读取Binding 属性会使用TIdSNMP::BoundIPTIdSNMP::BoundPort 属性分配套接字并将其绑定到本地IP/端口。绑定后,您无法更改该套接字的本地 Port,因此您对 Binding-&gt;Port 属性的分配实际上是无操作的。

    就此而言,无论如何,您都在尝试操作错误的套接字。 Binding 套接字用于向远程 SNMP 系统发送查询。 TIdSNMP 使用单独的套接字来接收陷阱。 TIdSNMP 有一个单独的 TrapPort 属性,用于指定该套接字的侦听端口。当Binding被访问时,陷阱套接字被分配并绑定到Binding-&gt;IPTIdSNMP::TrapPortTrapPort 属性默认为 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 发布以来,监听套接字发生了一些与陷阱相关的更改,因此您可能需要升级到更新的 Indy 版本才能修复错误。或者您可以下载最新版本,然后直接将IdSNMP.pas 添加到您的项目中,至少。

    【讨论】:

      【解决方案2】:

      仅使用 Indi 组件我无法读取陷阱 rev 2c 但我找到了一个使用 TWSocket 和 TSNMPInfo 的解决方案,似乎效果很好

      在我使用的代码下方:

      为了获取数据,我使用 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());
          }
      }
      

      为了分析收到的数据,我使用了 Indy

      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());
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多