|
Trabajando con Sockets UDP |
|
En esta práctica veremos como da soporte Java a UDP, tanto para envío
unicast, como multicast. Al ir avanzado en los ejercicios, fijaros en
las diferencias que existen entre enviar datos utilizando el protocolo
UDP y el protocolo TCP.
OBLIGATORIO ENTREGAR EL EJERCICIO 3 |
|||
|
Java proporciona tres clases para dar soporte a la comunicación via datagramas UDP, todas ellas contenidas en el paquete java.net. Estas clases son DatagramSocket, DatagramPacket y MulticastSocket DatagramaPacket y DatagramSocket
Analizad el siguiente código del cliente ClienteUDP.java: import java.net.*; import java.io.*; public class ClienteUDP { // Los argumentos proporcionan el mensaje y el nombre del servidor public static void main(String args[]) { try { DatagramSocket socketUDP = new DatagramSocket(); byte[] mensaje = args[0].getBytes(); InetAddress hostServidor = InetAddress.getByName(args[1]); int puertoServidor = 6789; // Construimos un datagrama para enviar el mensaje al servidor DatagramPacket peticion = new DatagramPacket(mensaje, args[0].length(), hostServidor, puertoServidor); // Enviamos el datagrama socketUDP.send(peticion); // Construimos el DatagramPacket que contendrá la respuesta byte[] bufer = new byte[1000]; DatagramPacket respuesta = new DatagramPacket(bufer, bufer.length); socketUDP.receive(respuesta); // Enviamos la respuesta del servidor a la salida estandar System.out.println("Respuesta: " + new String(respuesta.getData())); // Cerramos el socket socketUDP.close(); } catch (SocketException e) { System.out.println("Socket: " + e.getMessage()); } catch (IOException e) { System.out.println("IO: " + e.getMessage()); } } } Analizad el siguiente código del servidor ServidorUDP.java: import java.net.*; import java.io.*; public class ServidorUDP { public static void main (String args[]) { try { DatagramSocket socketUDP = new DatagramSocket(6789); byte[] bufer = new byte[1000]; while (true) { // Construimos el DatagramPacket para recibir peticiones DatagramPacket peticion = new DatagramPacket(bufer, bufer.length); // Leemos una petición del DatagramSocket socketUDP.receive(peticion); System.out.print("Datagrama recibido del host: " + peticion.getAddress()); System.out.println(" desde el puerto remoto: " + peticion.getPort()); // Construimos el DatagramPacket para enviar la respuesta DatagramPacket respuesta = new DatagramPacket(peticion.getData(), peticion.getLength(), peticion.getAddress(), peticion.getPort()); // Enviamos la respuesta, que es un eco socketUDP.send(respuesta); } } catch (SocketException e) { System.out.println("Socket: " + e.getMessage()); } catch (IOException e) { System.out.println("IO: " + e.getMessage()); } } } Para probar como funciona este sencillo programa, debereis arrancar primero el servidor, que se quedará a la escucha de peticiones, y después el cliente. Como podeis comprobar el cliente envía una única petición y finaliza; y el servidor se queda esperando por nuevas peticiones. Modificad el programa cliente anterior, para que envíe al servidor los mensajes que introduce un usario por la entrada estándar. MulticastSocketLa operación de multicast consiste en enviar un único mensaje desde un proceso a cada uno de los miembros de un grupo de procesos, de modo que la pertenencia a un grupo sea transparente al emisor, es decir, el emisor no conoce el número de miembros del grupo ni sus direcciones IP.Un grupo multicast está especificado por una dirección IP clase D y un puerto. Las direcciones IP clase D están en el rango 224.0.0.0 a 239.255.255.255, dentro de este rango existen direcciones reservadas, en concreto, la 224.0.0.1 y la 224.0.0.255. El resto de direcciones del rango pueden ser utilizadas por grupos temporales, los cuales deben ser creados antes de su uso y dejar de existir cuando todos los miembros lo hayan dejado. Java proporciona una interfaz de datagramas para multicast IP a través de la clase MulticastSocket, que es una subclase de DatagramSocket, con la capacidad adicional de ser capaz de pertenecer a grupos multicast. La clase MulticastSocket proporciona dos constructores alternativos:
Un proceso puede pertenecer a un grupo multicast invocando el método joinGroup(InetAddress mcastaddr) de su socket multicast. Así, el socket pertenecerá a un grupo de multidifusión en un puerto dado y recibirá los datagramas enviados por los procesos en otros computadores a ese grupo en ese puerto. Un proceso puede dejar un grupo dado invocando el método leaveGroup(InetAddress mcastaddr) de su socket multicast. Para enviar datos a un grupo multicast se utiliza el método send(DatagramPacket p, byte ttl), este método es muy similar al de la clase DatagramSocket, la diferencia es que este datagrama será enviado a todos los miembros del grupo multicast. El parámetro TTL, Time-To-Live, lo pondremos siempre a 1, valor por defecto, para que sólo se difunda en la red local. Para recibir datos de un grupo multicast se utiliza el método receive(DatagramPacket p) de la clase DatagramSocket superclase de MulticastSocket. Es necesario pertenecer a un grupo para recibir mensajes multicast enviados a ese grupo, pero no es necesario para enviar mensajes. Vamos a ver un ejemplo sencillo de utilización de la clase MulticastSocket. Nuestro programa Java implementará las acciones que debe de hacer un participante en un grupo multicast, primero se unirá al grupo, a continuación, enviará un mensaje al grupo, después se quedará a la espera de recibir mensajes de otros participantes del grupo, hasta que el mensaje recibido sea "Adios". Para simplificar el programa, consideramos el caso de que tanto el mensaje que envía el participante, como la dirección IP multicast del grupo, se pasan como parámetros. Código de MiembroMulticast import java.net.*; import java.io.*; public class MiembroMulticast { public static void main(String args[]) { // args[0] es el mensaje enviado al grupo y args[1] es la direccion del grupo try { InetAddress grupo = InetAddress.getByName(args[1]); MulticastSocket socket = new MulticastSocket(6789); // Se une al grupo socket.joinGroup(grupo); // Envia el mensaje byte[] m = args[0].getBytes(); DatagramPacket mensajeSalida = new DatagramPacket(m, m.length, grupo, 6789); socket.send(mensajeSalida); byte[] bufer = new byte[1000]; String linea; // Se queda a la espera de mensajes al grupo, hasta recibir "Adios" while (true) { DatagramPacket mensajeEntrada = new DatagramPacket(bufer, bufer.length); socket.receive(mensajeEntrada); linea = new String(mensajeEntrada.getData(), 0, mensajeEntrada.getLength()); System.out.println("Recibido:" + linea); if (linea.equals("Adios")) break; } // Si recibe "Adios" abandona el grupo socket.leaveGroup(grupo); } catch (SocketException e) { System.out.println("Socket:" + e.getMessage()); } catch (IOException e) { System.out.println("IO:" + e.getMessage()); } } } Para probar el programa, crearemos varias instancias de MiembroMulticast y veremos como cada vez que se crea un nuevo participante su mensaje llega a todos los demás. Para que todos los participantes abandonen el grupo, crearemos una instancia de MiembroMulticast con el mensaje "Adios". |
|||
|
|
|||
|
|