首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Qt多播从Windows到Mac都能工作,但不适用于其他

Qt多播从Windows到Mac都能工作,但不适用于其他
EN

Stack Overflow用户
提问于 2016-01-13 22:37:42
回答 1查看 376关注 0票数 0

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

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

这不是防火墙问题,因为我关闭了它,并且问题持续存在。

编辑:使用wireshark来监控流量,来自Mac的消息在上到达。

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

问题:,我是否需要两个单独的套接字来接收和发送?

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

netsh输出:

代码语言:javascript
复制
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输出

代码语言:javascript
复制
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

这是源代码

Multicast.h

代码语言:javascript
复制
#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

Multicast.cpp

代码语言:javascript
复制
#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);
    }
}

main.cpp

代码语言:javascript
复制
#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();
}

main.qml

代码语言:javascript
复制
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)
            }
        }
    }
}
EN

回答 1

Stack Overflow用户

发布于 2016-01-14 23:40:08

原因是VirtualBox网卡盗取multicasting.This是VirtualBox中的一个已知问题。

禁用网络接口或在设置中设置一个较高的设置可以解决此问题。

现在,我需要了解在特定接口上绑定套接字是否可行。但我想这将是另一个问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34778407

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档