Vamos a ver un ejemplo de dos programas java en el que uno de ellos envía una clase Serializable al otro a través de un socket UDP. Aprovecharemos para ir explicando lo mínimo imprescindible para manejar este tipo de sockets. Como siempre, al final tienes los fuentes del ejemplo para que puedas hacer tus pruebas.
En los sockets TCP es necesario establecer una conexión. El servidor TCP espera que un cliente TCP se le conecte. Una vez hecha la conexión, se pueden enviar mensajes. El protocolo TCP garantiza que todos los mensajes enviados van a llegar bien y en el orden enviado. Sólo el cliente necesita saber dónde está el servidor y en qué puerto está escuchando.
Por el contrario, en los sockets UDP no se establece conexión. El servidor se pone a la escucha de un puerto de su ordenador. El cliente también se pone a la escucha de un puerto de su ordenador. En cualquier momento, cualquiera de ellos puede enviar un mensaje al otro. Ambos necesitan saber en qué ordendador y en qué puerto está escuchando el otro. Aquí el concepto de cliente y servidor está un poco más difuso que en el caso de TCP. Podemos considerar servidor al que espera un mensaje y responde. Cliente sería el que inicia el trasiego de mensajes. El servidor debería, además, estar siempre arrancado y a la escucha.
Además, en contra de TCP, el protocolo UDP sólo garantiza que si el mensaje llega, llega bien. No garantiza que llegue ni que lleguen en el mismo orden que se han enviado. Este tipo de sockets es útil para el envío más o menos masivo de información no crucial. Por ejemplo, enviar los datos para el refresco de gráficos en una pantalla.
Otra ventaja de UDP respecto a TCP,
es que con UDP se puede enviar un mensaje a varios receptores
a la vez, mientras que en TCP, al haber una conexión
previa, sólo se puede enviar el mensaje al que está conectado
al otro lado. Con UDP se puede, por ejemplo, enviar una
sola vez los datos para que varias pantallas refresquen sus gráficos
a la vez.
Tanto cliente como servidor, para ponerse a la escucha de un puerto UDP, únicamente tienen que instanciar la clase DatagramSocket, pasándole los parámetros adecuados:
Por ello, el código del servidor es tan sencillo como esto
y el del cliente se parece bastante
Esta es la clase que se va a enviar y recibir como mensaje. Lleva dentro un array de bytes que es el que debemos rellenar con lo queremos enviar o en el que estará lo que hemos recibido.
Dependiendo de si es para enviar o recibir, esta clase se instancia de forma distinta. En ambos casos hay que pasarle el array de bytes. En el caso de enviar, hay que pasarle además la InetAdress del destinatario y el puerto en el que está escuchando el destinatario.
Para enviar el DatagramPacket, debemos llamar al método send() de DatagramSocket pasando como parámetro el DatagramPacket que acabamos de crear.
Para recibir, igual pero con socket.receive().
Lo de meter un array de bytes en el DatagramPacket está muy bien si leemos bytes de un fichero o de algún otro sitio. Sin embargo, si queremos enviar o recibir clases (Serializable, por supuesto), tenemos que hacer una conversión. Los siguientes código nos ayudan a hacer este tipo de conversiones. Suponemos que la clase se llama DatoUdp y que implenta la interface Serializable.
Con todo esto ya sabemos lo necesario para hacer un pequeño ejemplo de Servidor udp y cliente udp. Los fuentes del ejemplo los tienes en socketudp.zip. Si lo descomprimes, simplemente compila y ejecuta de la siguiente manera:
Deberías ver cómo el cliente envía 10 mensajes y el servidor los escribe en pantalla. Si no ejecutas ambos programas en el mismo ordenador, tendrás que cambiar los fuentes para que el cliente tenga el nombre del servidor.