¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. Desarrollo informático
  3. Programación de la red
Extrait - Desarrollo informático Aprenda a diseñar antes de programar
Extractos del libro
Desarrollo informático Aprenda a diseñar antes de programar Volver a la página de compra del libro

Programación de la red - Arquitectura 3 tiers

Objetivos del capítulo

  • Diseñar y desarrollar un servidor de objetos serializables.

  • Desarrollar aplicaciones cliente para este servidor.

Un objeto serializable se puede escribir en un workflow, usando el método writeObject() de la clase ObjectOutputStream. Un algoritmo de serialización permite codificarlo. Se obtiene una sucesión de bytes, que es posible descodificar y transformar como un objeto. Esto es lo que hace el método readObject() de la clase ObjectInputStream. En Java, un objeto serializable es un objeto de una clase que implementa la interfaz Serializable.

Definiciones

1. Servidor

Un servidor es una aplicación que «escucha» la red. Es capaz de leer las consultas de un programa cliente y responderle.

Esta noción de servidor es ambigua. Para un desarrollador, se trata de un programa. Para un administrador de red, el término servidor puede hacer referencia a la máquina que alberga el programa servidor.

2. Protocolo

Un cliente y un servidor pueden cambiar mensajes. De nuevo hace falta que se entiendan. Si no hablan el mismo lenguaje, se comunicarán mal.

Por este motivo se definen los protocolos que permiten estandarizar los mensajes. Los protocolos definen la sintaxis de los mensajes intercambiados por un cliente y un servidor.

De esta manera, los mensajes enviados a un servidor web deben respetar el protocolo HTTP. De vuelta, el servidor web responde en un lenguaje que es comprensible e interpretado por un navegador web, en general HTML.

Programación de los «sockets»

1. Presentación

La programación de los sockets permite a una aplicación comunicarse con otra aplicación, que se ejecuta eventualmente en otro ordenador.

Por medio de órdenes de escritura, podemos enviar mensajes. Usando órdenes de lectura, podemos leer mensajes.

Una aplicación cliente puede enviar consultas a un servidor y leer sus respuestas. Una aplicación servidor puede leer las consultas de un cliente y enviarle las respuestas.

2. Programa de acceso a un servidor web

El siguiente programa se comunica con un servidor web instalado localmente en el puerto 8080.

Un puerto permite identificar diferentes programas informáticos que se ejecutan en un ordenador. Un puerto se distingue por su número.

El programa:

  1. se conecta al servidor web,

  2. envía al servidor una consulta en formato HTTP,

  3. muestra en la consola el código HTML de la página devuelta por el servidor, en respuesta a la consulta.

public class SocketWeb  
{  
   public static void main(String argv[])  
   {  
       Socket socketCliente;  
       BufferedReader entrada;  
       PrintWriter salida;  
       String fila;  
  
       try  
   ...

Implementación de servidores de aplicaciones

1. Elección del nombre de las variables

En todos los ejemplos siguientes, hemos realizado programas «servidor» y programas «cliente». El programa «servidor» tiene un objeto de tipo ServidorSocket que «escucha» la red y espera las conexiones de los clientes. El programa «servidor» y el programa «cliente» se comunican con objetos Socket.

Vamos a tener que hacer elecciones sobre el nombre de variables:

En el programa servidor:

  • el objeto ServidorSocket se llama «servidor» porque es el que «escucha»,

  • el objeto Socket se llama «socketServidor».

En el programa cliente:

  • el objeto Socket se llama «socketCliente»

2. ServerSocket

Un objeto ServerSocket espera las consultas que llegan de la red. El programa servidor instancia un objeto ServerSocket:

. . .  
ServerSocket servidor = new ServerSocket(8189);  
. . . 

El programa servidor es accesible en el puerto 8189 de la máquina. Espera que un cliente se conecte gracias al método accept() de la clase ServerSocket:

. . .  
Socket socketServidor = servidor.accept();  
. . . 

Este método bloquea el programa hasta que un cliente se conecta. Entonces devuelve la referencia de un objeto Socket que permite dialogar con el cliente.

Un programa cliente se conecta al servidor ejecutando la instrucción:

Socket socketCliente = new Socket("localhost", 8189); 
images/1_215.png

El objeto socketCliente del programa cliente y el objeto socketServidor del programa servidor correspondiente.

  • El workflow de salida del cliente se corresponde con el workflow de entrada del servidor.

  • El workflow de entrada del cliente se corresponde con el workflow de salida del servidor.

images/2_215.png

3. Un servidor simple y su cliente

a. El servidor

El siguiente programa servidor tiene el comportamiento que se muestra a continuación: 

  • Instancia el objeto ServerSocket.

  • Espera una conexión del cliente: accept().

  • Cuando un cliente se conecta, le envía un mensaje de bienvenida.

  • Entonces lee un mensaje del cliente y se detiene. Los textos intercambiados se codifican en UTF-8.

  • Si el cliente no se conecta en 10 segundos, el servidor se detiene.

public class ServidorSimple  
{  
   public static void main(String argv[])  
   {  
     ...

Trabajo práctico: Proyecto ServidorObjetos

1. Objetivos

  • Diseñar y desarrollar en Java un servidor de aplicaciones conectado a una base de datos.

  • Desarrollar una aplicación en una arquitectura 3 tiers.

2. Arquitectura del proyecto: 3 tiers

images/14_215.png

El interés de esta arquitectura es que los clientes se conectan al servidor de objetos, en lugar de conectarse directamente al servidor base de datos.

El servidor de datos está separado de los clientes, que no lo conocen.

  • La seguridad de los datos es más fácil de garantizar de esta manera.

  • Solo el servidor de objetos se conecta a la base de datos, lo que aligera el trabajo del servidor de datos.

3. Tema

a. Ventana gráfica del servidor

A partir del servidor multithread de la sección anterior, desarrollar un servidor de objetos que presente la vista siguiente:

images/15_215.png

El botón ON/OFF permite arrancar y detener el servidor. La zona de texto permite seguir las conexiones y las consultas de los clientes.

b. Funcionamiento del servidor

Cuando el servidor se enciende:

  • Espera una conexión del cliente: accept().

  • Cuando un cliente se conecta, el servidor lanza un thread «cliente» para dialogar con él. 

  • El thread «cliente»:

  • Lee la consulta enviada por el cliente.

  • Envía la respuesta al cliente.

  • Se detiene.

c. Protocolo de intercambio entre el cliente y el servidor

La consulta del cliente es un objeto String. Contiene un texto en formato SQL

Ejemplo: SELECT * FROM CONTACTO

La respuesta enviada al cliente está formada por dos objetos:

  • Un primer objeto de tipo Integer, que puede tomar los valores 0, 1 o 2.

  • Un segundo objeto cuyo tipo depende del valor del primero:

  • Si el primer objeto vale 0, es un String el que contiene un mensaje de error.

  • Si el primer objeto vale 1, es un JuegoResultado el que contiene el resultado de la SELECT.

  • Si el primer objeto vale 2, es un Integer el que contiene el número de filas modificadas (UPDATE, INSERT, DELETE).

d. Programa proporcionado

El programa ClientServidorObjetos permite comprobar el servidor.

public class ClientServidorObjetos  
{  
   public static void main(String argv[])  
   {  
       Socket socketCliente;  
       ObjectInputStream entrada;  
       ObjectOutputStream salida;  
  
   ...

Trabajo práctico: Proyecto GestionContactoRed

1. Objetivo

  • Crear un cliente gráfico que reciba información del servidor de objetos.

2. Pantallas del cliente y del servidor

images/18_215.png

3. Tema

a. Presentación

La aplicación GestionContactoJdbc del capítulo JDBC - Mapping Objeto/Relacional accede directamente a la base de datos. Para esto utiliza las clases BaseDeDatos y AccesBase del paquete herramientasMG.jdbc.

La aplicación GestionContactoRed accede al servidor de objetos.

  • La clase socketServidor sustituye a BaseDeDatos.

Un objeto de la clase socketServidor referencia a un servidor de objetos. Su constructor recibe la dirección IP y el puerto del servidor.

  • La clase AccesServidor sustituye a AccesBase. Tiene los siguientes métodos:

  • AccesServidor(socketServidor toma)

  • socketServidor getToma ()

  • Socket getConnection() throws IOException

  • void closeConnection() throws IOException

  • JuegoResultado executeQuery(String select) throws IOException, ClassNotFoundException

  • Integer executeUpdate(String consulta) throws IOException, ClassNotFoundException

Atención: durante cada llamada a un método de AccesServidor, se debe abrir y cerrar la conexión al servidor. En efecto, el servidor abre un Socket durante la recepción de la consulta del cliente, ejecuta la consulta, envía el resultado y cierra el Socket. No se puede conservar la conexión.

b. Trabajo

El objetivo de las siguientes sugerencias es limitar el trabajo que hay que realizar.

  • Volver a copiar las clases de la aplicación GestionContactoJdbc en la aplicación GestionContactoRed.

  • Gracias al diseño MVC, la ventana de la aplicación no se modifica.

  • Se modifican los controladores y las clases DAO.

  • Duplicar el paquete herramientasVarios.daoJdbcMapping en herramientasVarios.daoServidorObjetos.

  • Escribir las clases socketServidor y AccesServidor y añadirlas al paquete herramientasVarios.daoServidorObjetos.

  • Las clases ContactoDAO, PagoDAO, SectorDAO se deben adaptar para leer los datos desde el servidor de objetos: sustituir las referencias de tipo AccesoBase por referencias de tipo AccesoServidor. También habrá que sustituir las SQLException generadas por los métodos de AccesoBase por las IOExceptionClassNotFoundException, generadas por los métodos de AccesServidor

c. Diagrama de secuencia

images/19_215.png

4. Proyecto GestionContactoRed: propuesta de corrección

a. Clase...