domingo, 23 de febrero de 2014

Reingeniería de Software.


Introducción.
Cuando un software ha tenido una vida útil de 10 a 15 años, ha sufrido muchos cambios y modificaciones tanto en su código, como en su arquitectura, su documentación, diseño, etc. y aun se provee realizar muchos más cambios para seguir satisfaciendo las necesidades del usuario, se llega a un punto en que el equipo encargado de realizar dichos cambios no comprenden a detalle las funciones del sistema y la complejidad actual del mismo complica las cosas. En este punto, la mejor opción es aplicarle reingeniería al software, aunque esto implique grandes costos, pero traerá mejores beneficios.
Reingeniería de Software.

Para entender todo lo que implica la reingeniería de software, primero debemos plantear que es y en qué consiste dicho proceso.
La reingeniería de software es la actividad de reconstrucción de un sistema, en el que el estado actual del sistema es muy complejo y dificultará realizar cambios en él, por lo que la opción más viable para que siga siendo útil es reconstruirlo (Pressman). Consta de seis etapas, que pueden seguir o no una secuencia lineal, pero siempre se desarrollarán cíclicamente.
Las etapas son:
  • Análisis de inventarios: se analizan los inventarios que poseen las empresas o el usuario sobre las características del programa y descripciones detalladas sobre su importancia, edad, etc., así se sabrá a que recursos se aplicará la reingeniería.
  • Reestructuración de documentos: aquí se analiza si se necesita documentar de nuevo todo el sistema, si se tiene que actualiza pero se cuentan con pocos recursos o si la documentación requiere de demasiado tiempo.
  • Ingeniería inversa: en esta etapa se analiza el programa para crear una representación mucho más abstracta que el código fuente y se recupera el diseño.
  • Reestructuración de código: aquí se analizan los módulos en los que se sospecha que el código que lo compone no sigue las estructuras de programación estructurada, para reestructurarlo y que siga dichas normas.
  • Reestructuración de los datos: esta etapa se lleva a cabo en un grado de abstracción bajo, y su respectiva reingeniería es de gran escala. Se definen los objetos de datos y los atributos, para después revisar la actual estructura de los datos.
  • Ingeniería avanzada. 
Conclusión.
Es importante conocer en qué consiste la reingeniería de software porque de esta manera sabremos en que casos y en qué momento es adecuado aplicarla para evitar que el sistema se vuelva mucho más complejo de lo que ya es, y así proveerle un sistema funcional y con mejores técnicas de programación al usuario.
Referencias.

Pressman, R. Ingeniería de Software. Un enfoque práctico. Mc Graw Hill.

domingo, 16 de febrero de 2014

Leyes de Lehman



Introducción.
Para proveer un buen mantenimiento, es necesario conocer el software y su código, cosa que se complica cuando se utiliza “código heredado”. Esto se refiere al código tomado de otro producto, pero que debido a los cambios y mantenimiento sufrido anteriormente, no es el código original y es más complicado entenderlo. Por esto, se desarrollaron las Leyes de Lehman, que se describirán a continuación y las cuales buscan resolver dichos problemas de código.
Las Leyes de Lehman.
Las Leyes de Lehman se derivan de los estudios realizados por el mismo Lehman, que se aplican invariablemente a todos los productos de software sobre los cambios que estos sufren. (Sommerville, 2005).
Son 8 leyes, de las cuales solo se explicarán y denominaran a detalle las 5 primeras, que por lo general son las más comunes y aplicables (Ruíz, 2000-2001), pero sin olvidar las últimas tres, que se agregaron tiempo después de haberse definido las primeras:
  • Cambio continuado. Se refiere a que el sistema está en constante cambio debido a que se pueden presentar nuevos requerimientos, se necesita solucionar los defectos que lleguen a presentarse, debe mejorarse la funcionalidad, eficiencia y seguridad.
  • Complejidad creciente. A medida que se realizan cambios, la estructura del sistema se vuelve mucho más compleja, provocando que en un futuro, cuando se quiera re-utilizar código, esta tarea se vuelva complicada.
  • Evolución prolongada del programa. El contexto en el que se desarrolla el sistema definirá que cambios realizar, en que momentos, los costes y como afectan al proceso de evolución, haciendo que la velocidad de los cambios a realizar sea gobernada por la efectividad y rapidez de la toma de decisiones de la organización.
  • Estabilidad organizacional. Es importante la buena comunicación entre cada integrante del equipo de desarrollo para lograr una eficiencia mutua que se verá reflejada a lo largo de la evolución del sistema.
  • Conservación de la familiaridad. A medida que se realicen cambios, todos aquellos que estén asociados al sistema, deberán conocer dichos cambios y su impacto en el comportamiento y funcionalidad del mismo, para así seguirlo desarrollando eficientemente, por lo que es preferible realizar pequeños cambios a uno grande, sabiendo que dichos cambios traerán consigo, indudablemente, nuevos defectos.
  • Crecimiento continuado. El crecimiento del sistema debe ser continuo para mostrarle mayor y mejor funcionalidad al usuario, que mantenga su interés por el sistema.
  • Decremento de la calidad. Para que la calidad de un sistema no decremente, éste debe adaptarse a los cambios que se presenten en su entorno, que puede referirse a actualizaciones de hardware y software como sistema operativo, librerías dependientes, etc.
  • Realimentación del sistema. El proceso de evolución del sistema y los cambios desarrollados toman como base la realimentación por parte de los usuarios realizada en diferentes niveles y de forma iterativa, para así satisfacer las necesidades que se presentan constantemente.
Conclusión.
Al analizar las Leyes de Lehman, podemos entender mucho mejor como y porque ocurren los cambios en el software provocando su evolución. Es importante considerarlas y tenerlas presentes porque proveen explicación a problemas que llegan a presentarse durante el desarrollo de un sistema.
Al entender lo que cada una dice, podemos tomar precauciones para no interferir en gran medida a ralentizar el proceso.
Referencias.
Ruíz, F. (2000-2001). Escuela Superior de Informática. Universidad de Castilla - La Mancha. Recuperado el 16 de Febrero de 2014, de Mantenimiento del Software.: http://alarcos.esi.uclm.es/per/fruiz/curs/mso/trans/s2.pdf
Sommerville, I. (2005). Ingeniería del Software. Madrid: Pearson Educación S.A.


Descargar "Leyes de Lehman".

lunes, 3 de febrero de 2014

Mantenimiento de Software


Introducción.

Cada que se desarrolla un sistema de software, debe tenerse en cuenta el mantenimiento que se le hace y cuál es el fin del mismo.

Para identificar el tipo de mantenimiento a realizar y el momento adecuado, a continuación se explicara en qué consiste propiamente el mantenimiento de software y los diferentes tipos que hay.

Mantenimiento de Software.
Para entender que es el mantenimiento de software, primero debe plantearse una definición como la siguiente, la cual está basada en el Estándar IEEE 1219 y el Estándar ISO/IEC 14764 (Sánchez Barreiro):

El mantenimiento de software es la modificación de un producto de software, antes de la entrega del producto como después de su entrega al cliente o usuario, para corregir defectos, mejorar el rendimiento u otras propiedades deseables, o para adaptarlo a un cambio de entorno.

Existen cuatro tipos de mantenimiento, los cuales se describirán.
  • Preventivo: Consiste en la revisión periódica de ciertos aspectos, tanto de hardware como de software. Esto permite que nuestro software tenga un mejor desempeño y seguridad de los datos almacenados. El propósito es prever averías o desperfectos en su estado inicial y corregirlas para mantener un funcionamiento óptimo (Fundación Omar Dengo. Educación, tecnología y desarrollo., 2011).
  • Correctivo: Tiene por objetivo localizar y eliminar defectos del software.
  • Adaptativo: Consiste en la modificación de un programa debido a cambios en el entorno de hardware o software en el cual se ejecuta. Estos cambios pueden afectar al sistema operativo, a la arquitectura física del  sistema de software o a su entorno de desarrollo.
  • Perfectivo: Consiste en las actividades realizadas para mejorar o añadir nuevas funcionalidades requeridas por el usuario (Martínez Torres, 2010).

Conclusión.

Después de ver en qué consisten los diferentes tipos de mantenimiento de software, podemos tener una idea más clara de la importancia que tienen los mismos.

Yo considero que el mantenimiento de software es importante ya que de esta manera garantizamos que nuestro producto de software es confiable y tiene un mínimo de probabilidades de fallar debido al efectivo mantenimiento que recibió antes y después de ser entregado.

Referencias.
Fundación Omar Dengo. Educación, tecnología y desarrollo. (2011). Recuperado el 03 de Febrero de 2014, de Mantenimiento Preventivo de Software.: http://www.rema.cr/pdf/Procedimiento_para_la_atencion_de_los_mantenimientos_preventivos.pdf

Martínez Torres, D. (12 de Julio de 2010). Universidad Tecnológica de la Mixteca. Recuperado el 03 de Febrero de 2014, de Ingeniería de Software. Tema 7: Mantenimiento del software.: http://www.utm.mx/~dtorres/cursos/ingsw/tema7.pdf
Sánchez Barreiro, P. (s.f.). Universidad de Cantabria. Dpto. de Matemáticas, Estadística y Computación. Recuperado el 03 de Febrero de 2014, de Ingeniería del So1ware II. Tema 08. Mantenimiento de Sistemas Software: http://ocw.unican.es/ensenanzas-tecnicas/ingenieria-del-software-ii/materiales/tema8-mantenimientoSistemasSoftware.pdf
Descargar "Mantenimiento de Software"

viernes, 29 de noviembre de 2013

Lexuz, un sistema distribuido

Un Sistema Distribuido es un sistema de computadoras en interconexión, que se comportan como una sola a pesar de estar compuestas por varios elementos. Al estar todas ellas en una red, el usuario puede consultar información sin importar si ésta se originó en otra computadora, ya que todas pueden tener acceso a la misma información y a los mismos procesos.
Este es el objetivo de los sistemas distribuidos, el establecer una comunicación Cliente-Servidor y el compartimiento de recursos de manera eficiente, segura y rápida. Todo esto se logra mediante el uso de mensajes entre las partes.
Lexuz es distribuido porque se compone de un servidor, en el cual se encuentra la base de datos y el programa ejecutándose, y de varios clientes, desde donde se puede accesar al sistema sin necesidad de tener la base de datos o el programa ejecutándose en la maquina cliente.
Esto se logra ya que se comunican utilizando la IP del servidor, se conectan a este y pueden obtener información generada por otra maquina cliente y ejecutar procesos.

miércoles, 20 de noviembre de 2013

Juego Distribuido

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ServidorTCP {
 private static final int INACTIVO = 0;
 private static final int JUGANDO = 1;
 private static final int GANO = 2;
 private static final int PERDIO = 3;
 private static final int SOLICITANDO_JUEGO_NUEVO = 4;
 private static final int nroPuerto = 8080;
 private static boolean SocketDisponible = true;
 private static int conexionesRealizadas = 0;
 private static Socket con;
 private static int estadoJuego = INACTIVO;
 private static char letra = '?';
 private static String palabra = "?";
 private static String palabraEnProgreso = "?";
 private static int nroIntentos = 6;
 static private final String[] palabrasAhorcado = {"reingenieria", "cubeta","tunelizacion", "protocolo", "puertos", "conexion", "broadcasting", "direccion","internet", "router", "switch", "wifi", "estandar", "socket", "transporte","enlace", "capas", "arquitectura", "cliente", "servidor", "proxy", "firewall","redes", "LAN", "WAN", "MAN", "hub", "concentrador", "datagrama", "puente","fibra", "TCP", "UDP", "mascara", "gateway", "servidor", "DNS", "cliente","conmutacion", "circuito", "satelite", "coaxial", "microondas", "señal","ingrarrojos", "token", "anillo", "bus", "control", "flujo", "congestion","enrutamiento", "aplicacion", "correo", "peertopeer", "reingenieria", "cubeta","tunelizacion", "protocolo", "puertos", "conexion", "broadcasting", "direccion","internet", "router", "switch", "wifi", "estandar", "socket", "transporte","enlace", "capas", "arquitectura", "cliente", "servidor", "proxy", "firewall","redes", "LAN", "WAN", "MAN", "hub", "concentrador", "datagrama", "puente","fibra", "TCP", "UDP", "mascara", "gateway", "servidor", "DNS", "cliente","conmutacion", "circuito", "satelite", "coaxial", "microondas", "señal","ingrarrojos", "token", "anillo", "bus", "control", "flujo", "congestion","enrutamiento", "aplicacion", "correo", "peertopeer"};
 private static int nroMensaje = 0;
 public static void main(String[] args) throws IOException {
     ServerSocket socketDeServicio = null;
  try {
      socketDeServicio = new ServerSocket(nroPuerto);
   BufferedReader entrada;
   DataOutputStream salida;
   while (true) {
      try {
          if (SocketDisponible) {
          //EL SOCKET ESTA DISPONIBLE, POR LO TANTO NO SE ESTA EN JUEGO
       if (estadoJuego == INACTIVO) {
           System.out.println("\nEsperando cliente...");
        con = socketDeServicio.accept();
        System.out.println("Conexion aceptada...\n");
        salida = new DataOutputStream(con.getOutputStream());
        entrada = new BufferedReader(new InputStreamReader(con.getInputStream()));
        conexionesRealizadas++;
        System.out.println("Servidor : Conexion aceptada a Cliente " +conexionesRealizadas);
        /*leer primer mensaje, peticion de inicio de juego desde el cliente.*/
        leerMensaje(entrada.readLine());
        // imprimirEntrada();
        procesarMensaje();
        salida.writeBytes(responderMensaje());
        // imprimirSalida();
        }} else {
         entrada = new BufferedReader(new InputStreamReader(con.getInputStream()));
         salida = new DataOutputStream(con.getOutputStream());
         //EL SOCKET ESTA OCUPADO, POR LO TANTO SE ESTA EN JUEGO
         if (estadoJuego == JUGANDO) {
         leerMensaje(entrada.readLine());
         // imprimirEntrada();
         procesarMensaje();
         salida.writeBytes(responderMensaje());
         // imprimirSalida();
         if (estadoJuego == GANO || estadoJuego == PERDIO) {
         estadoJuego = INACTIVO;SocketDisponible = true;
         System.out.println("Juego numero " + conexionesRealizadas + "Terminado.");
         }}}
       } catch (java.net.SocketException e) {
        System.out.println("Termino abrupto de la comunicacion con el cliente.");
     estadoJuego = INACTIVO;
     SocketDisponible = true;
     System.out.println("Juego numero " + conexionesRealizadas + " Terminado.");}}
   } catch (IOException BindException) {
       System.out.println("La maquina virtual de java ya esta ocupando el socket"+ "en ese puerto, intente iniciar el servicio con otro puerto");}}
   
private static void leerMensaje(String mensaje) {
            StringTokenizer stk = new StringTokenizer(mensaje, "#");
   while (stk.hasMoreTokens()) {
       estadoJuego = Integer.valueOf(stk.nextToken());
    nroIntentos = Integer.valueOf(stk.nextToken());
    letra = stk.nextToken().toUpperCase().charAt(0);
    palabraEnProgreso = stk.nextToken().toUpperCase();
    nroMensaje = Integer.valueOf(stk.nextToken());}
   nroMensaje++;}
  
private static void procesarMensaje() {
            if (estadoJuego == SOLICITANDO_JUEGO_NUEVO) {
       setSocketDisponible(false);
    setEstadoJuego(JUGANDO);
    setNroIntentos(6);
    setLetra('?');
    setPalabra(escojerPalabraJuegoNuevo());
    setPalabraEnProgreso();
   } else {
     if (estadoJuego == JUGANDO) {
         if (huboAcierto()) {
       reemplazarLetra();
       if (ganoJuego()) {estadoJuego = GANO;
       System.out.println("Servidor : Cliente ha ganado el juego");}
             else {System.out.println("Servidor : Cliente ha acertado la palabra");}}
         else {
      nroIntentos--;
      System.out.println("Servidor : Se le ha disminuido un intento al cliente por no haber acertado");
      if (nroIntentos == 0) {
       estadoJuego = PERDIO;
       System.out.println("Servidor : Cliente ha perdido el juego");}}}
      else {
        try {
         System.out.println("Servidor : cerrando conexion...");
      con.shutdownOutput();
      SocketDisponible = true;
      System.out.println("Servidor : Conexion finalizada.");
     } catch (IOException ex) {
       Logger.getLogger(ServidorTCP.class.getName()).log(Level.SEVERE, null, ex);}}}
 }
private static String responderMensaje() {
            String a = estadoJuego + "#" + nroIntentos + "#" + letra + "#" + palabraEnProgreso + "#" +nroMensaje + "\n";
   return a;}
  
public static void setSocketDisponible(boolean SocketDisponible) {
           ServidorTCP.SocketDisponible = SocketDisponible;
  }
 
public static void setConexionesRealizadas(int conexionesRealizadas) {
          ServidorTCP.conexionesRealizadas = conexionesRealizadas;}
   
public static void setEstadoJuego(int estadoJuego) {
          ServidorTCP.estadoJuego = estadoJuego;}
   
public static void setLetra(char letra) {
          ServidorTCP.letra = letra;}
   
public static void setNroIntentos(int nroIntentos) {
          ServidorTCP.nroIntentos = nroIntentos;}
   
public static void setPalabra(String palabra) {
          ServidorTCP.palabra = palabra;}
   
public static void setPalabraEnProgreso(String palabraEnProgreso) {
           ServidorTCP.palabraEnProgreso = palabraEnProgreso;}
    
private static String escojerPalabraJuegoNuevo() {
          return palabrasAhorcado[(int) (Math.random() * palabrasAhorcado.length)];}
   
private static void setPalabraEnProgreso() {
          String p = "";
    for (int i = 0; i < palabra.length(); i++) {
        p += "_";}
     palabraEnProgreso = p;}
    
private static boolean huboAcierto() {
         boolean tuvoAcierto = true;
   //PRIMERO DEBEMOS COMPROBAR QUE LA LETRA NO SE REPITA CON LO QUE YA TENEMOS COMPLETADO ACTUALMENTE
   tuvoAcierto = !seRepite(letra, palabraEnProgreso) && esParteDeLaPalabra(letra, palabra);
   return tuvoAcierto;}
  
private static boolean seRepite(char l, String enProgreso) {
         boolean repite = false;
   char[] prog = enProgreso.toCharArray();
   for (int i = 0; i < prog.length; i++) {
       if (l == prog[i]) {repite = true;}}
      return repite;}
  
private static boolean esParteDeLaPalabra(char letra, String palabra) {
         boolean esParte = false;
   char[] pa = palabra.toUpperCase().toCharArray();
   for (int i = 0; i < pa.length; i++) {
       if (letra == pa[i]) {esParte = true;}}
  return esParte;}
 
private static void reemplazarLetra() {
         String[] enProg = palabraEnProgreso.split("");
   String[] pal = palabra.split("");
   String reemplazada = "";
   for (int i = 0; i < pal.length; i++) {
       if (String.valueOf(letra).equalsIgnoreCase(pal[i])) {
        enProg[i] = String.valueOf(letra);}
       reemplazada += enProg[i];}
   palabraEnProgreso = reemplazada;}
  
private static boolean ganoJuego() {
         if (palabraEnProgreso.equalsIgnoreCase(palabra)) {
   return true;}
   else {return false;}}
  
private static String mostrarEstado() {
    if (estadoJuego == 0) {return "INACTIVO";}
 else {if (estadoJuego == 1) {
    return "JUGANDO";}
 else {if (estadoJuego == 2) {
     return "GANO";}
    else {if (estadoJuego == 3) {
     return "PERDIO";}
 else {if (estadoJuego == 4) {
     return "SOLICITANDO_JUEGO_NUEVO";}
 else {
     return "JUEGO_TERMINADO";}}}}}}
 
private static void imprimirEntrada() {
    String a = estadoJuego + "#" + nroIntentos + "#" + letra + "#" + palabraEnProgreso + "#" +nroMensaje;
 System.out.println("\nLeído por Servidor: " + a + "\n" + mostrarEstado());}

private static void imprimirSalida() {
    String a = estadoJuego + "#" + nroIntentos + "#" + letra + "#" + palabraEnProgreso + "#" +nroMensaje;
 System.out.println("\nEnviado por Servidor: " + a + "\n" + mostrarEstado());}

}

Juego Ahorcado Distribuido

Interfaz del Ahorcado:

public interface ClienteAhorcadoint{
 
 public  void enviarMensaje();
 public  String crearMensajeRespuesta();
 public  int getEstadoJuego();
 public  char getLetra();
 public  int getNroIntentos();
 public  String getPalabraEnProgreso();
 public  void setEstadoJuego(int estadoJuego);
 public  void setLetra(char letra);
 public  void leerMensaje(String mensaje);
 public  void imprimirMensajeEnPantalla();
 public String getPalabraActualGuionBajo();
 public  String mostrarEstado();
 public  void imprimirEntrada();
 public  void imprimirSalida();
}
 

Implementación de la Interfaz del Ahorcado:

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.StringTokenizer;

public class ClienteAhorc implements ClienteAhorcadoint {
private static final int INACTIVO = 0;
private static final int JUGANDO = 1;
private static final int GANO = 2;
private static final int PERDIO = 3;
private static final int SolicJuegoNuevo = 4;
private static final int JuegoTerminado = 5;
private static final int puerto = 10028;
private static BufferedReader in = null;
private static DataOutputStream out = null;
private static Socket conexion;
private static int edoJuego = INACTIVO;
private static int intentRest = 6;
private static char letra = '*';
private static String palabraEnProgreso = "*";
private static Integer numMensaje = 0;
public static void main(String[] args) {
try {
     ClienteAhorc Ahcd = new ClienteAhorc();
     conexion = new Socket("192.168.15.132", 10028);
  BufferedReader entradaUsuario = new BufferedReader(new InputStreamReader(System.in));
  System.out.println("Iniciando Conexion con servidor...");
  in = new BufferedReader(new InputStreamReader(conexion.getInputStream()));
  out = new DataOutputStream(conexion.getOutputStream());
  System.out.println("Conexion realizada...");
  boolean jugando = true;
  while (jugando == true) {
      if (edoJuego == INACTIVO) {
       Ahcd. setEstadoJuego(SolicJuegoNuevo);
    Ahcd.enviarMensaje();
    } else {
       Ahcd.leerMensaje(in.readLine());
       if (edoJuego == JUGANDO) {
     Ahcd.imprimirMensajeEnPantalla();
     System.out.println("Ingrese una letra: ");
     Ahcd.setLetra(entradaUsuario.readLine().charAt(0));
     Ahcd.enviarMensaje();
     } else {
        if (edoJuego == GANO) {
        Ahcd. setEstadoJuego(JuegoTerminado);
        Ahcd.imprimirMensajeEnPantalla();
        jugando = false;
        System.out.println("¡Felicidades! Ganaste en el juego de Ahorcado");
        }
        if (edoJuego == PERDIO) {
         Ahcd. setEstadoJuego(JuegoTerminado);
         Ahcd.imprimirMensajeEnPantalla();
         jugando = false;
         System.out.println("Lastima, no te quedan mas intentos.\nHas perdido");
        }
      System.out.println("Juego terminado");
       }
    }
   }
 }catch (IOException ex) {
    System.out.println("Error de Entrada/Salida");
    System.out.println("No fue posible realizar la conexion, posiblemente el servidor este inactivo.");
    }
}

public  void enviarMensaje() {
  ClienteAhorc Ahcd = new ClienteAhorc();
  try {
     if (edoJuego == SolicJuegoNuevo) {
      out.writeBytes(Ahcd.crearMensajeRespuesta());
  } else {
   out.writeBytes(Ahcd.crearMensajeRespuesta());
   }
 }catch (IOException iOException) {
     System.out.println("Error al enviar el mensaje");
  }
}
 
public  String crearMensajeRespuesta() {
    return edoJuego + "#" + intentRest + "#" + letra + "#" + palabraEnProgreso + "#" +numMensaje + "\n";
 }

public  int getEstadoJuego() {
    return edoJuego;
 }

public  char getLetra() {
    return letra;
 }

public  int getNroIntentos() {
    return intentRest;
 }
public  String getPalabraEnProgreso() {
    return palabraEnProgreso;
 }
public  void  setEstadoJuego(int edoJuego) {
    ClienteAhorc.edoJuego = edoJuego;}
public  void setLetra(char letra) {
    ClienteAhorc.letra = letra;
 }
public  void leerMensaje(String mensaje) {
  StringTokenizer stk = new StringTokenizer(mensaje, "#");
  while (stk.hasMoreTokens()) {
      edoJuego = Integer.valueOf(stk.nextToken());
   intentRest = Integer.valueOf(stk.nextToken());
   letra = stk.nextToken().charAt(0);
   palabraEnProgreso = stk.nextToken();
   numMensaje = Integer.valueOf(stk.nextToken());
   }
 }
  
public  void imprimirMensajeEnPantalla() {
    ClienteAhorc Ahcd = new ClienteAhorc();
 System.out.println("^^^^^^^^^^^ Ahorcado ^^^^^^^^^^^");
 imprimirAhorcado(intentRest);
 System.out.println("\nPalabra actual: " + Ahcd.getPalabraActualGuionBajo());
 System.out.println("Intentos restantes: " + intentRest);
 }
public  String getPalabraActualGuionBajo() {
    String[] a = palabraEnProgreso.split("");
 String impr = "";
 for (int i = 0; i < a.length; i++) {
     impr += a[i] + " ";}
 return impr;
 }

public  String mostrarEstado() {
    if (edoJuego == 0) {
     return "INACTIVO";}
    else {
     if (edoJuego == 1) {
  return "JUGANDO";}
 else {
     if (edoJuego == 2) {
  return "GANO";}
 else {
     if (edoJuego == 3) {
  return "PERDIO";}
 else {
     if (edoJuego == 4) {
  return "SolicJuegoNuevo";}
 else {
     return "JuegoTerminado";}}}}}}

public  void imprimirEntrada() {
    ClienteAhorc Ahcd = new ClienteAhorc();
    String a = edoJuego + "#" + intentRest + "#" + letra + "#" + palabraEnProgreso +"#" + numMensaje;
 System.out.println("Leido por el cliente: " + a + "\n" + Ahcd.mostrarEstado());}

public  void imprimirSalida() {
    ClienteAhorc Ahcd = new ClienteAhorc();
    String a = edoJuego + "#" + intentRest + "#" + letra + "#" + palabraEnProgreso +"#" + numMensaje;
 System.out.println("Enviado por el cliente: " + a + "\n" + Ahcd.mostrarEstado());}
public  void imprimirAhorcado(int intentRest) {
    System.out.println(" ________________");
 if (intentRest < 1) {
  System.out.println("|   |");
  System.out.println("|   |");
  System.out.println("|   O");
  System.out.println("|  \\|/");
  System.out.println("|   |");
  System.out.println("|  /|\\");
  System.out.println("|");
  System.out.println("|");
  System.out.println("|");
  }
 else {
     if (intentRest < 2) {
  System.out.println("|   |");
  System.out.println("|   |");
  System.out.println("|   O");
  System.out.println("|  \\|/");
  System.out.println("|   |");
  System.out.println("|  /|");
  System.out.println("|");
  System.out.println("|");
  System.out.println("|");
   }
 else {
      if (intentRest < 3) {
  System.out.println("|   |");
  System.out.println("|   |");
  System.out.println("|   O");
  System.out.println("|  \\|/");
  System.out.println("|   |");
  System.out.println("|   |");
  System.out.println("|");
  System.out.println("|");
  System.out.println("|");
   }
 else {
      if (intentRest < 4) {
  System.out.println("|   |");
  System.out.println("|   |");
  System.out.println("|   O");
  System.out.println("|  \\|");
  System.out.println("|   |");
  System.out.println("|   |");
  System.out.println("|");
  System.out.println("|");
  System.out.println("|");
   }
 else {
      if (intentRest < 5) {
  System.out.println("|  |");
  System.out.println("|  |");
  System.out.println("|  O");
  System.out.println("|  |");
  System.out.println("|  |");
  System.out.println("|  |");
  System.out.println("|");
  System.out.println("|");
  System.out.println("|");
   }
 else {
      if (intentRest < 6) {
  System.out.println("|  |");
  System.out.println("|  |");
  System.out.println("|  O");
  System.out.println("|");
  System.out.println("|");
  System.out.println("|");
  System.out.println("|");
  System.out.println("|");
  System.out.println("|");
   }
 else {
      if (intentRest < 7) {
  System.out.println("|  |");
  System.out.println("|  |");
  System.out.println("|");
  System.out.println("|");
  System.out.println("|");
  System.out.println("|");
  System.out.println("|");
  System.out.println("|");
  System.out.println("|");
   }}}}}}}
 System.out.print("----------------------------");}
}

domingo, 8 de septiembre de 2013

Modelo OSI

Introducción.

Como ya vimos antes, la comunicación entre personas necesita de unos pasos a seguir, y la comunicación entre dispositivos en red también los necesita, solo que se conocen como protocolos. El protocolo de comunicación que usaremos es el modelo OSI, que se compone de siete capas que se describirán hoy. Sin embargo, primero es importante saber que es un protocolo de comunicación y uno compuesto de capas.

Protocolo de comunicación.
Un protocolo de comunicación es una serie de lineamientos y reglas estrictas de procedimientos cuya función sea que el intercambio de datos entre componentes a través de la red sea de forma ordenada (Pérez, 2003).

Protocolos de comunicación de capas.
Los protocolos de comunicación de capas están implementados para la operación de sistemas abiertos, esto significa que todos los sistemas serán compatibles, y que la interconexión de redes será viable. Su objetivo es definir las funciones de telecomunicaciones y separarlas en conjuntos (capas) de subfunciones. Cada capa realiza una tarea distinta y autosuficiente, sin embargo, depende de las capas inferiores.

La mayoría de los protocolos de transferencia de datos de uso actual utilizan protocolos de capas. Cada capa se comunica con su igual en el otro sistema por medio de un protocolo. Sin embargo, la comunicación se da usando los servicios de la capa inferior. La comunicación entre una capa y su antecesora se conoce como interfaz. Así, cada capa presta sus servicios a la capa superior y utiliza los de la capa inferior. La información fluye de manera “lógica” horizontalmente usado protocolos, y en “forma real” verticalmente sobre interfaces. Un protocolo conecta siempre dos entidades al mismo nivel, mientras que la interfaz acopla capas de una misma entidad (Pérez, 2003).

Modelo OSI.

El modelo de Interconexión de sistemas abiertos (OSI: Open Systems Interconnection) fue diseñado por la Organización para la Estandarización Internacional (ISO: International Standard Organization) y permite que dos sistemas distintos se comuniquen sin importar su arquitectura. Se compone de siete capas, cada una con funcionalidades independientes pero relacionadas.


Modelo de interconexión de sistemas abiertos (OSI).
La figura siguiente muestra la transmisión de datos de un dispositivo A a uno B. Antes de que se envíen los daos al medio de trasmisión, estos se desplazan había abajo a través de las siete capas hasta llegar  a la física. En cada capa se añade información de control a los datos en forma de encabezados (headers) o caracteres de control (trailers). Los encabezados se añaden a los datos en las capas 7, 6, 5, 4, 3 y 2, mientras que los caracteres de control se añaden en la capa 2. En la maquina receptora, el encabezado y los caracteres de control se dejan caer mientras se avanza hacia la capa 7.



A continuación se describen brevemente las funciones de cada capa.
1.  Capa Física. Es la responsable de trasmitir los datos en forma de señales (grupos de bits) a través de un medio físico de un dispositivo a otro.

2.  Capa de Enlace de datos. Organiza los grupos de bits en unidades lógicas llamadas bloques de datos (frames). Añade un encabezado y caracteres de control que definen el bloque e información que define su direccionamiento. Además puede detectar errores en los datos y corregirlos

3.  Capa de Red. Envía los paquetes de datos al exterior, independientes uno del otro. Es responsable de la entrega de un nodo a otro de los paquetes de datos entre el origen y su destino final a los que les agrega un encabezado que contiene una dirección de origen y una destino (dirección lógica o IP, que permanece intacta).

4.  Capa de Transporte. Es el responsable de asegurar que se transmita del origen al destino el mensaje completo (conjunto de paquetes de datos). Se encarga de dividir el mensaje en paquetes y entregarlos a la capa de red.

5.  Capa de Sesión. Establece, mantiene y sincroniza el dialogo entre los sistemas. Añade puntos de sincronización que respaldan la entrega de los mensajes en caso de un fallo en la red. Estos puntos de sincronización dividen un mensaje largo en partes de mensaje, para que en caso de fallo no se reenvíe el mensaje completo, sino se desplace al último punto de sincronización y comenzar desde ahí.

6.  Capa de Presentación. Se encarga de darle una misma sintaxis (formato) y semántica (significado) a la información intercambiada. Comprime y descomprime los datos para conseguir un mejor rendimiento y los cifra y descifra por motivos de seguridad.

7.  Capa de Aplicación. Permite que el usuario (persona o software) accese a la red mediante servicios que simplifiquen el trabajo del usuario.


Conclusión.

Como ya vimos, el modelo OSI se creó para estandarizar la comunicación y transmisión de datos entre los dispositivos de una red. Este modelo lo ocupamos siempre que utilizamos aplicaciones que necesitan la comunicación entre nosotros y otra persona en otro lugar, y esto se da mediante el uso de una red. Es importante conocer y manejar cada capa de este modelo ya que lo utilizaremos a lo largo del curso.

Referencias.

Forouzan, B. A., & Chung Fegan, S. (2003). Foundations of computer science: from data manipulation to theory of computation. Estados Unidos: Brooks Cole.

Pérez, E. H. (2003). Tecnologías y Redes de transmisión de datos. México: Editorial Limusa.