Java:使用多个 DatagramSocket 接收 UDP 数据报包

2024-03-20

我正在尝试实现一种将 UDP 数据包发送到多个接收者的方法。我认为这应该是可行的设置setReuseAddress(true)在接收 DatagramSocket 实例上。

我的问题是,在某些情况下,我需要限制与本地计算机的通信 - 因此限制本地主机接口(下面的演示代码中的 useLocalhost=true )。在这种情况下,突然只有第一个接收器套接字收到传入数据包,其他两个套接字看不到任何内容。

我在 Windows(oracle 64 位)和 Linux(OpenJDK 64 位)上对此进行了测试,因此我只看到三种可能性:

  1. 这是一种有意为之且已知的行为(我不理解整个机制 - 又名“我大脑中的错误”)
  2. Java JRE 中存在错误
  3. 我的代码中有一个错误。

有人对此主题有任何经验吗?我可以帮助确定问题所在吗?

请参阅下面的一个最小工作示例来演示这一点。请注意,我使用广播地址来模拟来自真实外部主机的网络数据包。

如果一切顺利,您应该在末尾看到三行(按此顺序或不同的顺序):

Thread-0 - packet received
Thread-1 - packet received
Thread-2 - packet received

 

public static void main(String[] args) throws Exception {

    boolean useLocalhost = true;

    InetSocketAddress addr;
    String sendPacketTo = "192.168.1.255"; // we use broadcast so that packet comes from an real external address
    if (useLocalhost)
        sendPacketTo = "localhost"; // does not work (only listener 1 received packet)

    addr = new InetSocketAddress(15002);

    new MyThread(addr).start(); // Datagram socket listener 1
    new MyThread(addr).start(); // Datagram socket listener 2
    new MyThread(addr).start(); // Datagram socket listener 3

    DatagramSocket so = new DatagramSocket();
    so.setBroadcast(true); // does not change anything
    so.connect(new InetSocketAddress(sendPacketTo, 15002));
    so.send(new DatagramPacket("test".getBytes(), 4));
    Thread.sleep(1000);
    System.exit(0);
}

public static class MyThread extends Thread {

    DatagramSocket socket;

    public MyThread(InetSocketAddress addr) throws SocketException {
        super();
        setDaemon(true);
        socket = new DatagramSocket(null);
        socket.setReuseAddress(true);
        socket.setBroadcast(true); // does not change anything
        socket.bind(addr);
        System.out.println("Listener started: " + socket.getLocalAddress());
    }

    public void run() {
        byte[] buf = new byte[10];
        DatagramPacket p = new DatagramPacket(buf, buf.length);
        try {
            socket.receive(p);
            System.out.println(Thread.currentThread().getName() + " - packet received");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

192.168.1.255是一个广播地址,因此数据报是根据UDP广播规则进行广播的。 127.0.0.1是单播地址,因此数据包是单播的。所以你会得到不同的行为。

正如 @DavidSchwartz 评论的那样,您的代码是一个混合物。例如,连接到广播地址并没有多大意义,绑定到它也没有多大意义。我认为您正在寻找的是多播。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java:使用多个 DatagramSocket 接收 UDP 数据报包 的相关文章

随机推荐

  • 为什么在编程中使用常量? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 从命令行提供当前目录

    有人可以给我一个提示 如何使用 ruby 从命令行提供当前目录吗 如果我可以有一些系统范围的配置 例如 mime 类型 并简单地从每个目录启动它 那就太好了 最简单的方法 谢谢亚伦 帕特森 https twitter com tenderl
  • Firefox 不显示网站图标

    Locked 有对该问题内容的争议 help locked posts此时正在解决 目前不接受新的答案或互动 I DO知道这个问题仅在这个网站上就被问了至少一千次 但我已经阅读了其中的许多主题 我确实认为自己知识渊博 很少问任何事情 而是更
  • 使用 R 和 ggplot 将 y 轴调整为 2x2 ANOVA 条形图时出现问题 [重复]

    这个问题在这里已经有答案了 我不是 Pro R 用户 但我已经尝试了多种方法 但找不到问题的解决方案 我根据此网站创建了 2x2 方差分析的条形图 包括误差线 APA 主题和自定义颜色 https sakaluk wordpress com
  • 获取 ref 参数的地址

    我的代码如下 class MyClass static int iField 42 static void Test ref int arg unsafe fixed void pField iField fixed void pArg a
  • 模拟授权属性的存在

    我想知道如何在 MVC3 中模拟使用 Authorize 属性装饰控制器 我正在使用自定义会员资格提供商 我想测试一个控制器是否已用该属性装饰 并且您已获得授权 以及如果您没有获得授权 会发生什么情况 我正在使用起订量 这方面有什么好的建议
  • C++中对象的动态初始化是什么?

    C 中对象的动态初始化是什么 请用一个简单的例子来解释 动态初始化是指编译时初始化值未知的初始化 它在运行时计算以初始化变量 Example int factorial int n if n lt 0 return 1 indicates
  • Numpy - ImportError:无法导入名称 _distributor_init

    我一直在使用matplotlib from python和spyder ide为出版物创建一些数据 它总是有效 但即使在使用 Linux 多年之后 整个事情对我来说仍然是一个黑匣子 昨天我尝试运行另一个应用程序 它抱怨说numpy and
  • 空对象引用上的“boolean java.lang.Class.isInterface()”

    我在 Android 13 上遇到此崩溃 代码如下 Caused by java lang NullPointerException Attempt to invoke virtual method boolean java lang Cl
  • InvalidArgument=值“0”对于“SelectedIndex”无效

    我正在 NET 4 0 中开发 Windows 窗体应用程序 当我将数据绑定到BindingSource 其中一个ComboBox已绑定 我得到以下异常 注意 只有当我让调试器在抛出异常 未处理或已处理 时停止时 我才会得到它 因此 异常在
  • 旋转时碎片不会被破坏

    我有一个以编程方式添加的片段 然而 我发现在旋转之后 会创建一个新片段 但旧片段仍然存在 尽管没有显示 我假设片段会随着旋转活动而被销毁 但这里的情况并非如此 是什么导致我的片段被保留 未被破坏 请注意 我没有设置 setRetainIns
  • 从 'System.Int32' 到 'System.Nullable`1[[System.Int32, mscorlib]] 的强制转换无效

    Type t typeof int will get this dynamically object val 5 will get this dynamically object nVal Convert ChangeType val t
  • 如何一次刷新Postgresql 9.3中的所有物化视图?

    我正在将一堆数据加载到 PostgresQL 9 3 数据库中 然后我想刷新依赖于更新表的所有物化视图 有没有一种方法可以自动执行此操作 而不是逐一浏览每个视图并刷新它们 我知道 Oracle 可以很容易地做到这一点 但在梳理 Postgr
  • 使用单选按钮组打破键盘焦点

    这看起来很简单 但这对我来说有点令人头疼 给出以下 有效的 xhtml 过渡 代码
  • Angular CLI 将 font-awesome 字体文件输出到 dist root

    你一定要吗eject你的 angular cli 并覆盖 webpack 配置以放置font awesome字体放入 asset fonts 文件夹中 我有这个 angular cli 并且我以这种方式将 font awesome 包含在我
  • Python 特征向量

    eigenvalues eigenvectors linalg eig K 我怎样才能只打印特征向量len K 所以如果有K 2x2矩阵 我得到4个特征向量 如果有的话我怎样才能只打印其中2个len K 2 非常感谢 您将得到两个长度为 2
  • LLVM环境变量在哪里或者LLVM环境是如何配置的?

    作为上下文 我有一台 Mac 我在工作中使用它使用各种自定义构建脚本进行开发 我现在尝试使用同一台机器来玩一些个人 Xcode 项目 第一步 我在 Xcode 11 3 1 中创建一个新的 Single View App 项目 并尝试在我连
  • C# 中的内存使用情况

    我有一个在 C 中使用线程的程序 有没有办法以编程方式了解应用程序的内存使用情况 我想将线程的产生限制为 10 MB 内存 我该怎么做 如果您想要整个正在运行的进程的内存而不是每个线程的内存 那么 get the current proce
  • 用于出版质量图的 Python Pylab pcolor 选项

    我正在尝试使用 DFT 离散傅立叶变换 图pcolor在Python中 我之前一直使用 Mathematica 8 0 来执行此操作 但我发现 Mathematica 8 0 中的颜色条与我尝试表示的数据具有不良的一对一相关性 例如 这是我
  • Java:使用多个 DatagramSocket 接收 UDP 数据报包

    我正在尝试实现一种将 UDP 数据包发送到多个接收者的方法 我认为这应该是可行的设置setReuseAddress true 在接收 DatagramSocket 实例上 我的问题是 在某些情况下 我需要限制与本地计算机的通信 因此限制本地