windows环境下基于QTc++和ONVIF协议写一个设备发现工具代码
时间: 2024-02-01 14:13:35 浏览: 244
OnvifDeviceManager onvif IPC客户端工具
这是一个基于QT C++和ONVIF协议的简单设备发现工具示例代码:
首先,你需要创建一个QT窗口应用程序,在mainwindow.h文件中添加以下头文件:
```c++
#include <QObject>
#include <QUdpSocket>
#include <QNetworkDatagram>
#include <QList>
#include <QDebug>
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
#include <QTimer>
#include <QNetworkInterface>
#include <QNetworkAddressEntry>
```
然后在mainwindow.h文件中添加以下成员变量:
```c++
private:
QUdpSocket *m_udpSocket;
QList<QHostAddress> m_localAddresses;
QList<QHostAddress> m_onvifAddresses;
QList<QHostAddress> m_onvifDevices;
QMutex m_mutex;
QWaitCondition m_waitCondition;
QTimer *m_timer;
```
在mainwindow.cpp文件中初始化成员变量:
```c++
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
// 初始化UDP套接字
m_udpSocket = new QUdpSocket(this);
connect(m_udpSocket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
// 获取本地IP地址列表
QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
foreach (QNetworkInterface interface, interfaces) {
if (interface.flags().testFlag(QNetworkInterface::IsUp) && !interface.flags().testFlag(QNetworkInterface::IsLoopBack)) {
QList<QNetworkAddressEntry> addressEntries = interface.addressEntries();
foreach (QNetworkAddressEntry addressEntry, addressEntries) {
if (addressEntry.ip().protocol() == QAbstractSocket::IPv4Protocol) {
m_localAddresses.append(addressEntry.ip());
}
}
}
}
// 设置ONVIF协议的IP地址和端口
m_onvifAddresses.append(QHostAddress("239.255.255.250"));
m_onvifAddresses.append(QHostAddress("255.255.255.255"));
m_onvifAddresses.append(QHostAddress("ff02::c"));
m_onvifAddresses.append(QHostAddress("ff02::1"));
m_onvifAddresses.append(QHostAddress("ff02::2"));
// 初始化定时器
m_timer = new QTimer(this);
connect(m_timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
}
```
接下来,实现onReadyRead()和onTimeout()函数:
```c++
void MainWindow::onReadyRead()
{
QNetworkDatagram datagram = m_udpSocket->receiveDatagram();
QHostAddress senderAddress = datagram.senderAddress();
if (m_onvifAddresses.contains(senderAddress) && datagram.data().contains("urn:schemas-xmlsoap-org:device:")) {
QString data = QString(datagram.data());
QStringList lines = data.split("\r\n");
QString deviceType, friendlyName, manufacturer, modelDescription, modelName, serialNumber, presentationURL;
foreach (QString line, lines) {
if (line.contains("urn:schemas-upnp-org:device:")) {
deviceType = line;
} else if (line.contains("friendlyName")) {
friendlyName = line.split(":").at(1).trimmed();
} else if (line.contains("manufacturer")) {
manufacturer = line.split(":").at(1).trimmed();
} else if (line.contains("modelDescription")) {
modelDescription = line.split(":").at(1).trimmed();
} else if (line.contains("modelName")) {
modelName = line.split(":").at(1).trimmed();
} else if (line.contains("serialNumber")) {
serialNumber = line.split(":").at(1).trimmed();
} else if (line.contains("presentationURL")) {
presentationURL = line.split(":").at(1).trimmed();
}
}
QString deviceInfo = QString("%1\n%2\n%3\n%4\n%5\n%6\n%7\n")
.arg(senderAddress.toString())
.arg(deviceType)
.arg(friendlyName)
.arg(manufacturer)
.arg(modelDescription)
.arg(modelName)
.arg(serialNumber);
m_mutex.lock();
m_onvifDevices.append(senderAddress);
m_mutex.unlock();
}
}
void MainWindow::onTimeout()
{
m_udpSocket->writeDatagram("M-SEARCH * HTTP/1.1\r\n"
"Host: 239.255.255.250:1900\r\n"
"Man: \"ssdp:discover\"\r\n"
"MX: 1\r\n"
"ST: urn:schemas-xmlsoap-org:device:NetworkVideoTransmitter:1\r\n\r\n",
QHostAddress("239.255.255.250"), 1900);
}
```
最后,在mainwindow.cpp文件的构造函数中启动定时器:
```c++
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
// ...
// 启动定时器
m_timer->start(5000);
}
```
这样,你就可以在windows环境下运行该设备发现工具,以查找ONVIF协议的设备并获取其IP地址和其他信息。
阅读全文