首页 > 解决方案 > UDP 多播是否适用于 VertX 3 中 0.0.0.0 以外的地址

问题描述

问题1:只在使用0.0.0.0地址时有效

我正在尝试使用 Vertx 3.9.2 接收和发送多播消息。我首先尝试按照项目文档中的示例进行操作,但遇到了另一个 SO question 中描述的 NullPointerException 问题。但是,在加入多播组时指定网络接口后,我能够接收多播消息。

socket.listen(5001, "0.0.0.0", handler1 -> {
    if (handler1.succeeded()) {
        socket.listenMulticastGroup("234.3.2.1", "en0", null, handler2 -> {
            LOG.debug("Joined multicast group? {}", handler2.succeeded());
            socket.handler(packet -> LOG.debug("Received packet: {}", packet));
        });
    } else {
        LOG.error("Failure to listen on address", handler1.cause());
    }
});

尽管如此,接收多播消息仅在使用该0.0.0.0地址时才有效。如果我使用任何网络接口的地址,我永远不会收到多播消息。我第一次尝试像:

socket.listen(5001, "192.168.1.10", handler1 -> {
    if (handler1.succeeded()) {
        socket.listenMulticastGroup("234.3.2.1", "en0", null, handler2 -> {
            LOG.debug("Joined multicast group? {}", handler2.succeeded());
            socket.handler(packet -> LOG.debug("Received packet: {}", packet));
        });
    } else {
        LOG.error("Failure to listen on address", handler1.cause());
    }
});

还有这个其他版本:

socket.listen(5001, "192.168.1.10", handler1 -> {
    if (handler1.succeeded()) {
        socket.listenMulticastGroup("234.3.2.1", handler2 -> {
            LOG.debug("Joined multicast group? {}", handler2.succeeded());
            socket.handler(packet -> LOG.debug("Received packet: {}", packet));
        });
    } else {
        LOG.error("Failure to listen on address", handler1.cause());
    }
});

在所有三种情况下,多播组都已成功加入。但是最后两个没有收到多播消息。

问题 2:禁用 Loopback 模式似乎不起作用

我正在使用同一个套接字来读取和写入多播。当我能够接收多播消息(通过绑定到 0.0.0.0)时,我注意到所有写入的消息也会被读取操作接收回来。

这是创建套接字的方式:

Vertx vertx = Vertx.vertx();
DatagramSocket socket = vertx.createDatagramSocket(
    new DatagramSocketOptions()
        .setReuseAddress(true)
        .setReusePort(true)
        .setLoopbackModeDisabled(true)
        .setIpV6(false));

一个有趣的观察是,当绑定到另一个地址(如上面的示例)时,我能够写出多播消息并且这些消息不会“回音”。但是我想知道原因是否是一开始就没有收到多播消息。

这似乎是一个已知问题

我确实在 GitHub中发现了一个似乎与同一问题相关的未解决问题。它指向当前已损坏的链接,但未提供最终解决方案。

我真的希望有人能对此事有所了解。

更新 1

该问题发生在 Docker 中的 Mac OS X Catalina 10.15.5 和 Alpine Linux 3.12 中。

更新 2

listen如果您在呼叫中使用多播地址,接收多播消息也可以工作。

socket.listen(5001, "234.3.2.1", handler1 -> {
    if (handler1.succeeded()) {
        socket.listenMulticastGroup("234.3.2.1", "en0", null, handler2 -> {
            LOG.debug("Joined multicast group? {}", handler2.succeeded());
            socket.handler(packet -> LOG.debug("Received packet: {}", packet));
        });
    } else {
        LOG.error("Failure to listen on address", handler1.cause());
    }
});

但是,当这样调用时,不能使用套接字写入listen

标签: vert.x

解决方案


推荐阅读