windows - Windows 上通过 QUdpSocket 的链路本地多播

标签 windows qt udp ipv6 multicast

我正在尝试使用链路本地多播发送 UDP 电报。我正在使用提供 QUdpSocket 的 Qt。我能够在 Linux 上执行此操作,但无法让代码在 Windows 上运行。

我的第一个代码如下所示:

udp.writeDatagram(QByteArray("hello world"), QHostAddress("FF02::1"), 4321);

它可以在 Linux 上运行,但不能在 Windows 上运行。我什至尝试使用管理员权限运行该应用程序。 writeDatagram() 返回两个系统上电报的大小。

我发现的唯一建议是在特定的网络接口(interface)上发送电报。我的这种方法的代码:

foreach(const QHostAddress& address, QNetworkInterface::allAddresses()) {
    udp.bind(address, 0);

    if(address.protocol() == QAbstractSocket::IPv6Protocol) {
        udp.writeDatagram(data, QHostAddress("FF02::1"), 4321);
    }

    udp.close();
}

该代码再次在 Linux 上发送电报,但不在 Windows 上发送电报。 allAddresses() 返回两个操作系统上的 IPv6 链路本地地址。

QUdpSocket::joinMulticastGroup() 也没有执行任何操作(如预期,因为它只涉及接收)。

我使用 Wireshark(在发送机器和网络中的另一台机器上)检查电报是否已发送。为了检查网络代码是否有效,我添加了一个 IPv4 广播,它可以在 Windows 上使用这两种解决方案。我知道我的 Windows 支持 IPv6,因为它有一个链接本地地址。 Windows 防火墙在测试期间被禁用,并且我在测试系统上没有安装其他防火墙。完整的测试代码可以参见 here in a Gist .

为什么Windows拒绝发送电报?我的代码是否缺少某些内容或者 Qt 中存在错误?有人让它发挥作用吗?请帮忙。

最佳答案

第二种方法是正确的。在 close() 之后,我必须再次 open() 套接字。我想我认为这是在 bind() 中完成的,因为套接字在创建对象后打开......

工作代码:

foreach(const QHostAddress& address, QNetworkInterface::allAddresses()) {
    if(address.protocol() == QAbstractSocket::IPv6Protocol) {
        _udp.bind(address, 0);
        _udp.writeDatagram(data, QHostAddress("FF02::1"), DISCO_PORT);

        _udp.close();
        _udp.open(QUdpSocket::ReadWrite);
    }

}

关于windows - Windows 上通过 QUdpSocket 的链路本地多播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25695503/

相关文章:

.net - 使用后删除临时文件

c# - 从 linq 查询突出显示 ListView 中的文本

c++ - Qt - 将 QString 路径保存到注册表中的 QSettings

c++ - 当给定索引处的列尚未创建时,setSectionResizeMode() 崩溃

windows - 为什么在 asyncio 事件循环运行时我无法捕获 SIGINT?

c++ - 使用 C++ Lambda 函数作为 Qt 中的槽是否有助于保持库的二进制兼容性?

Java nio udp广播

c++ - 在哪种情况下 UDP 套接字上的 sendto() 返回 0?

c++ - epoll 对 udp 客户端来说是个坏主意吗?

c++ - 如何在 Windows 中比较可能的替代文件名?