KD SOAP API Documentation 2.2
Loading...
Searching...
No Matches
KDSoapUdpClient.cpp
Go to the documentation of this file.
1/****************************************************************************
2**
3** This file is part of the KD Soap project.
4**
5** SPDX-FileCopyrightText: 2020 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
6**
7** SPDX-License-Identifier: MIT
8**
9****************************************************************************/
10
11#include "KDSoapUdpClient.h"
12#include "KDSoapUdpClient_p.h"
13
14#include "KDSoapMessage.h"
17#include <QNetworkInterface>
18
19static bool isMulticastAddress(const QHostAddress &address)
20{
21 if (address.protocol() == QAbstractSocket::IPv4Protocol) {
22 return address.isInSubnet(QHostAddress(QLatin1String("224.0.0.0")), 4);
23 } else if (address.protocol() == QAbstractSocket::IPv6Protocol) {
24 return address.isInSubnet(QHostAddress(QLatin1String("ff00::")), 8);
25 }
26 return false;
27}
28
30 : QObject(parent)
31 , d_ptr(new KDSoapUdpClientPrivate(this))
32{
34 d->socket = new QUdpSocket(this);
36}
37
39{
40 delete d_ptr;
41}
42
44{
46 const bool rc = d->socket->bind(QHostAddress::Any, port, mode);
47 if (!rc) {
48 qWarning() << "KDSoapUdpClient: failed to bind on port" << port << "mode" << mode << ":" << d->socket->errorString();
49 }
50 return rc;
51}
52
54{
56 d->soapVersion = version;
57}
58
59bool KDSoapUdpClient::sendMessage(const KDSoapMessage &message, const KDSoapHeaders &headers, const QHostAddress &address, quint16 port)
60{
63 msgWriter.setVersion(d->soapVersion);
64 const QByteArray data = msgWriter.messageToXml(message, QString(), headers, QMap<QString, KDSoapMessage>());
65
66 if (isMulticastAddress(address)) {
67 bool anySuccess = false;
68 const auto &allInterfaces = QNetworkInterface::allInterfaces();
69 for (const auto &iface : allInterfaces) {
70 if (iface.flags().testFlag(QNetworkInterface::IsUp) && iface.flags().testFlag(QNetworkInterface::CanMulticast)) {
71 // qDebug() << "Sending multicast to" << iface.name() << address << ":" << data;
72 d->socket->setMulticastInterface(iface);
73 const qint64 writtenSize = d->socket->writeDatagram(data, address, port);
74 anySuccess = anySuccess || (writtenSize == data.size());
75 }
76 }
77 return anySuccess;
78 } else {
79 // qDebug() << "Sending to" << address << ":" << data;
80 const qint64 writtenSize = d->socket->writeDatagram(data, address, port);
81 return writtenSize == data.size();
82 }
83}
84
86{
88 while (socket->hasPendingDatagrams()) {
90
91 QByteArray buffer;
92 buffer.resize(size);
93 QHostAddress senderAddress;
94 quint16 senderPort;
95 socket->readDatagram(buffer.data(), buffer.size(), &senderAddress, &senderPort);
96
97 receivedDatagram(buffer, senderAddress, senderPort);
98 }
99}
100
101void KDSoapUdpClientPrivate::receivedDatagram(const QByteArray &messageData, const QHostAddress &senderAddress, quint16 senderPort)
102{
104 // qDebug() << "Received datagram from:" << senderAddress << "data:" << QString::fromUtf8(messageData);
105
106 KDSoapMessage replyMessage;
107 KDSoapHeaders replyHeaders;
108
110 reader.xmlToMessage(messageData, &replyMessage, 0, &replyHeaders, soapVersion);
111
112 emit q->receivedMessage(replyMessage, replyHeaders, senderAddress, senderPort);
113}
static bool isMulticastAddress(const QHostAddress &address)
XmlError xmlToMessage(const QByteArray &data, KDSoapMessage *pParsedMessage, QString *pMessageNamespace, KDSoapHeaders *pRequestHeaders, KDSoap::SoapVersion soapVersion) const
void setVersion(KDSoap::SoapVersion version)
KDSoap::SoapVersion soapVersion
void receivedDatagram(const QByteArray &messageData, const QHostAddress &senderAddress, quint16 senderPort)
KDSoapUdpClient provides an interface for implementing a SOAP-over-UDP client.
void setSoapVersion(KDSoap::SoapVersion version)
bool bind(quint16 port=0, QAbstractSocket::BindMode mode=QAbstractSocket::DefaultForPlatform)
bool sendMessage(const KDSoapMessage &message, const KDSoapHeaders &headers, const QHostAddress &address, quint16 port)
KDSoapUdpClient(QObject *parent=nullptr)
char * data()
void resize(int size)
int size() const const
bool isInSubnet(const QHostAddress &subnet, int netmask) const const
QAbstractSocket::NetworkLayerProtocol protocol() const const
void readyRead()
QList< QNetworkInterface > allInterfaces()
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
T qobject_cast(QObject *object)
QObject * sender() const const
bool hasPendingDatagrams() const const
qint64 pendingDatagramSize() const const
qint64 readDatagram(char *data, qint64 maxSize, QHostAddress *address, quint16 *port)

© Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
https://www.kdab.com/development-resources/qt-tools/kd-soap/
Generated on Sat Apr 20 2024 00:04:25 for KD SOAP API Documentation by doxygen 1.9.8