2011-03-29 12 views
5

He escrito la clase de prueba sencilla que está destinado a escuchar en Eth y recibir todos los UDP paquetes, que van al puerto 5001:Java DatagramSocket escucha en una dirección de difusión

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

Es ya no funciona . Imprime Waiting for data y nunca continúa. tcpdump me muestra que vienen los paquetes de difusión UDP. ¿Qué estoy haciendo mal? Muchas gracias

+0

¿Por casualidad trabaja en el campo c2x? – nyyrikki

Respuesta

12

El receptor no puede escuchar en una dirección de difusión.

La dirección de difusión es para remitentes: el remitente puede enviar un paquete con 255.255.255.255:5001 como destino, y todos los receptores que escuchan ese puerto en una subred lo recibirán. Pero no hay forma de crear un receptor que pueda recibir "todos los paquetes UDP".

Si ya tiene un emisor de radiodifusión y desea recibir sus paquetes, tiene que escuchar en una dirección comodín en su lugar:

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

No estoy de acuerdo con la forma en que no se puede obtener todo el tráfico UDP. Busque "Wireshark": puede escuchar todo el tráfico de la red en cualquier interfaz de su computadora ... Sin perturbar el tráfico. Como existe y funciona, tiene que haber * a * way –

+0

. Hay formas, pero no sin utilizar bibliotecas nativas fuera de la API de Java. Vea mi respuesta sobre Jpcap para más detalles. –

1

La toma DatagramSocket que envíe el debe estar vinculado a un puerto (5001) usando

socket = new DatagramSocket(5001); 

a continuación, cuando se envía en esta toma, utilice

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

Luego, cuando se escucha en el otro conector, utilice

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

y se puede escuchar a los datos UDP que se envía al puerto 5001, en el puerto 5001. No sé por qué, es algo que ver con la mesa de fresado InetAddress utilizando diferentes IP direcciones subredes para la misma dirección 127.0.0.1?

0

No puede hacer esto en Java puro, porque necesita poner la interfaz de red en "modo promiscuo" y la API de Java no incluye ninguna forma de hacerlo. Sin embargo, hay bibliotecas que pueden ayudar. Jpcap parece una muy prometedora. Techrepublic escribió un breve intro sobre cómo usarlo, aunque parece un poco anticuado porque afirma que la biblioteca solo funciona para Windows y Linux, mientras que la página Jpcap también menciona soporte para MacOS.

Cuestiones relacionadas