开发者

Java DatagramSocket listening on a broadcast address

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 nev开发者_StackOverflower continue. tcpdump shows me, that UDP broadcast packets come. What am I doing wrong? Thank you much.


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")); 


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?


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜