gentoo linux, java, software libre y otras hierbas
Abr, 02 2008 - 1:03 pm

[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

Descargar código fuente

Etiquetas: java
Los ejercicios utilizados en este post están basados en ejemplos del libro Cómo programar en Java de Deitel, y por lo tanto están bajo la licencia que esta editorial disponga.

14 Comentarios | deja el tuyo

14 Comentarios en “[código] Uso de Datagramas en Java (Protocolo UDP)”

  1. locx24 dice:

    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.

  2. Casidiablo dice:

    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 :P

    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!

  3. gp dice:

    ejemplo muy bueno, me ha sido de mucha utilidad.

    Gracias.

  4. Aleja dice:

    hola!!, me compilo super tu ejemplo, tu me puedes decir cmo hacer para q salga la interfaz, primera q muestras, no me sale!

  5. Daniel dice:

    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!!!

  6. VICTORIA MARTINEZ APOLINAR dice:

    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

  7. VICK dice:

    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…

  8. MONICA GARCIA dice:

    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.

  9. karina calderon dice:

    Holaaa. me gustaria que me ayudaran a realizar un codigo que me permita comunicar un cliente con varios servidores.(Broadcast) en java.. Gracias

  10. novato dice:

    hola esta muy bueno tu ejemplo…
    pero necesito que en vez de una cadena de texto envie un video o archivo de sonido… :(

  11. Jose Lopez dice:

    Viejo, esto fue perfecto para una tarea

    Gracias

  12. anonimo dice:

    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)??…

  13. yadoble dice:

    Muchas gracias. A penas voy a checar el codigo, pero gracias

  14. vagos dice:

    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…

¡Déjanos tu comentario!