在开发中,可能会遇到需要寻找局域网可用主机的需求,可以搜索一下zeroconf关键字,做这一块的项目不多,但大多都需要用苹果的打印服务,而且在各个系统平台都没有一个统一的工具。当然也可以自己根据协议写一个,其实就是局域网内广播,本着有现成资源就用的原则,最后发现了 QMdnsEngine ,经过测试后,效果还是不错。
https://github.com/nitroshare/qmdnsengine
去github下载即可,由于它使用的CMake进行的管理,你自己的项目最好也是使用的CMake管理
它的官方介绍如下:
新建项目Qt项目 Provider ,在CMakeLists中添加以下,就可将QMdnsEngine添加到项目,注意QMdnsEngine是和CMakeLists在同一目录。
add_subdirectory(qmdnsengine)
target_link_libraries(${PROJECT_NAME}
PRIVATE
qmdnsengine
)
main.cpp
#include "mainwindow.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
static QSharedPointer<QMdnsEngine::Server> server(new QMdnsEngine::Server());
static QSharedPointer<QMdnsEngine::Hostname> hostname(new QMdnsEngine::Hostname(server.get()));
static QSharedPointer<QMdnsEngine::Provider> provider(new QMdnsEngine::Provider(server.get(), hostname.get()));
/// 这里构建需要发送的内容
QMdnsEngine::Service service;
service.setType("_http._tcp.local.");
service.setName(QString("name%1").toLatin1());
// service.setHostname("hostname 192.168.1.112");
service.setPort(2231);
QMap<QByteArray, QByteArray> map;
map.insert(QString("id1").toLatin1(), QString("data1").toLatin1());
map.insert(QString("id2").toLatin1(), QString("data2").toLatin1());
service.setAttributes(map);
//更新
provider->update(service);
/// 下面的内容可以不要,我这里是测试了下,如果有新数据不停的更新时效果,实时上也是可以的,但更新频率不能太高
/// 更新频率太高会更新不到。
QTimer t;
int num = 0;
QObject::connect(&t, &QTimer::timeout, [&]() {
num++;
map.insert(QString("id1").toLatin1(), QString("data%1").arg(num).toLatin1());
service.setAttributes(map);
provider->update(service);
});
t.start(10 * 1000);
return a.exec();
}
同样新建项目Qt项目 Browser ,在CMakeLists中添加以下内容
add_subdirectory(qmdnsengine)
target_link_libraries(${PROJECT_NAME}
PRIVATE
qmdnsengine
)
main.cpp
#include "mainwindow.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
static QSharedPointer<QMdnsEngine::Server> server(new QMdnsEngine::Server());
static QSharedPointer<QMdnsEngine::Browser> browser(new QMdnsEngine::Browser(server.get(), QMdnsEngine::MdnsBrowseType));
QObject::connect(browser.get(), &QMdnsEngine::Browser::serviceAdded, [&](const QMdnsEngine::Service& service) {
qDebug() << "Add: " << service.type() << service.name() << service.hostname() << service.port() << service.attributes();
});
QObject::connect(browser.get(), &QMdnsEngine::Browser::serviceUpdated, [&](const QMdnsEngine::Service& service) {
qDebug() << "Updated: " << service.type() << service.name() << service.hostname() << service.port() << service.attributes();
});
QObject::connect(browser.get(), &QMdnsEngine::Browser::serviceRemoved, [&](const QMdnsEngine::Service& service) {
qDebug() << "Removed: " << service.type() << service.name() << service.hostname() << service.port() << service.attributes();
});
return a.exec();
}
两个代码直接运行就可以了,注意有以下几点需要注意的: