监听广播地址的Java DatagramSocket

时间:2011-03-29 12:11:47

标签: java broadcast

我编写了一个简单的测试类,用于侦听Eth并接收所有 UDP 数据包,这些数据包将转到端口5001

public class Main {

  public static void main(String[] args) throws SocketException, UnknownHostException, IOException {
    DatagramSocket socket = new DatagramSocket(5001, InetAddress.getByName("255.255.255.255"));
    socket.setBroadcast(true);
    System.out.println("Listen on " + socket.getLocalAddress() + " from " + socket.getInetAddress() + " port " + socket.getBroadcast());
    byte[] buf = new byte[512];
    DatagramPacket packet = new DatagramPacket(buf, buf.length);
    while (true) {
      System.out.println("Waiting for data");
      socket.receive(packet);
      System.out.println("Data received");
    }
  }
}

它不再起作用了。它打印出Waiting for data并且永远不会继续。 tcpdump告诉我,UDP广播包来了。我究竟做错了什么?非常感谢。

3 个答案:

答案 0 :(得分:15)

接收方无法收听广播地址。

广播地址用于发件人 - 发件人可以发送一个255.255.255.255:5001作为目的地的数据包,并且监听子网中该端口的所有接收者都会收到它。但是没有办法创建一个可以接收“所有UDP数据包”的接收器。

如果您已有广播发送者并希望接收其数据包,则需要收听通配符地址:

DatagramSocket socket = new DatagramSocket(5001, InetAddress.getByName("0.0.0.0")); 

答案 1 :(得分:1)

您发送的DatagramSocket套接字必须使用

绑定到端口(5001)
socket = new DatagramSocket(5001);

然后当您发送此套接字时,请使用

InetAddress sendAddress = InetAddress.getByName("127.0.0.1");
DatagramPacket packet = new DatagramPacket(buf, buf.length, sendAddress, socket.getLocalPort());
socket.send(packet);  

然后当您在另一个套接字上收听时,请使用

DatagramSocket socket = new DatagramSocket(5001, InetAddress.getByName("127.0.0.1"));

你可以在端口5001上收听你发送到端口5001的UDP数据。不知道为什么,它与使用不同IP地址子网的InetAddress路由器表相同的127.0.0.1地址有关吗?

答案 2 :(得分:0)

您不能在纯Java中执行此操作,因为您需要将网络接口置于“混杂模式”,并且Java API不包含任何方法来执行此操作。但是,有些库可以提供帮助。 Jpcap看起来非常有前途。 Techrepublic写了一篇关于如何使用它的简短intro,虽然它看起来有点陈旧,因为它声称该库仅适用于Windows和Linux,而Jpcap页面本身也提到了对MacOS的支持。