Examples: Update multicast sender and receiver examples for IPv6
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 <marten.nordheim@qt.io> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
This commit is contained in:
parent
c5a3022b04
commit
f9c07da7b6
@ -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()));
|
||||
}
|
||||
}
|
||||
|
@ -71,8 +71,10 @@ private slots:
|
||||
|
||||
private:
|
||||
QLabel *statusLabel = nullptr;
|
||||
QUdpSocket udpSocket;
|
||||
QHostAddress groupAddress;
|
||||
QUdpSocket udpSocket4;
|
||||
QUdpSocket udpSocket6;
|
||||
QHostAddress groupAddress4;
|
||||
QHostAddress groupAddress6;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user