UDPListener improvements: (#53)

- if you listen to a multicast address, it now also listens to all ipv4 addresses
- shared udp sockets - multiple hyperiond instance can optionally share the same udp packets
This commit is contained in:
penfold42 2016-06-27 04:08:03 +10:00 committed by brindosch
parent e486b10aa6
commit de39ff8997
3 changed files with 21 additions and 13 deletions

View File

@ -26,7 +26,7 @@ public:
/// @param hyperion Hyperion instance /// @param hyperion Hyperion instance
/// @param port port number on which to start listening for connections /// @param port port number on which to start listening for connections
/// ///
UDPListener(const int priority, const int timeout, const std::string& address, quint16 listenPort); UDPListener(const int priority, const int timeout, const std::string& address, quint16 listenPort, bool shared);
~UDPListener(); ~UDPListener();
/// ///

View File

@ -10,7 +10,7 @@
#include "utils/ColorRgb.h" #include "utils/ColorRgb.h"
#include "HyperionConfig.h" #include "HyperionConfig.h"
UDPListener::UDPListener(const int priority, const int timeout, const std::string& address, quint16 listenPort) : UDPListener::UDPListener(const int priority, const int timeout, const std::string& address, quint16 listenPort, bool shared) :
QObject(), QObject(),
_hyperion(Hyperion::getInstance()), _hyperion(Hyperion::getInstance()),
_server(), _server(),
@ -21,25 +21,32 @@ UDPListener::UDPListener(const int priority, const int timeout, const std::strin
_log(Logger::getInstance("UDPLISTENER")) _log(Logger::getInstance("UDPLISTENER"))
{ {
_server = new QUdpSocket(this); _server = new QUdpSocket(this);
QHostAddress listenAddress = QHostAddress(QHostAddress::Any);
if (address.empty()) { QAbstractSocket::BindFlag bondage = QAbstractSocket::DefaultForPlatform;
listenAddress = QHostAddress::Any; if (shared) {
} else { bondage = QAbstractSocket::ShareAddress;
}
QHostAddress listenAddress = QHostAddress(QHostAddress::Any);
QHostAddress mcastGroup;
if (!address.empty()) {
listenAddress = QHostAddress( QString::fromStdString(address) ); listenAddress = QHostAddress( QString::fromStdString(address) );
} }
if (listenAddress.isInSubnet(QHostAddress::parseSubnet("224.0.0.0/4"))) {
mcastGroup = listenAddress;
listenAddress = QHostAddress(QHostAddress::AnyIPv4);
}
if (!_server->bind(listenAddress, listenPort)) if (!_server->bind(listenAddress, listenPort, bondage))
{ {
Warning(_log, "Could not bind to %s:%d parsed from %s", listenAddress.toString().toStdString().c_str(), listenPort, address.c_str()); Warning(_log, "Could not bind to %s:%d parsed from %s", listenAddress.toString().toStdString().c_str(), listenPort, address.c_str());
} else { } else {
Info(_log, "Started, listening on %s:%d", listenAddress.toString().toStdString().c_str(), listenPort); Info(_log, "Started, listening on %s:%d", listenAddress.toString().toStdString().c_str(), listenPort);
// if (listenAddress.QHostAddress::isMulticast() ) { // needs qt >= 5.6 if (!mcastGroup.isNull()) {
if (listenAddress.isInSubnet(QHostAddress::parseSubnet("224.0.0.0/4"))) { if (_server->joinMulticastGroup(mcastGroup)) {
if (_server->joinMulticastGroup(listenAddress)) { Info(_log, "Multicast listening on %s",mcastGroup.toString().toStdString().c_str());
Info(_log, "Multicast enabled");
} else { } else {
Warning(_log, "Multicast failed"); Warning(_log, "Multicast failed for %s", mcastGroup.toString().toStdString().c_str());
} }
} }
} }

View File

@ -251,7 +251,8 @@ void HyperionDaemon::startNetworkServices()
udpListenerConfig.get("priority",700).asInt(), udpListenerConfig.get("priority",700).asInt(),
udpListenerConfig.get("timeout",10000).asInt(), udpListenerConfig.get("timeout",10000).asInt(),
udpListenerConfig.get("address", "").asString(), udpListenerConfig.get("address", "").asString(),
udpListenerConfig.get("port", 2801).asUInt() udpListenerConfig.get("port", 2801).asUInt(),
udpListenerConfig.get("shared", false).asBool()
); );
Info(_log, "UDP listener created and started on port %d", _udpListener->getPort()); Info(_log, "UDP listener created and started on port %d", _udpListener->getPort());
} }