Qt多播可以在Windows和Mac之间工作,但不能在其他平台上工作

Qt多播可以在Windows和Mac之间工作,但不能在其他平台上工作,qt,networking,multicast,Qt,Networking,Multicast,我使用一个实验项目来测试Qt多播。它就像本地网络中的一个简单聊天程序。我可以从Windows向Mac发送消息,但不能从Mac向Windows发送消息。请参阅Multicast.cpp中的注释 它们都加入一个预定义的组。我使用了一些硬编码的IP来查找要绑定到的相应接口。我还使用netstat和netsh检查了两个平台上的多播组,它在两侧显示了预定义的组 这不是防火墙问题,因为我关闭了它,问题仍然存在 编辑:使用wireshark监控流量,来自Mac的消息将到达Windows 编辑:刚刚在Windo

我使用一个实验项目来测试Qt多播。它就像本地网络中的一个简单聊天程序。我可以从Windows向Mac发送消息,但不能从Mac向Windows发送消息。请参阅Multicast.cpp中的注释

它们都加入一个预定义的组。我使用了一些硬编码的IP来查找要绑定到的相应接口。我还使用netstat和netsh检查了两个平台上的多播组,它在两侧显示了预定义的组

这不是防火墙问题,因为我关闭了它,问题仍然存在

编辑:使用wireshark监控流量,来自Mac的消息将到达Windows

编辑:刚刚在Windows上找到绑定到interface 4 Ethernet的多播组。但我的程序多播接口输出8个局域网连接。 Qt版本:5.5

问题:我是否需要两个单独的插座来分别接收和发送

有什么建议我下一步应该做什么来诊断这个问题吗

netsh输出:

C:\Users\Jerry>netsh interface ip show joins

Interface 1: Loopback Pseudo-Interface 1

Scope       References  Last  Address
----------  ----------  ----  ---------------------------------
0                    1  Yes   224.0.0.251
0                    4  Yes   239.255.255.250

Interface 4: Ethernet

Scope       References  Last  Address
----------  ----------  ----  ---------------------------------
0                    0  Yes   224.0.0.1
0                    2  Yes   224.0.0.251
0                    1  Yes   224.0.0.252
0                    0  Yes   239.255.43.21
0                    4  Yes   239.255.255.250

Interface 8: Local Area Connection

Scope       References  Last  Address
----------  ----------  ----  ---------------------------------
0                    0  Yes   224.0.0.1
0                    2  Yes   224.0.0.251
0                    1  Yes   224.0.0.252
0                    4  Yes   239.255.255.250
netstat输出

eve:~ Jerry$ netstat -g
Link-layer Multicast Group Memberships
Group                   Link-layer Address  Netif
1:0:5e:7f:2b:15         <none>              en0
1:0:5e:0:0:fb           <none>              en0
1:0:5e:0:0:1            <none>              en0
33:33:ff:c9:32:14       <none>              en0
33:33:0:0:0:fb          <none>              en0
33:33:ff:41:27:e        <none>              en0
33:33:0:0:0:1           <none>              en0
33:33:ff:33:5b:7a       <none>              en0
1:80:c2:0:0:3           <none>              en0
33:33:0:0:0:fb          <none>              en1
1:3:93:df:b:92          <none>              en1
33:33:0:0:0:fb          <none>              awdl0
33:33:80:0:0:fb         <none>              awdl0

IPv4 Multicast Group Memberships
Group                   Link-layer Address  Netif
224.0.0.251             <none>              lo0
224.0.0.1               <none>              lo0
239.255.43.21           1:0:5e:7f:2b:15     en0
224.0.0.251             1:0:5e:0:0:fb       en0
224.0.0.1               1:0:5e:0:0:1        en0

IPv6 Multicast Group Memberships
Group                   Link-layer Address  Netif
ff02::fb%lo0            <none>              lo0
ff02::2:ff33:9cc0%lo0   <none>              lo0
ff01::1%lo0             <none>              lo0
ff02::1%lo0             <none>              lo0
ff02::1:ff00:1%lo0      <none>              lo0
ff02::1:ffc9:3214%en0   33:33:ff:c9:32:14   en0
ff02::fb%en0            33:33:0:0:0:fb      en0
ff01::1%en0             33:33:0:0:0:1       en0
ff02::2:ff41:270e%en0   33:33:ff:41:27:e    en0
ff02::1%en0             33:33:0:0:0:1       en0
ff02::1:ff33:5b7a%en0   33:33:ff:33:5b:7a   en0
ff02::fb%en1            33:33:0:0:0:fb      en1
ff02::fb%awdl0          33:33:0:0:0:fb      awdl0

原因是VirtualBox网卡窃取多播。这是VirtualBox中的一个已知问题

禁用网络接口或在“设置”中设置一个高值可以解决此问题

现在我需要找出在特定接口上绑定套接字是否可行。但我想这将是一个单独的问题

#ifndef MULTICAST_H
#define MULTICAST_H

#include <QQuickItem>
#include <QHostAddress>
#include <QNetworkInterface>

class QUdpSocket;

class Multicast : public QQuickItem
{
    Q_OBJECT
public:
    Multicast();

    Q_INVOKABLE void multicast(QString s);

signals:
    void messageAdded(const QString msg);

private slots:
    void processPendingDatagrams();

private:
    QNetworkInterface getNetworkInterfaceByAddress(QString adr);
    void printNetworkInterfaceInfo(QNetworkInterface ni);
private:
    QHostAddress groupAddress;
    QUdpSocket *udpSocket;
};

#endif // MULTICAST_H
#include "multicast.h"

#include <QtNetwork>

Multicast::Multicast()
{
    // hard coded group
    groupAddress = QHostAddress("239.255.43.21");
    udpSocket = new QUdpSocket(this);

    udpSocket->bind(QHostAddress::AnyIPv4, 45454, QUdpSocket::ShareAddress);
    // hard coded IP to find network interface. 10.0.1.40 for the other devices
    // if I don't manually set this interface, and set loopback to 1, 
    // this can receive the message from itself. Otherwise, it receives
    // nothing.
    udpSocket->setMulticastInterface(getNetworkInterfaceByAddress("10.0.1.39"));
    bool r = udpSocket->joinMulticastGroup(groupAddress);
    udpSocket->setSocketOption(QAbstractSocket::MulticastLoopbackOption, QVariant(1));
    QNetworkInterface intf(udpSocket->multicastInterface());
    printNetworkInterfaceInfo(intf);

    connect(udpSocket, SIGNAL(readyRead()),
            this, SLOT(processPendingDatagrams()));
}

QNetworkInterface Multicast::getNetworkInterfaceByAddress(QString adr)
{
    QList<QNetworkInterface> il(QNetworkInterface::allInterfaces());
    for (int i = 0; i < il.size(); i++)
    {
        QList<QNetworkAddressEntry> ade(il[i].addressEntries());
        for (int j = 0; j < ade.size(); j++)
        {
            if (ade[j].ip().toString() == adr)
                return il[i];
        }
    }

    return QNetworkInterface();
}

void Multicast::printNetworkInterfaceInfo(QNetworkInterface ni)
{
    qDebug() << ni.index() << ni.humanReadableName();
    QList<QNetworkAddressEntry> ade(ni.addressEntries());
    for (int j = 0; j < ade.size(); j++)
        qDebug() << ade[j].ip();
}

void Multicast::multicast(QString msg)
{
    QByteArray datagram = msg.toUtf8();
    udpSocket->writeDatagram(datagram.data(), datagram.size(),
                             groupAddress, 45454);
}

void Multicast::processPendingDatagrams()
{
    while (udpSocket->hasPendingDatagrams()) {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());
        udpSocket->readDatagram(datagram.data(), datagram.size());
        QString data(datagram);
        emit messageAdded(data);
    }
}
#include <QApplication>
#include <QQmlApplicationEngine>

#include "multicast.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    qmlRegisterType<Multicast>("com.multicast.test", 1, 0, "Multicast");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}
import QtQuick 2.3
import QtQuick.Controls 1.2


import com.multicast.test 1.0

ApplicationWindow {
    id: applicationWindow1
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Multicast {
        id : multicast
    }

    menuBar: MenuBar {
        Menu {
            title: qsTr("File")
            MenuItem {
                text: qsTr("&Open")
                onTriggered: console.log("Open action triggered");
            }
            MenuItem {
                text: qsTr("Exit")
                onTriggered: Qt.quit();
            }
        }
    }

     TextInput {
         id: textInput1
         y: 57
         width: 450
         height: 20
         text: qsTr("Text Input")
         anchors.left: parent.left
         anchors.leftMargin: 50
         font.pixelSize: 12
     }

     Button {
         id: button1
         y: 57
         text: qsTr("Button")
         anchors.left: textInput1.right
         anchors.leftMargin: 20

         onClicked: {
            textEdit1.append(textInput1.text)
            multicast.multicast(textInput1.text)
            textInput1.text = ""
         }
     }

     TextEdit {
         id: textEdit1
         y: 106
         height: 327
         readOnly: true
         anchors.left: parent.left
         anchors.leftMargin: 50
         anchors.right: parent.right
         anchors.rightMargin: 50
         font.pixelSize: 12

         Connections {
            target: multicast
            onMessageAdded: {
                textEdit1.append(msg)
            }
        }
    }
}