Java DatagramSocket listening on a broadcast addre

2019-04-07 15:28发布

I have written the simple test class which is meant to listen on Eth and receive all UDP packets, which go to port 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");
    }
  }
}

It does not work anymore. It prints out Waiting for data and never continue. tcpdump shows me, that UDP broadcast packets come. What am I doing wrong? Thank you much.

3条回答
仙女界的扛把子
2楼-- · 2019-04-07 15:58

The DatagramSocket socket that you send on must be bound to a port (5001) using

socket = new DatagramSocket(5001);

Then when you send on this socket, use

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

Then when you listen on another socket, use

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

and you can listen to UDP data that you sent to port 5001, on port 5001. Not sure why, it's something to do with InetAddress router table using different IP address subnets for the same 127.0.0.1 address?

查看更多
戒情不戒烟
3楼-- · 2019-04-07 16:03

Receiver can't listen on a broadcast address.

Broadcast address is for senders - sender can send a packet with 255.255.255.255:5001 as a destination, and all receivers listening that port in a subnet would receive it. But there is no way to create a receiver that can receive "all UDP packets".

If you already have a broadcast sender and want to receive its packets, you need to listen on a wildcard address instead:

DatagramSocket socket = new DatagramSocket(5001, InetAddress.getByName("0.0.0.0")); 
查看更多
趁早两清
4楼-- · 2019-04-07 16:10

You can’t do this in pure Java, because you need to put the network interface in “promiscuous mode” and the Java API does not include any way to do this. There are, however, libraries that can help. Jpcap looks like a very promising one. Techrepublic wrote a short intro on how to use it, though it looks a bit dated because it claims the library only works for Windows and Linux, while the Jpcap page itself mentions support for MacOS as well.

查看更多
登录 后发表回答