1

在 Windows 中,我有两个物理接口。在每个接口上设置两个 IP 地址:IPv4 和 IPv6。以下代码在此配置中不正确工作:joinMulticastGroup仅对第一个接口返回true ,对于下一个接口joinMulticastGroup返回false

但是,如果我在 Windows 接口上关闭 IPv6,则此代码可以正常工作。

帮我理解。

QUdpSocket udpSocket;
QHostAddress groupAddress;

groupAddress = QHostAddress("239.255.255.250");
udpSocket.bind(QHostAddress::AnyIPv4, 1900,
                QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);

QList<QNetworkInterface> mListIfaces = QNetworkInterface::allInterfaces();

for (int i = 0; i < mListIfaces.length(); ++i) {
    bool rez = udpSocket.joinMulticastGroup(groupAddress, mListIfaces.at(i));
    qDebug() << rez;
}
4

3 回答 3

2

我最近在处理多播和 Qt,而 Qt 5.6 和 Win7 似乎仍然存在这个问题。

问题是joinMulticastGroup()使用接口的第一个地址而不检查它是 IPV4 还是 IPV6(即使您在绑定中使用 AnyIpv4)。

这个问题在官方 Qt 版本中没有得到修复,但建议的补丁对我有用:

https://bugreports.qt.io/browse/QTBUG-27641

于 2016-05-22T17:36:46.203 回答
1

尝试阅读 isValid() 并最终

QNetworkInterface::CanMulticast从接口标志和检查 QNetworkInterface::IsRunning并没有 QNetworkInterface::IsLoopBack.

进一步检查关联的addresses()IPv4QNetworkAddressEntry::ip().protocol() == QAbstractSocket::IPv4Protocol

于 2013-10-07T07:59:18.837 回答
1

因此,对于可能对其他人有所帮助的工作示例,请在下面找到在带有 Qt 5.15.0 MinGW 的 Win10 Pro 64 位中的工作原理。本质上,获取接口列表,然后循环遍历这些接口并通过测试标志和函数丢弃不应使用的isValid()接口。

在我的示例中,我只想加入我最初的 QUDPSocket 绑定调用的 IP 地址。如果您愿意,if/then 过滤器是可选的,它会导致加入该接口上的所有有效地址。

// Windows is weird
QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
// Try the multicast UDP socket for SA first
saMC = new QUdpSocket(this);
saMC->setSocketOption(QAbstractSocket::LowDelayOption, 1);
//saMC->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
connect(saMC, &QUdpSocket::readyRead, this, &Commander::handleDatagram, Qt::UniqueConnection);
QHostAddress toBind("192.168.0.51");
if(saMC->bind(toBind, 6969, QUdpSocket::ShareAddress|QUdpSocket::ReuseAddressHint))
{
    foreach(QNetworkInterface interface, interfaces)
    {
        //qDebug()<<"interface:"<<interface.isValid()<<interface.flags();
        QNetworkInterface::InterfaceFlags iflags = interface.flags();
        if(interface.isValid() && !iflags.testFlag(QNetworkInterface::IsLoopBack) && iflags.testFlag(QNetworkInterface::CanMulticast) && iflags.testFlag(QNetworkInterface::IsRunning))
        {

            QList<QNetworkAddressEntry> addressEntries = interface.addressEntries();
            for (int i = 0; i < addressEntries.length(); i++) {
                QNetworkAddressEntry ae = addressEntries.at(i);
                if(ae.ip() == toBind)
                {
                    bool ok = false;
                    if (ae.ip().protocol() == QAbstractSocket::IPv4Protocol)
                    {
                        ok = saMC->joinMulticastGroup(QHostAddress("239.2.3.1"), interface);
                    }
                    if(ok)
                    {
                        qDebug()<<"SA bound...join mc group:"<<ae.ip();
                    }
                    else
                    {
                        qDebug()<<"SA bound...interface unsuitable for Multicast:"<<ae.ip();
                    }
                }
            }
        }
    }
}
else
{
    qDebug()<<"SA multicast socket unable to bind...."<<saMC->errorString();
}
于 2021-09-23T18:44:52.117 回答