Program Ac i on Client Es Er Vidor

download Program Ac i on Client Es Er Vidor

of 13

Transcript of Program Ac i on Client Es Er Vidor

  • 8/18/2019 Program Ac i on Client Es Er Vidor

    1/13

    PROGRAMACIÓN CLIENTE-SERVIDOR

    MEDIANTE SOCKETS EN JAVA

    ¿Qué es la arquitectura cliente servidor?

    La arquitectura cliente-servidor es un modelo de aplicación distribuida en el que las tareas

    se reparten entre los proveedores de recursos o servicios, llamados servidores, y los

    demandantes, llamados clientes. Es decir, un cliente es el que hace una solicitud de un

    servicio a un servidor y el servidor es un programa que recibe una solicitud, realiza el

    servicio requerido y devuelve los resultados en forma de una respuesta. 

    ¿Qué es un socket?Los  sockets  son un sistema de comunicación entre procesos de diferentes máquinas de

    una red. Más exactamente, un  socket  es un punto de comunicación por el cual un

    proceso puede emitir o recibir información.

    ¿Cómo funciona un socket?

    El modelo básico de los sockets consta de 2 simples programas, un servidor y un cliente.  

    Básicamente el programa SERVIDOR comienza a escuchar en un puerto determinado(nosotros lo especificamos), y posteriormente el programa CLIENTE debe conocer la IP o

    nombre de dominio/hostname del servidor y el puerto que está escuchando.

    El socket sigue normalmente realiza los procesos de Abrir-Leer-Escribir-Cerrar. Antes de que

    un proceso de usuario pueda realizar operaciones de entrada/salida, debe hacer una

    llamada a Abrir (open), luego realizar llamadas a Leer (read) y Escribir (write), para la

    lectura y escritura de los datos y una vez concluido el intercambio de información, el

    proceso de usuario llamará a Cerrar (close) para informar que ha finalizado.

    Un proceso tiene un conjunto de descriptores de entrada/salida desde donde leer y por

    donde escribir. Estos descriptores pueden estar referidos a ficheros, dispositivos, o canales

    de comunicaciones llamados sockets.

    El ciclo de vida de un descriptor, aplicado a un canal de comunicación (por ejemplo, un

     socket), está determinado por tres fases:

      Creación, apertura del socket  Lectura y Escritura, recepción y envío de datos por el socket  Destrucción, cierre del socket

  • 8/18/2019 Program Ac i on Client Es Er Vidor

    2/13

     

    En un esquema más completo donde se tiene muchos clientes con peticiones a un solo

    servidor se puede apreciar cómo se realiza la comunicación con el siguiente esquema

    que se muestra.

  • 8/18/2019 Program Ac i on Client Es Er Vidor

    3/13

    Ejemplo 1

    SALUDO DE BIENVENIDA

    El siguiente programa establece una conexión básica entre un servidor y un cliente

    Donde una vez establecida la conexión el servidor solicita el nombre del cliente, el cliente

    introduce su nombre, y el servidor le da una bienvenida mediante un mensaje.

    Programa Servidor

    //Declaramos librerías necesariasimport java.io.*;import java.net.*;import java.util.Scanner;

    public class Servidor {

    private ServerSocket sServidor; //Socket del servidor private Socket sCliente; //Socket para el cliente 

    private Scanner entrada; //Flujo de Entrada para envio de datos private PrintStream salida; //Flujo de Salida para recepcion de datos private int puerto; // Puerto por el cual escuchara el servidor 

    public Servidor(int p){

    puerto=p;}

    public void iniciar(){try {

    //Se Crea el socket del servidor sServidor =new ServerSocket(puerto);

    System.out.println(" - SERVIDOR INICIADO - ");System.out.println(" - Espèrando Cliente - ");

    //El metodo accept(), espera hasta que un cliente realice una conexión //Una vez que se ha establecido una conexión por el cliente, este 

    //método devolverá un objeto tipo Socket, a través del cual se establecerá//la comunicación con el cliente sCliente=sServidor.accept();

    //Obtengo una referencia a los flujos de datos de entrada y salida del socket cliente 

    entrada =new Scanner(sCliente.getInputStream());salida =new PrintStream(sCliente.getOutputStream());

    ////Esta sección puede ser modificada según nuestros requerimientos////////// System.out.println("Cliente Conectado:"+ sCliente.getInetAddress() +":"+

    sCliente.getPort() );salida.println("EJEMPLO1-Saludo");

    salida.print("Ingrese Su Nombre ->");String nombre= entrada.next();salida.println("Bienvenido "+ nombre);/////////////////////////////////////////////////////////////////////////////  

    //Cerramos la conexión finalizar();

    }catch(Exception e){

    finalizar ();e.printStackTrace();

    }

    }public void finalizar(){

    try {entrada.close();salida.close();sCliente.close();

    sServidor.close();System.out.print("Conexion Finalizada...");

    }

  • 8/18/2019 Program Ac i on Client Es Er Vidor

    4/13

      catch (IOException e) {e.printStackTrace();

    }}} 

    public class Main {

    public static void main(String arg[]){Servidor x=new Servidor(9998);x.iniciar();

    }

    }

    Capturas

    Iniciando el servidor

    Estableciendo conexión desde el cliente mediante telnet

    Resultado, una vez introducido nuestro nombre el servidor nos manda un mensaje de

    bienvenida

  • 8/18/2019 Program Ac i on Client Es Er Vidor

    5/13

    Ejemplo 2

    Chat simple

    El siguiente programa establece una conexión básica entre un servidor y un cliente

    Donde una vez establecida la conexión el servidor y el cliente, pueden chatear entre ellos,

    hasta que los dos introduzcan la palabra “bye”.

    Programa Servidor

    //Importamos librerías necesarias import java.io.*;import java.net.*;import java.util.Scanner;import java.awt.event.*;

    public class Servidor {private ServerSocket sServidor; //Socket del servidor 

    private Socket sCliente; //Socket para el cliente private Scanner entrada; //Flujo de Entrada para envio de datos private PrintStream salida; //Flujo de Salida para recepcion de datos private int puerto; // Puerto por el cual escuchara el servidor 

    private String mensaje_enviar="";

    private String mensaje_recibido="";private javax.swing.Timer t; //Declaramos un Timer 

    public Servidor (int p){puerto=p;

    //El timer será el encargado de ejecutar este bloque de código cada 500 [ms] //Es decir, que este leerá y mostrara los mensajes recibidos cada 0.5 segundos//siempre o cuando se haya creado una conexión y exista un mensaje. 

    t = new javax.swing.Timer(500,new ActionListener() {public void actionPerformed(ActionEvent e) {

    if (sCliente.isConnected() && !mensaje_recibido.equals("bye")){

    mensaje_recibido=entrada.next();System.out.println("Cliente_dice:"+mensaje_recibido);

    }

    }});

    }

    public void iniciar(){

    try{//Inicamos el servidor sServidor =new ServerSocket(puerto);System.out.println(" - SERVIDOR INICIADO- ");

    System.out.println("- Esperando cliente ...");

    //El metodo accept(), espera hasta que un cliente realice una conexión 

    //Una vez que se ha establecido una conexión por el cliente, este //método devolverá un objeto tipo Socket, a través del cual se establecerá//la comunicación con el cliente. sCliente=sServidor.accept();

    //Obtengo una referencia a los flujos de datos de entrada y salida del socket cliente salida=new PrintStream(sCliente.getOutputStream());

    entrada =new Scanner(sCliente.getInputStream());System.out.println("Cliente conectado "+ sCliente.getInetAddress()+":"+

    sCliente.getPort()+"\n");

    //iniciamos el timer t.start();

    Scanner lector=new Scanner(System.in);

    //Escribimos los mensajes hacia el cliente 

  • 8/18/2019 Program Ac i on Client Es Er Vidor

    6/13

      while(!mensaje_recibido.equals("bye")){

    mensaje_enviar=lector.next();salida.println("Servidor Dice : " +mensaje_enviar);

    }

    //Terminamos la conexión finalizar();}

    catch(Exception e){e.printStackTrace();

    finalizar();}

    }public void finalizar(){try{

    t.stop();salida.close();entrada.close();sCliente.close();sServidor.close();

    }catch(Exception e){

    e.printStackTrace();}

    }}

    public class Main {public static void main(String arg[]){

    Servidor x=new Servidor(9999);x.iniciar();

    }}

    Capturas

    Iniciando el servidor

    Conectando el cliente al servidor

  • 8/18/2019 Program Ac i on Client Es Er Vidor

    7/13

    Resultado, una vez establecida la conexión podemos proceder a chatear entre un

    servidor y un cliente.

    Ejemplo 3

    Eco

    El siguiente programa establece una conexión básica entre un servidor y un cliente

    Donde una vez establecida la conexión el servidor solicita que introduzca un texto al

    cliente y el servidor devuelve un “eco”, es decir el mismo mensaje que se envió. A

    continuación se implementa el programa del servidor conjuntamente el programa delcliente.

    Programa Servidor

    import java.io.*;import java.net.*;import java.util.*;

    public class Servidor {private ServerSocket sServidor;

    private Socket sCliente;

    private Scanner entrada;

    private PrintStream salida;private int puerto;private String mensaje="";

  • 8/18/2019 Program Ac i on Client Es Er Vidor

    8/13

     public Servidor (int p){

    puerto =p;}public void iniciar(){

    try{sServidor=new ServerSocket(puerto);System.out.println(" - SERVIDOR INICIADO - ");System.out.println(" - Esperando Cliente - ");sCliente=sServidor.accept();entrada=new Scanner(sCliente.getInputStream());salida = new PrintStream(sCliente.getOutputStream());

    //Se reenvía los mensajes que van llegando hasta q el cliente introduzca la palabra

    //”bye”,while(!mensaje.equals("bye")){

    mensaje=entrada.next();System.out.println("Mensaje cliente: "+mensaje);salida.println("Eco:_"+mensaje);

    }finalizar();

    }

    catch(Exception e){e.printStackTrace();finalizar();

    }

    }

    public void finalizar(){try{

    salida.close();entrada.close();sCliente.close();sServidor.close();System.out.print("Conexion Finalizada!!");

    }catch(Exception e){

    e.printStackTrace();

    }}} 

    public class MainServidor {public static void main(String arg[]){

    Servidor x=new Servidor(9990);x.iniciar();

    }}

    Programa Cliente

    import java.io.*;import java.net.*;

    import java.util.Scanner;public class Cliente {

    private Socket sCliente;private Scanner entrada;prívate PrintStream salida;prívate String host; //IP del servidor con el que me voy a conectar private int puerto;

    private String mensaje="";

    public Cliente(String h, int p){

    host=h;puerto=p;

    }

    public void iniciar(){try{

  • 8/18/2019 Program Ac i on Client Es Er Vidor

    9/13

      //Estableciendo conexion con el servidor sCliente =new Socket(host,puerto);System.out.println("CONEXION INICIADA");System.out.println("Conectado a : "+ sCliente.getRemoteSocketAddress());

    //Obtengo una referencia a los flujos de datos de entrada y salida salida=new PrintStream(sCliente.getOutputStream());entrada=new Scanner(sCliente.getInputStream());

    //Este bloque de código se encarga de enviar mensajes al servidor hasta que//este introduzca la palabra “bye” 

    Scanner lectura=new Scanner(System.in);

    while (!mensaje.equals("bye")){

    System.out.print("\nDigite mensaje :");mensaje=lectura.next();salida.println(mensaje);System.out.print(entrada.next());

    }

    finalizar();

    }catch(Exception e){

    e.printStackTrace();finalizar();

    }}public void finalizar(){

    try{salida.close();entrada.close();sCliente.close();}

    catch(Exception e){e.printStackTrace();

    }}

    public class MainCliente {

    public static void main(String arg[]){Cliente c=new Cliente("127.0.0.1", 9990);c.iniciar();

    }}

  • 8/18/2019 Program Ac i on Client Es Er Vidor

    10/13

    Capturas

    Iniciando el servidor

    Estableciendo conexión desde el cliente, iniciando cliente 

    Resultados, enviando mensajes y retornado ecos

    Por parte del cliente 

    Por parte del servidor  

  • 8/18/2019 Program Ac i on Client Es Er Vidor

    11/13

    Ejemplo 4

    Enviar un correo mediante un socket cliente.

    El siguiente programa cliente establece envía un correo mediante SMTP.

    En este ejemplo se enviara un correo electrónico a un servidor SMTP (implementado en el

    laboratorio anterior). Cabe notar que solo es necesario codificar el programa cliente,

    debido a que el protocolo SMTP ya esta implementado y configurado con Postfix.

    Programa Cliente

    //Importando librerías necesarias import java.io.*;import java.net.*;import java.util.Scanner;public class Cliente {

    private Socket sCliente;private Scanner entrada;

    private PrintStream salida;private String host="";private int puerto;

    public Cliente(String h, int p){host=h;

    puerto=p;}public void iniciar(String correoOrigen, String correoDestino, String asunto,String mensaje){try{

    //Estableciendo conexion con el servidor SMTP sCliente =new Socket(host,puerto);

    System.out.println("CONEXION INICIADA");System.out.println("Conectado a : "+ sCliente.getRemoteSocketAddress());

    //Obtengo una referencia a los flujos de datos de entrada y salida salida=new PrintStream(sCliente.getOutputStream());entrada=new Scanner(sCliente.getInputStream());

    //Escribiendo el correo (Notese que se sigue el formato propio del SMTP )System.out.println(entrada.nextLine()); //Respuesta del servidor salida.println("MAIL FROM: "+correoOrigen); //Correo de Origen System.out.println(entrada.nextLine()); //Respuesta del servidor salida.println("RCPT TO: "+correoDestino); //Correo de Destino System.out.println(entrada.nextLine()); //Respuesta del servidor salida.println("DATA"); //Indicamos q mandaremos un Mensaje

    salida.println("Subject: "+asunto); //Asunto del correo System.out.println(entrada.nextLine()); //Respuesta del servidor 

    salida.println(mensaje); //Mensaje salida.println(".");salida.println("."); //Terminamos el mensaje salida.println("quit");System.out.println(entrada.nextLine()); //Respuesta del servidor System.out.println("\nCorreo Enviado!");finalizar();

    }catch(Exception e){

    e.printStackTrace();finalizar();

    }}

    public void finalizar(){

    try{salida.close();

    entrada.close();sCliente.close();}catch(Exception e){

  • 8/18/2019 Program Ac i on Client Es Er Vidor

    12/13

  • 8/18/2019 Program Ac i on Client Es Er Vidor

    13/13

    Revisamos si el correo llego en forma adecuada.

    NOTA 

    * Ambos programas (servidor y cliente) no necesitan estar programados en Java, es

    posible programarlos en lenguajes de programación diferentes, o inclusive programar un

    servidor en java y utilizar un cliente ya existente o solo programar el cliente y acceder a unservidor ya existente.

    * Cuando se selecciona un número de puerto, se debe tener en cuenta que los puertos enel rango 0-1023 están reservados. Estos puertos son los que utilizan los servicios estándar delsistema como email, ftp, http, dns, dhcp, etc. Por lo que, para aplicaciones de usuario, elprogramador deberá asegurarse de seleccionar un puerto por encima del 1023.

    * El cliente debe de conocer tanto el puerto a utilizar como la IP o dominio del servidor,

    mientras el servidor solo debe conocer el puerto de conexión.

    * Si las pruebas son realizadas en Windows 7, es necesario habilitar el telnet en Panel decontrol -> Desinstalar un programa -> Activar o desactivar las características de Windows -

    > cliente telnet.