[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
19 Comentarios | deja el tuyo





olaa estoy interesado en el tema y la vez tengo muchas dudas, xq el ejemplo si me funciona pero solo en modo localhost, que podria implementar al codigo para q, yo conectado a mi pc pueda acceder a otra (Cliente) necesito ayuda…, mas detalles:
mi pc(Servidor):
ip:192.168.40.100
hostname:Rodriguez-PC
puerto:(indefinido) no lo tengo definido
otra pc(Cliente):
ip:10.0.0.4
hostname:
puerto:(indefinido) no lo tengo definido
en q parte del codigo modifico y como lo modifico. ¿Puedo comunicarme a travez de internet? tipo un antivirus. gracias de antemano mi correo: not_alone_411@hotmail.com
hola tengo una duda como hago que un servidor pueda enviar un paquete a varios clientes al mismo tiempo.
en protocolo udp.
gracias de antemano.
mi correo: maicol.1991@hotmail.com
Hola Amigo, necesito si me puedes colaborar con lo siguiente:
Necesito una aplicación en java cliente-servidor que simule un servidor DHCP, en la que basicamente el cliente deberá realizar la solicitud de dirección IP a la máquina servidora implementando una petición broadcast y enviando un mensaje codificado con la dirección MAC el cual reconocerá su servidor. Su servidor renviará una dirección ip seleccionada de una lista que al configurar su servidor será definido por el usuario que levanta el servicio.La dirección MAC deberá ser tomada dinámicamente de la máquina cliente. No debe ser digitada por el usuario
gracias de antemano.
Correo: carlitosbega@hotmail.com