From f9c07da7b6c167820a71d2c840b7be70c393457a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 12 Dec 2017 13:55:32 -0800 Subject: Examples: Update multicast sender and receiver examples for IPv6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's the right thing to do, as we're in 2017, not 1997. Also, this takes care to indicate that QAbstractSocket::MulticastTtlOption makes sense mostly for IPv4, even though it's implemented for both families. In IPv4, it's used to indicatae the scope, whereas in IPv6 it's stored in bits 12-15 of the address. Task-number: QTBUG-46046 Change-Id: I9741f017961b410c910dfffd14ffaabe0a2024d8 Reviewed-by: MÃ¥rten Nordheim Reviewed-by: Timur Pocheptsov --- examples/network/multicastreceiver/receiver.cpp | 35 ++++++++++++++++++------- examples/network/multicastreceiver/receiver.h | 6 +++-- examples/network/multicastsender/sender.cpp | 23 ++++++++++++---- examples/network/multicastsender/sender.h | 6 +++-- 4 files changed, 52 insertions(+), 18 deletions(-) (limited to 'examples') diff --git a/examples/network/multicastreceiver/receiver.cpp b/examples/network/multicastreceiver/receiver.cpp index 8985ad1d82..d793242ad0 100644 --- a/examples/network/multicastreceiver/receiver.cpp +++ b/examples/network/multicastreceiver/receiver.cpp @@ -55,9 +55,10 @@ Receiver::Receiver(QWidget *parent) : QDialog(parent), - groupAddress(QStringLiteral("239.255.43.21")) + groupAddress4(QStringLiteral("239.255.43.21")), + groupAddress6(QStringLiteral("ff12::2115")) { - statusLabel = new QLabel(tr("Listening for multicasted messages")); + statusLabel = new QLabel(tr("Listening for multicast messages on both IPv4 and IPv6")); auto quitButton = new QPushButton(tr("&Quit")); auto buttonLayout = new QHBoxLayout; @@ -72,21 +73,37 @@ Receiver::Receiver(QWidget *parent) setWindowTitle(tr("Multicast Receiver")); - udpSocket.bind(QHostAddress::AnyIPv4, 45454, QUdpSocket::ShareAddress); - udpSocket.joinMulticastGroup(groupAddress); + udpSocket4.bind(QHostAddress::AnyIPv4, 45454, QUdpSocket::ShareAddress); + udpSocket4.joinMulticastGroup(groupAddress4); - connect(&udpSocket, SIGNAL(readyRead()), + if (!udpSocket6.bind(QHostAddress::AnyIPv6, 45454, QUdpSocket::ShareAddress) || + !udpSocket6.joinMulticastGroup(groupAddress6)) + statusLabel->setText(tr("Listening for multicast messages on IPv4 only")); + + connect(&udpSocket4, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams())); + connect(&udpSocket6, &QUdpSocket::readyRead, this, &Receiver::processPendingDatagrams); connect(quitButton, SIGNAL(clicked()), this, SLOT(close())); } void Receiver::processPendingDatagrams() { QByteArray datagram; - while (udpSocket.hasPendingDatagrams()) { - datagram.resize(int(udpSocket.pendingDatagramSize())); - udpSocket.readDatagram(datagram.data(), datagram.size()); - statusLabel->setText(tr("Received datagram: \"%1\"") + + // using QUdpSocket::readDatagram (API since Qt 4) + while (udpSocket4.hasPendingDatagrams()) { + datagram.resize(int(udpSocket4.pendingDatagramSize())); + udpSocket4.readDatagram(datagram.data(), datagram.size()); + statusLabel->setText(tr("Received IPv4 datagram: \"%1\"") .arg(datagram.constData())); } + + // using QUdpSocket::receiveDatagram (API since Qt 5.8) + while (udpSocket6.hasPendingDatagrams()) { + QNetworkDatagram dgram = udpSocket6.receiveDatagram(); + statusLabel->setText(statusLabel->text() + + tr("\nReceived IPv6 datagram from [%2]:%3: \"%1\"") + .arg(dgram.data().constData(), dgram.senderAddress().toString()) + .arg(dgram.senderPort())); + } } diff --git a/examples/network/multicastreceiver/receiver.h b/examples/network/multicastreceiver/receiver.h index 54927fdd63..0325d861df 100644 --- a/examples/network/multicastreceiver/receiver.h +++ b/examples/network/multicastreceiver/receiver.h @@ -71,8 +71,10 @@ private slots: private: QLabel *statusLabel = nullptr; - QUdpSocket udpSocket; - QHostAddress groupAddress; + QUdpSocket udpSocket4; + QUdpSocket udpSocket6; + QHostAddress groupAddress4; + QHostAddress groupAddress6; }; #endif diff --git a/examples/network/multicastsender/sender.cpp b/examples/network/multicastsender/sender.cpp index cb4bf45672..a542a2528f 100644 --- a/examples/network/multicastsender/sender.cpp +++ b/examples/network/multicastsender/sender.cpp @@ -52,11 +52,21 @@ Sender::Sender(QWidget *parent) : QDialog(parent), - groupAddress(QStringLiteral("239.255.43.21")) + groupAddress4(QStringLiteral("239.255.43.21")), + groupAddress6(QStringLiteral("ff12::2115")) { - statusLabel = new QLabel(tr("Ready to multicast datagrams to group %1 on port 45454").arg(groupAddress.toString())); + // force binding to their respective families + udpSocket4.bind(QHostAddress(QHostAddress::AnyIPv4), 0); + udpSocket6.bind(QHostAddress(QHostAddress::AnyIPv6), udpSocket4.localPort()); - auto ttlLabel = new QLabel(tr("TTL for multicast datagrams:")); + QString msg = tr("Ready to multicast datagrams to groups %1 and [%2] on port 45454").arg(groupAddress4.toString()); + if (udpSocket6.state() != QAbstractSocket::BoundState) + msg = tr("IPv6 failed. Ready to multicast datagrams to group %1 on port 45454").arg(groupAddress4.toString()); + else + msg = msg.arg(groupAddress6.toString()); + statusLabel = new QLabel(msg); + + auto ttlLabel = new QLabel(tr("TTL for IPv4 multicast datagrams:")); auto ttlSpinBox = new QSpinBox; ttlSpinBox->setRange(0, 255); @@ -88,7 +98,8 @@ Sender::Sender(QWidget *parent) void Sender::ttlChanged(int newTtl) { - udpSocket.setSocketOption(QAbstractSocket::MulticastTtlOption, newTtl); + // we only set the TTL on the IPv4 socket, as that changes the multicast scope + udpSocket4.setSocketOption(QAbstractSocket::MulticastTtlOption, newTtl); } void Sender::startSending() @@ -101,6 +112,8 @@ void Sender::sendDatagram() { statusLabel->setText(tr("Now sending datagram %1").arg(messageNo)); QByteArray datagram = "Multicast message " + QByteArray::number(messageNo); - udpSocket.writeDatagram(datagram, groupAddress, 45454); + udpSocket4.writeDatagram(datagram, groupAddress4, 45454); + if (udpSocket6.state() == QAbstractSocket::BoundState) + udpSocket6.writeDatagram(datagram, groupAddress6, 45454); ++messageNo; } diff --git a/examples/network/multicastsender/sender.h b/examples/network/multicastsender/sender.h index 5d8769790e..0af6f9aaec 100644 --- a/examples/network/multicastsender/sender.h +++ b/examples/network/multicastsender/sender.h @@ -70,9 +70,11 @@ private slots: private: QLabel *statusLabel = nullptr; QPushButton *startButton = nullptr; - QUdpSocket udpSocket; + QUdpSocket udpSocket4; + QUdpSocket udpSocket6; QTimer timer; - QHostAddress groupAddress; + QHostAddress groupAddress4; + QHostAddress groupAddress6; int messageNo = 1; }; -- cgit v1.2.3