DatagramSocket 广播行为(Windows 与 Linux)

Posted

技术标签:

【中文标题】DatagramSocket 广播行为(Windows 与 Linux)【英文标题】:DatagramSocket Broadcast Behavior (Windows vs. Linux) 【发布时间】:2013-05-14 23:35:08 【问题描述】:

背景故事: 我有一个无线设备,它创建自己的 SSID,使用自动 IP 为自己分配一个 IP 地址,并开始向 255.255.255.255 广播发现信息。 (不幸的是,它不容易支持多播)

我要做什么: 我需要能够接收发现信息,然后将配置信息发送到设备。问题是,使用自动 ip,“IP 协商”过程在 Windows 等上可能需要几分钟(在此期间我可以看到广播,甚至可以将广播信息发送回设备)。

所以我枚举了所有连接的网络接口(无法直接判断哪个将用于与设备通信),为它们的每个地址创建一个 DatagramSocket,然后开始监听。如果我通过特定套接字接收发现信息,我知道我可以使用同一个套接字将数据发送回设备。 这适用于 Windows。

问题: 在 Linux 和 OSX 上,以下代码不接收广播数据包:

byte[] addr = (byte)169, (byte)254, (byte)6, (byte)215;  
DatagramSocket foo = new DatagramSocket(new InetSocketAddress(InetAddress.getByAddress(addr), PORT_NUM));  
while (true)  
  
byte[] buf = new byte[256];  
DatagramPacket pct = new DatagramPacket(buf, buf.length);  
foo.receive(pct);  
System.out.println( IoBuffer.wrap(buf).getHexDump() );  

为了接收广播数据包(在 Linux/OSX 上),我需要使用以下命令创建我的 DatagramSocket:DatagramSocket foo = new DatagramSocket(PORT_NUM);

但是,当我随后使用此套接字将数据发送回设备时,数据包由操作系统路由(我假设)并且由于感兴趣的接口可能在中间自动ip协商,失败。

有以下想法吗?

如何在 Linux/OSX 上实现“正常工作”的 Windows 行为 处理此过程的更好方法

提前致谢!

【问题讨论】:

我不明白你的 Linux 机器的网络接口会如何“在自动 IP 协商中”,那台机器是如何获得它的 IP 地址的?静态还是 DHCP?机器的IP地址应该独立于无线设备吗?还是您所有的机器都通过自动 IP 获取 IP 地址?自动ip真的是en.wikipedia.org/wiki/Zero-configuration_networking吗? @HeatfanJohn 我相信 auto-IP(自动私有 IP 寻址 (APIPA))和 ZeroConf 是一回事。在 IP 协商过程中,操作系统会随机选择 IP 地址并进行探测,以确保没有冲突。该过程可能需要几分钟。在此期间,我仍然可以使用该接口发送和接收广播如果我正在使用之前绑定的套接字。但是,使用“通配符”DatagramSocket,操作系统不会将数据包路由到此设备。 【参考方案1】:

我不认为这是代码的问题。您是否检查过 OSX/Linux 是否正确允许这些地址/端口号通过其防火墙?我过去也遇到过这个简单的问题=P..

仅供参考,有一种名为零配置的好技术就是为了解决这个问题而构建的。它很容易学习,所以我建议你也看看它。

祝你好运。

【讨论】:

我希望我可以使用 ZeroConf!不幸的是,该设备不支持那种东西。我知道防火墙设置很好,因为当我用通配符实例替换 DatagramSocket 实例时,我可以看到广播。

以上是关于DatagramSocket 广播行为(Windows 与 Linux)的主要内容,如果未能解决你的问题,请参考以下文章

使用MulticastSocket实现多点广播

连接到广播IP地址

Flink 的广播状态行为

发送广播消息时的奇怪行为

洪泛和广播的区别

Java使用DatagramSocket