最近公司需要用到BonJour ,目前网上资料比较少,网页也没什么非常好的参考资料,只有下载源码,后在源码上修改如下:
.pro 文件如下:
LIBS += -L$$PWD/bonjour/Lib/x64/ -ldnssd INCLUDEPATH += $$PWD/bonjour/Include DEPENDPATH += $$PWD/bonjour/Include LIBS += -lws2_32
void MainWindow::browse_services(const char *regtype, const char *domain) { DNSServiceErrorType error = DNSServiceBrowse(&browse_ref, 0, 0, regtype, domain, browse_reply, &browse_ref); if (error != kDNSServiceErr_NoError) { qDebug() << "Browse failed with error" << error; return; } //DNSServiceProcessResult(browse_ref);//read 如果读取不到数据,就一直等待,阻塞等待 //DNSServiceRefDeallocate(browse_ref); }
void MainWindow::browse_reply(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context) { if (errorCode == kDNSServiceErr_NoError) { qDebug() << "Found service:" <<"["<< serviceName<<"]"<<"regtype:" <<"["<< regtype<<"]"<< "replyDomain" <<"["<< replyDomain <<"]"<<endl; resolveServicess(serviceName, regtype,replyDomain); } else { qDebug() << "Browse error:" << errorCode; } } void MainWindow::resolveServicess(const char *name, const char *type, const char *domain)
{
DNSServiceRef sdRef = NULL;
DNSServiceErrorType error = DNSServiceResolve( &sdRef, 0, 0, name, type, domain, resolve_reply, NULL);
if (error != kDNSServiceErr_NoError)
{
qDebug() << "DNSServiceResolve failed with error" << error;
return;
}
// 等待解析完成
DNSServiceProcessResult(sdRef);
DNSServiceRefDeallocate(sdRef);
}
void MainWindow::resolve_reply(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context)
{
if (errorCode != kDNSServiceErr_NoError)
{
qDebug()<<"22222222222"<<errorCode<<endl;
//fprintf(stderr, "Resolve failed: %ld\n", errorCode);
//exit(1);
}
qDebug()<<"333333"<<endl;
qDebug()<<"fullname:"<<fullname<<endl;
qDebug()<<"hostname:"<<hosttarget<<endl;
qDebug()<<"Port:"<<port<<endl;
QString strText(QString::fromUtf8(reinterpret_cast<const char*>(txtRecord), txtLen));
qDebug()<<"txt:"<<strText<<endl;
QHostInfo hostInfo = QHostInfo::fromName(hosttarget);
foreach (const QHostAddress &address, hostInfo.addresses())
{
if (address.protocol() == QAbstractSocket::IPv4Protocol)
{
qDebug() << "IPv4 Address:" << address.toString();
}
else if (address.protocol() == QAbstractSocket::IPv6Protocol)
{
qDebug() << "IPv6 Address:" << address.toString();
}
}
}
void MainWindow::HandleEvent()//DNSServiceProcessResult(browse_ref); 函数为阻塞接口,I/O中读取数据
{
fd_set fd_setVec;//定义集合
int fd_read=-1;
int fd_readMax=-1;
struct timeval tv;
int result=-1;
while(!mIsRun)
{
FD_ZERO(&fd_setVec);//清空集合
int fd_read=-1;
if(browse_ref !=nullptr)
{
fd_read=DNSServiceRefSockFD(browse_ref);
FD_SET(fd_read,&fd_setVec);//将文件句柄加入集合中,监听数据
}
fd_readMax=fd_read+1;
tv.tv_sec = 0;
tv.tv_usec = 500000;//500ms
result=select(fd_readMax,&fd_setVec,(fd_set *)nullptr,(fd_set*)nullptr,&tv);
if(result >0 )
{
qDebug()<<"Read Data:"<<endl;
DNSServiceErrorType error=kDNSServiceErr_NoError;
if( FD_ISSET(fd_read,&fd_setVec) && (browse_ref != nullptr) )
{
error=DNSServiceProcessResult(browse_ref);
if(error != kDNSServiceErr_NoError)
{
DNSServiceRefDeallocate(browse_ref);
mIsRun=true;
}
}
}
else if(result == 0)
{
//TimeOut
mIsRun=true;
qDebug()<<"TimeOut:"<<endl;
}
else
{
mIsRun=true;
qDebug()<<"Error...:"<<endl;
}
}
}
void MainWindow::on_pushButton_clicked()
{
mIsRun=false;
browse_services("_services._udp","local.");
HandleEvent();
}