如何使用indy TidSNMP组件获取陷阱

时间:2012-08-09 08:37:44

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

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

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

下面你可以找到我现在正在尝试使用的代码片段。

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

2 个答案:

答案 0 :(得分:1)

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

就此而言,你正试图操纵错误的套接字。 Binding套接字用于向远程SNMP系统发送查询。 TIdSNMP使用单独的套接字来接收陷阱。 TIdSNMP具有单独的TrapPort属性,用于指定该套接字的侦听端口。访问Binding时,将分配陷阱套接字并绑定到Binding->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,至少。

答案 1 :(得分:0)

仅使用Indi组件我无法读取陷阱rev 2c 但我发现使用TWSocket和TSNMPInfo的解决方案似乎运行良好

在我使用的代码下面:

要获取数据我使用的是FPiette组件套件的TWSocket:

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

}