Qt多播可以在Windows和Mac之间工作,但不能在其他平台上工作
我使用一个实验项目来测试Qt多播。它就像本地网络中的一个简单聊天程序。我可以从Windows向Mac发送消息,但不能从Mac向Windows发送消息。请参阅Multicast.cpp中的注释 它们都加入一个预定义的组。我使用了一些硬编码的IP来查找要绑定到的相应接口。我还使用netstat和netsh检查了两个平台上的多播组,它在两侧显示了预定义的组 这不是防火墙问题,因为我关闭了它,问题仍然存在 编辑:使用wireshark监控流量,来自Mac的消息将到达Windows 编辑:刚刚在Windows上找到绑定到interface 4 Ethernet的多播组。但我的程序多播接口输出8个局域网连接。 Qt版本:5.5 问题:我是否需要两个单独的插座来分别接收和发送 有什么建议我下一步应该做什么来诊断这个问题吗 netsh输出:Qt多播可以在Windows和Mac之间工作,但不能在其他平台上工作,qt,networking,multicast,Qt,Networking,Multicast,我使用一个实验项目来测试Qt多播。它就像本地网络中的一个简单聊天程序。我可以从Windows向Mac发送消息,但不能从Mac向Windows发送消息。请参阅Multicast.cpp中的注释 它们都加入一个预定义的组。我使用了一些硬编码的IP来查找要绑定到的相应接口。我还使用netstat和netsh检查了两个平台上的多播组,它在两侧显示了预定义的组 这不是防火墙问题,因为我关闭了它,问题仍然存在 编辑:使用wireshark监控流量,来自Mac的消息将到达Windows 编辑:刚刚在Windo
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)
}
}
}
}