[código] Uso de Datagramas en Java (Protocolo UDP)
Hace un rato ponía un ejemplo acerca del uso de Sockets en Java, para enviar y recibir datos vía red (TCP). Esta vez haremos algo similar pero usando Datagramas, es decir, usando UDP.
UDP es un protocolo no orientado a la conexión. Esto significa que la comunicación es más rápida (porque no hay que establecer conexiones ni circuitos virtuales entre máquinas) pero también menos segura, puesto que a diferencia del TCP no mantiene estado de conexión alguno. (Leer más acerca de las diferencias entre UDP y TCP).
Para dicho propósito, el programa hace uso de las clases DatagramSocket y DatagramPacket. Esta clase representa a los paquetes de datos que vamos a recibir o transmitir a través de los objetos DatagramSocket. Estos paquetes constan de una cabecera (que incluye la dirección de origen y destino del paquete, el puerto, la longitud del paquete, un checksum, etc.) y un cuerpo (donde se encuentra el contenido real del paquete) [?].
El resultado…

El código…
La clase Servidor.java:
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Servidor extends JFrame {
private JTextArea areaPantalla;
private DatagramSocket socket;
// configurar GUI y DatagramSocket
public Servidor()
{
super( "Servidor" );
areaPantalla = new JTextArea();
getContentPane().add( new JScrollPane( areaPantalla ),
BorderLayout.CENTER );
setSize( 400, 300 );
setVisible( true );
// crear objeto DatagramSocket para enviar y recibir paquetes
try {
socket = new DatagramSocket( 5000 );
}
// procesar los problemas que pueden ocurrir al crear el objeto DatagramSocket
catch( SocketException excepcionSocket ) {
excepcionSocket.printStackTrace();
System.exit( 1 );
}
} // fin del constructor de Servidor
// esperar a que lleguen los paquetes, mostrar los datos y repetir el paquete al cliente
private void esperarPaquetes()
{
while ( true ) { // iterar infinitamente
// recibir paquete, mostrar su contenido, devolver copia al cliente
try {
// establecer el paquete
byte datos[] = new byte[ 100 ];
DatagramPacket recibirPaquete =
new DatagramPacket( datos, datos.length );
socket.receive( recibirPaquete ); // esperar el paquete
// mostrar la información del paquete recibido
mostrarMensaje( "\nPaquete recibido:" +
"\nDel host: " + recibirPaquete.getAddress() +
"\nPuerto del host: " + recibirPaquete.getPort() +
"\nLongitud: " + recibirPaquete.getLength() +
"\nContenido:\n\t" + new String( recibirPaquete.getData(),
0, recibirPaquete.getLength() ) );
enviarPaqueteACliente( recibirPaquete ); // enviar paquete al cliente
}
// procesar los problemas que pueden ocurrir al manipular el paquete
catch( IOException excepcionES ) {
mostrarMensaje( excepcionES.toString() + "\n" );
excepcionES.printStackTrace();
}
} // fin de instrucción while
} // fin del método esperarPaquetes
// repetir el paquete al cliente
private void enviarPaqueteACliente( DatagramPacket recibirPaquete )
throws IOException
{
mostrarMensaje( "\n\nRepitiendo datos al cliente..." );
// crear paquete a enviar
DatagramPacket enviarPaquete = new DatagramPacket(
recibirPaquete.getData(), recibirPaquete.getLength(),
recibirPaquete.getAddress(), recibirPaquete.getPort() );
socket.send( enviarPaquete ); // enviar el paquete
mostrarMensaje( "Paquete enviado\n" );
}
// método utilitario que es llamado desde otros subprocesos para manipular a
// areaPantalla en el subproceso despachador de eventos
private void mostrarMensaje( final String mensajeAMostrar )
{
// mostrar el mensaje del subproceso de ejecución despachador de eventos
SwingUtilities.invokeLater(
new Runnable() { // clase interna para asegurar que la GUI se actualice apropiadamente
public void run() // actualiza areaPantalla
{
areaPantalla.append( mensajeAMostrar );
areaPantalla.setCaretPosition(
areaPantalla.getText().length() );
}
} // fin de la clase interna
); // fin de la llamada a SwingUtilities.invokeLater
}
public static void main( String args[] )
{
JFrame.setDefaultLookAndFeelDecorated(true);
Servidor aplicacion = new Servidor();
aplicacion.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
aplicacion.esperarPaquetes();
}
} // fin de la clase Servidor
La clase Cliente.java:
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Cliente extends JFrame {
private JTextField campoIntroducir;
private JTextArea areaPantalla;
private DatagramSocket socket;
// configurar GUI y DatagramSocket
public Cliente()
{
super( "Cliente" );
Container contenedor = getContentPane();
campoIntroducir = new JTextField( "Escriba aquí el mensaje" );
campoIntroducir.addActionListener(
new ActionListener() {
public void actionPerformed( ActionEvent evento )
{
// crear y enviar el paquete
try {
areaPantalla.append( "\nEnviando paquete que contiene: " +
evento.getActionCommand() + "\n" );
// obtener mensaje del campo de texto y convertirlo en arreglo byte
String mensaje = evento.getActionCommand();
byte datos[] = mensaje.getBytes();
// crear enviarPaquete
DatagramPacket enviarPaquete = new DatagramPacket( datos,
datos.length, InetAddress.getLocalHost(), 5000 );
socket.send( enviarPaquete ); // enviar paquete
areaPantalla.append( "Paquete enviado\n" );
areaPantalla.setCaretPosition(
areaPantalla.getText().length() );
}
// procesar los problemas que pueden ocurrir al crear o enviar el paquete
catch ( IOException excepcionES ) {
mostrarMensaje( excepcionES.toString() + "\n" );
excepcionES.printStackTrace();
}
} // fin de actionPerformed
} // fin de la clase interna
); // fin de la llamada a addActionListener
contenedor.add( campoIntroducir, BorderLayout.NORTH );
areaPantalla = new JTextArea();
contenedor.add( new JScrollPane( areaPantalla ),
BorderLayout.CENTER );
setSize( 400, 300 );
setVisible( true );
// crear objeto DatagramSocket para enviar y recibir paquetes
try {
socket = new DatagramSocket();
}
// atrapar los problemas que pueden ocurrir al crear objeto DatagramSocket
catch( SocketException excepcionSocket ) {
excepcionSocket.printStackTrace();
System.exit( 1 );
}
} // fin del constructor de Cliente
// esperar a que lleguen los paquetes del Servidor, mostrar el contenido de los paquetes
private void esperarPaquetes()
{
while ( true ) { // iterar infinitamente
// recibir el paquete y mostrar su contenido
try {
// establecer el paquete
byte datos[] = new byte[ 100 ];
DatagramPacket recibirPaquete = new DatagramPacket(
datos, datos.length );
socket.receive( recibirPaquete ); // esperar un paquete
// mostrar el contenido del paquete
mostrarMensaje( "\nPaquete recibido:" +
"\nDel host: " + recibirPaquete.getAddress() +
"\nPuerto del host: " + recibirPaquete.getPort() +
"\nLongitud: " + recibirPaquete.getLength() +
"\nContenido:\n\t" + new String( recibirPaquete.getData(),
0, recibirPaquete.getLength() ) );
}
// procesar los problemas que pueden ocurrir al recibir o mostrar el paquete
catch( IOException excepcion ) {
mostrarMensaje( excepcion.toString() + "\n" );
excepcion.printStackTrace();
}
} // fin de instrucción while
} // fin del método esperarPaquetes
// método utilitario que es llamado desde otros subprocesos para manipular a
// areaPantalla en el subproceso despachador de eventos
private void mostrarMensaje( final String mensajeAMostrar )
{
// mostrar mensaje del subproceso de ejecución despachador de eventos
SwingUtilities.invokeLater(
new Runnable() { // clase interna para asegurar que la GUI se actualice apropiadamente
public void run() // actualiza areaPantalla
{
areaPantalla.append( mensajeAMostrar );
areaPantalla.setCaretPosition(
areaPantalla.getText().length() );
}
} // fin de la clase interna
); // fin de la llamada a SwingUtilities.invokeLater
}
public static void main( String args[] )
{
JFrame.setDefaultLookAndFeelDecorated(true);
Cliente aplicacion = new Cliente();
aplicacion.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
aplicacion.esperarPaquetes();
}
} // fin de la clase Cliente
14 Comentarios | deja el tuyo



Holas.
Me preguntaba de donde sacas tan excelentes ejemplos. Algunos los he identificado con solo verlos.
Son del libro Como programar en Java de Deitel & Deitel. Pero otros no logro ubicarlos, podrías postear alguna vez tu principal bibliografia de la que te basas para hacer tus ejemplos?
Por cierto se acerca el momento de publicar mi curso de Java en videotutoriales, ya completo. Espero y cuando lo suba me heches la mano para propagarlo por la red antes de que algún vivo lo intente vender.
De antemano gracias y Saludos.
Claro que te ayudo… lo de la fuente de los ejemplos, pues hombre la mayoría son del libro de Deitel, y ahora que lo dices no tengo citada la fuente.
Es un mero descuido… lo tenía citado en el antiguo blog y en el foro de elhacker.net, pero aquí no
Cuando actualice la página de Java lo pongo…
Un saludo!
P.d. Los libros de Deitel SON DE LO MEJOR en programación. Me encantan!
ejemplo muy bueno, me ha sido de mucha utilidad.
Gracias.
hola!!, me compilo super tu ejemplo, tu me puedes decir cmo hacer para q salga la interfaz, primera q muestras, no me sale!
Sólo puedo decir una cosa sobre esta sección: GRACIAS, MIL GRACIAS!!! He resuelto muchas dudas con el código que has adjuntado (y con muy poquito tiempo para entregar una práctica). GRACIAS!!!
HOLA TU PROGRAMA ESTA PERFECTO CON LO QUE A ENVIO DE PAQUETES SE REFIERE PERO ME GUSTARIA QUE ME AYUDES A OBTENER UN CODIGO DE ENVIO DE PAQUETES, POR EJEMPLO QUE ESTE PLATICANDO CON EL CODIGO DE MENSAJES Y QUE PUEDA ENVIAR NO SE POR ESTE MISMO CODIGO UN ARCHIVO EN .DOC O DE CUALQUIER TIPO. POR FAVOR ESPERARE TU RESPUESTA, GRACIAS POR TODO ERES FENOMENAL
HOLA TU PROGRAMA ESTA PERFECTO CON LO QUE A ENVIO DE MENSAJES SE REFIERE PERO ME GUSTARIA QUE ME AYUDES A OBTENER UN CODIGO DE ENVIO DE PAQUETES, POR EJEMPLO QUE ESTE PLATICANDO CON EL CODIGO DE MENSAJES Y QUE PUEDA ENVIAR NO SE POR ESTE MISMO CODIGO UN ARCHIVO EN .DOC O DE CUALQUIER TIPO. POR FAVOR ESPERARE TU RESPUESTA, GRACIAS POR TODO ERES FENOMENAL. TE LO VOLVI A ESCRIBIR PORQUE ME EQUIVOQUE EN LA PRIMERA SOLICITUD…
me gustaria mucho que me pudieran ayudar ha ser un codigo para la simulacion de un ruteador solo me gustaria que me dieran una idea de como hacerlo. la verdad esque estudio informatica y se me complicaun poco lo de la programacion gracias. y muy buenos ejemplos eh.
Holaaa. me gustaria que me ayudaran a realizar un codigo que me permita comunicar un cliente con varios servidores.(Broadcast) en java.. Gracias
hola esta muy bueno tu ejemplo…
pero necesito que en vez de una cadena de texto envie un video o archivo de sonido…
Viejo, esto fue perfecto para una tarea
Gracias
como se haria para guardar la informacion que se envia a una base de datos, la cual puedas consultarla despues (mas o menos como un servidor de correos)??…
Muchas gracias. A penas voy a checar el codigo, pero gracias
Hola todos uds son unos vagos o no tienen la más mínima gana de aprender o realmente no les da el seso para la programación. Busquen y en base a estos ejemplos hagan sus propios programas. Besos a todos esos que se ponen nombres de mujer para que les envien los códigos jajaja vagos de mie…