From 92622c556b1566df131d15cc1d328352fdb0b253 Mon Sep 17 00:00:00 2001 From: Andrew Goessling Date: Wed, 16 Aug 2023 21:35:17 -0700 Subject: [PATCH 1/2] Add multicast support to DataStreamUDP. This adds the ability to specify a address other than 127.0.0.1 when starting DataStreamUDP. If the address is a multicast address the UDP socket is configured to join the multicast group. --- .../DataStreamUDP/udp_client.py | 16 ++++-- .../DataStreamUDP/udp_server.cpp | 33 +++++++++--- .../DataStreamUDP/udp_server.ui | 54 ++++++++++++++++--- 3 files changed, 85 insertions(+), 18 deletions(-) diff --git a/plotjuggler_plugins/DataStreamUDP/udp_client.py b/plotjuggler_plugins/DataStreamUDP/udp_client.py index 31388bc76..1bb566ab6 100755 --- a/plotjuggler_plugins/DataStreamUDP/udp_client.py +++ b/plotjuggler_plugins/DataStreamUDP/udp_client.py @@ -1,10 +1,16 @@ #!/usr/bin/python +import argparse import socket import math import json from time import sleep +parser = argparse.ArgumentParser(description="Send UDP test data.") +parser.add_argument("--address", default="127.0.0.1", help="UDP address") +parser.add_argument("--port", default=9870, type=int, help="UDP port") +args = parser.parse_args() + sock = socket.socket(socket.AF_INET, # Internet socket.SOCK_DGRAM) # UDP time = 0.0 @@ -20,8 +26,8 @@ "sin": math.sin(time) } } - sock.sendto( json.dumps(data).encode(), ("127.0.0.1", 9870) ) - + sock.sendto( json.dumps(data).encode(), (args.address, args.port) ) + test_str = "{ \ \"1252\": { \ \"timestamp\": { \ @@ -35,7 +41,7 @@ \"volt\": 24.852617263793945 \ }\ }\ - } }" - - sock.sendto( test_str.encode('utf-8'), ("127.0.0.1", 9870) ) + } }" + + sock.sendto( test_str.encode("utf-8"), (args.address, args.port) ) diff --git a/plotjuggler_plugins/DataStreamUDP/udp_server.cpp b/plotjuggler_plugins/DataStreamUDP/udp_server.cpp index 85ea996ed..4cf0a3fe7 100644 --- a/plotjuggler_plugins/DataStreamUDP/udp_server.cpp +++ b/plotjuggler_plugins/DataStreamUDP/udp_server.cpp @@ -97,8 +97,10 @@ bool UDP_Server::start(QStringList*) // load previous values QSettings settings; QString protocol = settings.value("UDP_Server::protocol", "JSON").toString(); + QString address_str = settings.value("UDP_Server::address", "127.0.0.1").toString(); int port = settings.value("UDP_Server::port", 9870).toInt(); + dialog.ui->lineEditAddress->setText(address_str); dialog.ui->lineEditPort->setText(QString::number(port)); ParserFactoryPlugin::Ptr parser_creator; @@ -130,6 +132,7 @@ bool UDP_Server::start(QStringList*) return false; } + address_str = dialog.ui->lineEditAddress->text(); port = dialog.ui->lineEditPort->text().toUShort(&ok); protocol = dialog.ui->comboBoxProtocol->currentText(); @@ -137,23 +140,41 @@ bool UDP_Server::start(QStringList*) // save back to service settings.setValue("UDP_Server::protocol", protocol); + settings.setValue("UDP_Server::address", address_str); settings.setValue("UDP_Server::port", port); + QHostAddress address(address_str); + + bool success = true; + success &= !address.isNull(); + _udp_socket = new QUdpSocket(); - _udp_socket->bind(QHostAddress::Any, port); + + if (!address.isMulticast()) + { + success &= _udp_socket->bind(address, port); + } + else + { + success &= _udp_socket->bind( + address, port, QAbstractSocket::ShareAddress | QAbstractSocket::ReuseAddressHint); + success &= _udp_socket->joinMulticastGroup(address); + } + + _running = true; connect(_udp_socket, &QUdpSocket::readyRead, this, &UDP_Server::processMessage); - if (_udp_socket) + if (success) { - qDebug() << "UDP listening on port" << port; - _running = true; + qDebug() << tr("UDP listening on (%1, %2)").arg(address_str).arg(port); } else { QMessageBox::warning(nullptr, tr("UDP Server"), - tr("Couldn't bind UDP port %1").arg(port), QMessageBox::Ok); - _running = false; + tr("Couldn't bind to UDP (%1, %2)").arg(address_str).arg(port), + QMessageBox::Ok); + shutdown(); } return _running; diff --git a/plotjuggler_plugins/DataStreamUDP/udp_server.ui b/plotjuggler_plugins/DataStreamUDP/udp_server.ui index d175faa77..79d5a7216 100644 --- a/plotjuggler_plugins/DataStreamUDP/udp_server.ui +++ b/plotjuggler_plugins/DataStreamUDP/udp_server.ui @@ -6,8 +6,8 @@ 0 0 - 293 - 232 + 298 + 312 @@ -19,24 +19,65 @@ 12 - 75 true - Port of the UDP server: + UDP Server Settings: - + + + + + + + true + + + + Address: + + + + + + + + + + + + + + + + + true + + + + Port: + + + + + + + + + + + + 12 - 75 true @@ -67,7 +108,6 @@ - 75 true From a4d8ab911e3d41173cec258368a2d7efffeb9019 Mon Sep 17 00:00:00 2001 From: Andrew Goessling Date: Thu, 17 Aug 2023 22:33:51 -0700 Subject: [PATCH 2/2] UDP multicast listen on all appicable interfaces. --- plotjuggler_plugins/DataStreamUDP/udp_server.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/plotjuggler_plugins/DataStreamUDP/udp_server.cpp b/plotjuggler_plugins/DataStreamUDP/udp_server.cpp index 4cf0a3fe7..415fda7c0 100644 --- a/plotjuggler_plugins/DataStreamUDP/udp_server.cpp +++ b/plotjuggler_plugins/DataStreamUDP/udp_server.cpp @@ -28,6 +28,7 @@ THE SOFTWARE. #include #include #include +#include #include "ui_udp_server.h" @@ -158,7 +159,18 @@ bool UDP_Server::start(QStringList*) { success &= _udp_socket->bind( address, port, QAbstractSocket::ShareAddress | QAbstractSocket::ReuseAddressHint); - success &= _udp_socket->joinMulticastGroup(address); + + // Add multicast group membership to all interfaces which support multicast. + for (const auto& interface : QNetworkInterface::allInterfaces()) + { + QNetworkInterface::InterfaceFlags iflags = interface.flags(); + if (interface.isValid() && !iflags.testFlag(QNetworkInterface::IsLoopBack) && + iflags.testFlag(QNetworkInterface::CanMulticast) && + iflags.testFlag(QNetworkInterface::IsRunning)) + { + success &= _udp_socket->joinMulticastGroup(address, interface); + } + } } _running = true;