我正在尝试实现一种将 UDP 数据包发送到多个接收者的方法。我认为这应该是可行的设置setReuseAddress(true)
在接收 DatagramSocket 实例上。
我的问题是,在某些情况下,我需要限制与本地计算机的通信 - 因此限制本地主机接口(下面的演示代码中的 useLocalhost=true )。在这种情况下,突然只有第一个接收器套接字收到传入数据包,其他两个套接字看不到任何内容。
我在 Windows(oracle 64 位)和 Linux(OpenJDK 64 位)上对此进行了测试,因此我只看到三种可能性:
- 这是一种有意为之且已知的行为(我不理解整个机制 - 又名“我大脑中的错误”)
- Java JRE 中存在错误
- 我的代码中有一个错误。
有人对此主题有任何经验吗?我可以帮助确定问题所在吗?
请参阅下面的一个最小工作示例来演示这一点。请注意,我使用广播地址来模拟来自真实外部主机的网络数据包。
如果一切顺利,您应该在末尾看到三行(按此顺序或不同的顺序):
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(使用前将#替换为@)