Как получить ловушку с инди-компонентом TidSNMP
Я использую C++ BuilderXE с Indy 10.5.7, и я пытаюсь получить ловушку от другого агента snmp.
У меня нет информации, описывающей, как сделать программу для получения ловушки.
Ниже вы можете найти фрагмент кода, который я пытаюсь использовать сейчас.
Метод ReceiveTrap() всегда возвращает 0, что означает отсутствие данных.
Я протестировал конфигурацию ПК с другой программой, которую я сделал несколько лет назад, используя запасной API, и ловушка получена, поэтому я не делаю этого, это должно быть проблемой конфигурации.
Есть ли у вас какие-либо предположения о том, что я ошибаюсь в повседневной жизни? С наилучшими пожеланиями, Энцо
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 ответа
Это не правильный способ настройки порта прослушивания для приема прерываний. Чтение Binding
свойство выделяет и привязывает сокет к локальному IP/ порту, используя TIdSNMP::BoundIP
а также TIdSNMP::BoundPort
свойства. Вы не можете изменить локальный сокет Port
после того, как он уже был связан, так что ваше назначение Binding->Port
собственность по сути неактивна.
В этом отношении вы все равно пытаетесь манипулировать не тем сокетом. Binding
сокет используется для отправки запросов в удаленную систему SNMP. TIdSNMP
использует отдельный сокет для приема ловушек. TIdSNMP
имеет отдельный TrapPort
свойство для указания порта прослушивания этого сокета. Когда Binding
доступ, сокет ловушки выделен и привязан к Binding->IP
а также TIdSNMP::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 в прослушивающем сокете произошли некоторые изменения, связанные с ловушками, поэтому вам может потребоваться перейти на более новую версию Indy, чтобы получить исправления ошибок. Или вы можете скачать последнюю версию, а затем просто добавить IdSNMP.pas
к вашему проекту напрямую, по крайней мере.
Используя только компонент Indi, я не могу прочитать trap 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());
}
}
Для анализа полученных данных я использую Инди
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());
}
}