对于SNMP++异步调用,在进行读取操作后,必须调用start_poll_thread();开启事件循环线程,否则回调函数只会在程序退出时即对象机构时被调用,并且在回调中
qDebug() << "SNMP session, callback error:" << session->error_msg(reason);
返回的错误为-8,"SNMP++: Closing session with outstanding requests"。
这就要求在编译snmp++库时不能添加--disable-threads选项。
snmp++会新建一个轮询的线程,调用系统的select()或者poll()处理事件。
使用异步的机制比较简单,snmp++提供的几个操作函数都会有重载的带回调的一种方法,例如:
/**
* @brief Get bulk data.
*
* @param oid : Start oid.
* @param nonReps: non repeaters.
* @param maxReps: max repetitions.
*
*/
bool SNMPSession::getBulk(const QString &oid, int nonReps, int maxReps)
{
Pdu pdu;
pdu += Vb(Oid(oid.toLocal8Bit().constData()));
int ret = m_snmp->get_bulk(pdu, m_target, nonReps, maxReps,
&SNMPSession::sessionCallback, this);
if (ret != SNMP_CLASS_SUCCESS) {
qDebug() << "SNMP session, " << getEntiry() << "get bulk error: " << m_snmp->error_msg(ret);
addErrCnt();
return false;
}
return true;
}
这里调用的是类中静态回调函数,并把当前类指针传入到回调中,方便后续处理:
/**
* @brief Callback function of SNMP session.
*
* @param reason : Reason for callback (see snmperrs.h)
* @param session: Pointer to Snmp object that was used to send the request
* @param pdu : The received Pdu if reason indicates a received message
* @param target : source target
* @param data : Pointer passed to the async method
*
*/
void SNMPSession::sessionCallback(int reason, Snmp *session, Pdu &pdu, SnmpTarget &target, void *data)
{
Q_UNUSED(session)
Q_UNUSED(target)
SNMPSession *snmp = static_cast(data);
if (reason != SNMP_CLASS_ASYNC_RESPONSE) {
qDebug() << "Thread: " << QThread::currentThreadId()
<< ", SNMP session " << snmp->getEntiry()
<< ", callback error:" << session->error_msg(reason);
snmp->addErrCnt();
return;
}
snmp->changeCommstatus(DevOnline);
emit snmp->readyRead(snmp->m_ipv4, pdu);
}