Cliente/Servidor por UDP con búfer en java

27.10.08. Por ooscarr (ooscarr)

No sólo por TCP/IP se pueden comunicar varios servidores, sino que también por UDP. En estos 2 ejemplos también se hará uso de búfer.

¿Qué es UDP?

User Datagram Protocol (UDP) es uno de los protocoles base del Conjunto de Protocolos de Internet. Por medio del UDP, programas en cmputadores conectados por red pueden enviar mensajes cortos a veces conocidos como datagramas (usando Datagram Sockets) de un lado al otro. UDP es a veces llamado el Protocolo Universal de Datagramas. El protocolo fue diseñado por David P. Reed en 1980 y formalmente definido en RFC 768.

UDP no garantiza la confiabilidad o el orden de la manera en que lo hace TCP. Los Datagramas pueden llegar en distinto orden, aparecer duplicados, o perderse sin informar. Al evitar el trabajo de revisar si cada paquete de verdad llegó hace a UDP más rápido y más eficiente, para aplicaciones que no necesitan envíos garantizados. Aplicaciones sensibles al tiempo a menudo usan UDP porque los paquetes recientemente enviados tienen preferencia a los paquetes atrasados. La naturaleza de la falta de estados de UDP también es útil para servidores que responden pequeñas consultas de un enorme número de clientes. A diferencia de TCP, UDP es compatible con broadcast de paquetes (enviando a todos en una red local) y multicasting (enviar a todos los suscritos).

Como aplicaciones de red comunes que utilizan UDP se incluyen: El Sistema de Nombres de Dominio (DNS), aplicaciones streaming media tales como IPTV, Voz sobre IP (VoIP), Trivial File Transfer Protocol (TFTP) y juegos online.

Seguir leyendo en Wikipedia

Ejemplo 1

Como primer ejemplo, encontré esta simple comunicación donde el Cliente le envía un paquete cualquiera al Servidor y éste le responde con la fecha y hora:

DataTimeClient.java

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class DataTimeClient {
    
    /** Creates a new instance of DataTimeClient */
    public DataTimeClient() {  
 }
    
    public static void main(String args[]) {
        byte[] buf = new byte[256];
        DatagramSocket socket;
        try {
            socket = new DatagramSocket();
            InetAddress address= InetAddress.getByName("localhost");
            DatagramPacket packet = new DatagramPacket(buf,buf.length,address,9090);
            socket.send(packet);
            packet = new DatagramPacket(buf,buf.length);
            socket.receive(packet);
            System.out.println(new String(packet.getData()));
        } catch (IOException ex) {
            ex.printStackTrace();
        }       
    }
}

TimeServer.java

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Date;
/**
 *
 * @author pcrao
 */
public class TimeServer{
    static DatagramSocket socket ;
    /** Creates a new instance of Main */
    public TimeServer() {
  
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {
            socket = new DatagramSocket(9090);
            byte[] buf = new byte[256];
            DatagramPacket packet = new DatagramPacket(buf, buf.length);
            while(true) {
                System.out.println("Listening");
                socket.receive(packet);          
                
                String toClient=new Date().toString();
                buf = toClient.getBytes();
                InetAddress address = packet.getAddress();
                int port = packet.getPort();
                packet = new DatagramPacket(buf, buf.length, address, port);
                socket.send(packet);
            }
            
        } catch (SocketException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    
}

Servidor de Raíz cuadrada

Y para terminar, el mismo ejemplo que hicimos antes por TCP/IP, pero por UDP con búfer.

Cliente.java

import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class Cliente {
    
    /** Creates a new instance of DataTimeClient */
    public Cliente() {  
 }
 
    /* Se definen cuatro variables que leen DESDE EL TECLADO
  stdin1 para saber si sigue o no
  stdin2 para saber qué función desea realizar
  stdin3 para obtener el valor que quiere resolver
  stdin4 para el exponente, en caso que desea resolver una potencia*/
 private static BufferedReader stdin1 = new BufferedReader(new InputStreamReader(System.in));
 private static BufferedReader stdin2 = new BufferedReader(new InputStreamReader(System.in));
 
    public static void main(String args[]) {
  
  //La dirección del servidor de raíces cuadradas
  String IP_SQRT= "localhost";
  //Puerto del servidor de raíces cuadradas
  int PUERTO_SQRT=5001;
        
  //Por defecto sí sigue (empieza)
  String sigue="s";
  
  System.out.println("\nBuenos días");
  
  //Mientras el usuario siga con ganas de resolver
  while(sigue.equals("s")){
   
   System.out.println("RAÍZ CUADRADA");
   try{
    
    //Lee el valor desde teclado
    System.out.print("Raíz cuadrada de: ");
    String valor=stdin2.readLine();
    
    //Envía el valor a la función de más abajo
    String resultado=realizar_operacion(IP_SQRT,PUERTO_SQRT,valor);
    
    //Imprime el resultado
    System.out.println("= "+resultado);
    
   } catch(Exception e){
    System.err.println(e);
   }   
   
   //Sigue el ciclo
   System.out.print("\nDesea realizar otra operación? (s/n): ");
   try{
    sigue = stdin1.readLine();
   } catch(Exception e){
    System.err.println(e);
   }
  }

    }



 /* Función realizar operacion se encarga de comunicarse con el coordinador*/
 static String realizar_operacion(String IP_SQRT,int PUERTO_SQRT,String valor){

  //Se define el búfer
        byte[] buf = new byte[256];
  byte[] buf2 = new byte[256];
  
        DatagramSocket socket;
  
  String respuesta=null;

  try {
   //Nuevo socket UDP
            socket = new DatagramSocket();

   buf = valor.getBytes();

   //Se crea el paquete
            DatagramPacket paquete = new DatagramPacket(buf,buf.length,InetAddress.getByName(IP_SQRT),PUERTO_SQRT);

   //Se envía el paquete por el socket
            socket.send(paquete);

            paquete = new DatagramPacket(buf2,buf2.length);
   //Se espera que llegue el paquete
            socket.receive(paquete);

   respuesta=new String(paquete.getData());
   //System.out.println(respuesta);
   
   socket.close();

        } catch (IOException ex) {
            ex.printStackTrace();
        }
  //Retorna el valor recibido como respuesta
  return respuesta;
 }
}

Servidor.java

import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class Servidor{
    static DatagramSocket socket ;
 
    //Constructor crea nueva instancia del main
    public Servidor() {
    }
    
    public static void main(String[] args) {
  int PUERTO_SQRT=5001;
  
  while(true) {
   try{
    
    socket = new DatagramSocket(PUERTO_SQRT);
    
    byte[] buf = new byte[256];
    DatagramPacket paquete = new DatagramPacket(buf, buf.length);
    
                System.out.println("Esperando para resolver raíces cuadradas...");
    //Se recibe un paquete por el socket
                socket.receive(paquete);
    String valor=new String(paquete.getData(), 0, paquete.getLength());
    
    System.out.print("Raíz cuadrada de "+valor+" es... ");
    
    //Creo una instancia de las operaciones definidas
    Operaciones operar=new Operaciones(valor);
    
    //Realizo la operación
    String resultado=null;
    resultado=String.valueOf(operar.sqrt());
    System.out.println(resultado);
    
    System.out.print("Enviando resultado... ");
    buf = new byte[256];
                buf = resultado.getBytes();
                InetAddress IP_CLIENTE = paquete.getAddress();
                int PUERTO_CLIENTE = paquete.getPort();
                paquete = new DatagramPacket(buf, buf.length, IP_CLIENTE,PUERTO_CLIENTE);
                socket.send(paquete);
    
    System.out.println("OK");
    
    //Se cierra la petición de conexión llamada socket
    try{
     socket.close();
    }
    catch (Exception ex){
     System.err.println(ex);
    }
    
   } catch (Exception e){
    System.err.println("Hubo un error.");
    System.err.println(e);
    if(socket!=null){
     System.out.print("Cerrando socket ...");
     try{
      socket.close();
      System.out.println("OK");
     } catch (Exception ex){
      System.out.println("FAIL");
     }
    }
    break;
   }
  }//fin del while(true)
    }
    
}

Fuentes

Artículos relacionados

Etiquetas: ,

0 comentarios (RSS ATOM) :

Página principal

Publicidad