Beruflich Dokumente
Kultur Dokumente
(1 Parte de 3)
Introduccin a las redes, a java.io, java.zip, java.net,
java.nio, a RMI y a CORBA
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
La imagen de la pgina anterior corresponde a un goteado de Jackson Pollock y el copyright pertenece a sus herederos o a
cualquier institucin que los represente. Se reproduce sin nimo de lucro.
- 2/313 -
http://www.javahispano.org
Pgina 5
Pgina 15
- 3/313 -
Pgina 15
Pgina 22
Pgina 23
Pgina 33
Pgina 49
Pgina 52
Pgina 55
Pgina 55
Pgina 56
Pgina 67
Pgina 69
Pgina 70
Pgina 70
Pgina 70
Pgina 71
Pgina 77
Pgina 90
Pgina 100
Pgina 101
Pgina 106
Pgina 117
Pgina 131
Pgina 139
Pgina 141
Pgina 143
Pgina 146
Pgina 148
Pgina 150
Pgina 156
Pgina 156
Pgina 175
Pgina 180
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 4/313 -
Pgina 189
Pgina 189
Pgina 194
Pgina 194
Pgina 203
Pgina 205
Pgina 209
Pgina 215
Pgina 230
Pgina 248
Pgina 250
Pgina 250
Pgina 252
Pgina 256
Pgina 259
Pgina 282
Pgina 285
Pgina 286
http://www.javahispano.org
(1 Parte de 3)
Fecha de creacin: 27.07.2004
Miguel ngel Abin
mabian AT aidima DOT es
Copyright (c) 2004, Miguel ngel Abin. Este documento puede ser distribuido slo
bajo los trminos y condiciones de la licencia de Documentacin de javaHispano v1.0
o posterior (la ltima versin se encuentra en http://www.javahispano.org/licencias/).
Many web generations ago, the ARPA knights started a revolution against the
telco circuit-switching empire and determined to destroy the death stars and
their twisted pairs. I was one of those knights when our leader Vint Cerf, Father
of the Internet, crossed over to the telco side of the force. Cerf Vader and
legions of imperial stormlawyers are now defending the death stars against the
insignificant ispwoks. The previous speaker in this forum series, the Father of
the Web, Tim-Berners-Lee-Po --who speaks over 6,000,000,000 dialects-- has
been captured by Java the Hutt. You are Luke and Leia. The death stars must
be destroyed and I foresee it.
Bob Metcalfe, padre de Ethernet, rememora en clave cmica las batallas
contra AT&T
La decisin de hacer de la Web un sistema abierto fue necesaria para que
fuese universal. Si hubisemos patentado la tecnologa, probablemente, no
hubiera despegado. No puedes proponer que algo sea un espacio universal si,
al mismo tiempo, mantienes el control sobre ello.
Tim Berners-Lee
Hay dos grandes productos que vienen de Berkeley: LSD y [Unix] BSD. No
creemos que esto sea una coincidencia.
Jeremy S. Anderson
La red no es nada ms que una masa inerte de metal, plstico y arena. Somos
los nicos seres vivientes en el ciberespacio.
Richard Barbrook
1.- Introduccin
El propsito de este tutorial, dividido en tres partes, es desarrollar un panorama
general de las comunicaciones en red mediante Java, tanto para JDK 1.2-1.3 como
para JDK 1.4-1.5 (el JDK 1.5 se conoce ahora como 5.0), excluyendo los applets. Para
ello se explicarn con detalle cuatro paquetes de Java, as como las tecnologas RMI y
CORBA:
java.io
java.zip
java.net
java.nio (incorporado con JDK 1.4 y mantenido en JDK 1.5 o 5.0)
- 5/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Debido a como Java trata las comunicaciones en red, bien podra este tutorial
titularse Entrada y salida en Java. Parte de mi motivacin para escribirlo reside en
que no existe todava ningn libro que trate de forma sinrgica los cinco paquetes (al
menos, yo no he podido encontrarlo; mi bsqueda se ha limitado a libros en castellano,
ingls y francs). Los pocos textos que abordan de forma precisa los paquetes
java.nio o java.rmi no suelen presentar con detalle los otros, y viceversa. Aparte,
los pocos libros en castellano que proclaman cubrir las novedades de JDK 1.4
(oficialmente, Java 2 SDK standard version 1.4) caen de pleno en la categora de
Realidad, falta de adecuacin a.
Doy por hecho que el lector conoce la sintaxis de Java, las estructuras bsicas de
control y los hilos (threads). Si no es as, puede recurrir a los tutoriales de javaHispano.
Un buen comienzo son los tutoriales Java bsico con ejemplos, de Abraham Otero, y
Threads, de Scheme the API man (sic). Mi idea es dar unos cuantos ladrillos bsicos
para que cada uno pueda construir sus propios edificios virtuales, y proporcionar trucos
y consejos que no suelen explicarse en los textos ni en las aulas.
En el apartado 2 se introducen los fundamentos necesarios para entender los
conceptos utilizados en redes: protocolos, arquitecturas, sockets, puertos, etc. Aunque
el lector tenga conocimientos de redes, recomiendo su lectura para que sepa cul es la
terminologa que usar durante el resto del tutorial y su significado. Comprender qu
son los datagramas, los protocolos TCP/UDP y la API Socket explica el
comportamiento de las clases del paquete java.net, imprescindibles para desarrollar
con Java aplicaciones en red. El trabajo que se invierte en entender bien el
funcionamiento de las redes TCP/IP tiene sus dividendos: uno aprende enseguida a
manejar java.net.
Este apartado lo he escrito en pianissimo, pues tena que poner, una tras otra, las
bases para llegar al concepto de socket, que resulta fundamental para las
comunicaciones en red. Y no me refiero slo a las comunicaciones en red con Java:
este lenguaje usa el mismo modelo de sockets que el sistema operativo UNIX BSD,
modelo que ha devenido estndar de facto. He omitido intencionadamente cualquier
contenido relativo a la historia y desarrollo de Internet, pues resulta muy fcil acceder a
esa informacin mediante la propia red de redes.
La ltima parte del apartado est dedicada a varios servicios de la capa de
aplicacin (administracin de redes, transferencia de archivos, correo electrnico,
World Wide Web). En el apartado 8 veremos qu clases tiene Java para trabajar con
algunos de estos servicios.
En el apartado 3 se explica el paquete java.io. Casi todas las clases del
paquete
java.net
permiten
abrir
objetos
java.io.InputStream
o
java.io.OutputStream, que pueden usarse directamente para el intercambio de
datos. El trabajo en red con Java resulta asombrosamente sencillo: basta usar la clase
apropiada de java.net, extraer de ella un flujo de entrada o salida y escribir en el flujo
o leer de l. Dentro de apartado se hace especial hincapi en las clases derivadas de
java.io.Reader y java.io.Writer, indispensables para permitir comunicaciones
plurales en cuanto al lenguaje, y en el papel que desempea el patrn decorador como
estructura interna de java.io. Incluyo tambin algunos consejos para manejar este
paquete (cmo cerrar flujos, cmo tratar posibles excepciones en la E/S, etc.), adems
de unos cuantos ejemplos de uso para las situaciones ms frecuentes. Si el lector tiene
Miguel ngel Abin, Julio 2004
- 6/313 -
http://www.javahispano.org
- 7/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 8/313 -
http://www.javahispano.org
- 9/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 10/313 -
http://www.javahispano.org
- 11/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 12/313 -
http://www.javahispano.org
con que se nos ofrezcan los datos: una cantidad excesiva de datos sueltos, dispersos,
faltos de trabazn, no es informacin, del mismo modo que un montn de tableros no
constituye un mueble. Acumular datos sin ton ni son no es ciencia ni tecnologa, sino
algo muy distinto: filatelia. Creo que la escritura lineal sigue siendo importante para dar
sentido de conjunto a unos datos o hechos, para dotarlos de coherencia y argumento.
En una palabra, para transformarlos en verdadera informacin, en autntico
conocimiento. No niego que esta opinin viene motivada, probablemente, porque nac
antes de que existiera el hipertexto e Internet. Si el lector quiere interpretar mis
palabras como el lamento quejoso y moribundo de un ser anacrnico-analgico,
acatar gustoso su veredicto: desde nio he sentido simpata por el pjaro dodo.
La abundancia de datos inconexos no constituye el nico obstculo para la
bsqueda de informacin en Internet. Muchos servicios que ofrecen informacin se
comportan como algunos programas de televisin: prometen muchas, muchsimas
cosas en los anuncios previos a la emisin o en las pausas para la publicidad
(novedades informativas, entrevistas, actuaciones, regalos, cuerpos ligeros de ropa,
etc.), siempre enseguida, siempre ahora mismo, de modo que intentan mantener la
atencin del espectador que quiz piensa, desesperado y predispuesto al engao,
que la programacin va a mejorar por fin, pero al final no cumplen sus promesas o no
lo hacen como imaginaba el espectador.
As las cosas, este trabajo intenta evitar al lector el esfuerzo de extraer un vasito
de informacin a partir de la cascada de datos sobre redes y Java que ofrecen Internet
y la bibliografa tcnica. El resultado final, con sus aciertos y sus fallos, est ante sus
ojos. Si no le parece interesante, lo siento. Lo har mejor la prxima vez. Palabra.
- 13/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 14/313 -
http://www.javahispano.org
- 15/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 16/313 -
http://www.javahispano.org
Un servicio (de una red) es una funcin que presenta a sus usuarios.
Internet, por ejemplo, ofrece servicios de archivos, de correo
electrnico, de grupos de noticias, de foros, etc. Todo servicio ofrece un
conjunto de operaciones que el usuario puede aprovechar. As,
cualquier servicio de archivos ofrece leer, escribir, borrar, intercambiar y
enviar archivos.
Los URL (Uniform Resource Locator: localizador universal de
recursos) identifican cualquier servicio o recurso de una red. Un URL
identifica el ordenador de la red que proporciona el servicio o recurso e
identifica qu servicio o recurso solicita el usuario.
Una capa o nivel es una abstraccin que agrupa distintos problemas
de comunicaciones relacionados entre s.
Los paquetes (de datos) son unidades de datos en cualquier capa de
un conjunto de protocolos (la estratificacin en capas de los protocolos
se estudiar ms adelante). Todo paquete consta de dos partes: una
cabecera (donde se incluye la informacin de la mquina que lo origin
y de la mquina a la que va dirigido) y un rea de datos (donde va la
informacin).
Los datagramas son paquetes de datos de la capa IP o de red (se ver
en el apartado 2.3). A veces se usa datagrama como sinnimo de
paquete.
Una trama (frame) es un paquete preparado para su transmisin por
un medio fsico. El proceso de preparacin (entramado o framing)
suele consistir en aadir delimitadores para indicar el principio y fin del
paquete, as como campos de control. En una red Ethernet, verbigracia,
durante el proceso de entramado se convierten las direcciones IP en
direcciones fsicas o de Ethernet, asociadas al hardware.
Una trama fsica (physical frame) o trama de red fsica es un
paquete tal y como es transmitido en un medio fsico (fibra ptica,
ondas de radio, microondas, cable coaxial, cable de par trenzado, etc.).
Puede, por tanto, ser una secuencia de seales elctricas, pticas o
electromagnticas. Decir que una trama, un datagrama o un paquete
circula por una red equivale a decir que una trama fsica circula por ella,
y viceversa. Por ello, muchas veces se usa trama, datagrama o paquete
en lugar de trama fsica. En este tutorial usar paquete en el sentido
general descrito en la pgina anterior, reservar datagrama para los
paquetes de la capa de red, y escribir trama fsica cuando quiera
subrayar la conversin de bits en seales fsicas. He aqu varios
ejemplos de mi uso de estos trminos: La capa de red genera
datagramas; El paquete recorre todas las capas; El mdem convierte
las tramas en tramas fsicas.
Los encaminadores o encaminadores IP (routers o IP routers) son
dispositivos que encaminan los paquetes de datos entre subredes,
intentando encontrar el mejor camino posible para cada paquete.
Fsicamente, pueden ser dispositivos electrnicos que conectan entre s
subredes heterogneas (basadas en fibra ptica, Ethernet, etc.) o
anfitriones en los que se ha instalado software de encaminamiento.
Suele reservarse el trmino pasarela (gateway) para los dispositivos
Miguel ngel Abin, Julio 2004
- 17/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 18/313 -
http://www.javahispano.org
Figura 3. Una extranet muy sencilla. Dibujo escaneado de Daryl's TCP/IP Primer
- 19/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Red
principal
Red principal
Subred (regional,
nacional, etc.)
Subred (regional,
nacional, etc.)
- 20/313 -
http://www.javahispano.org
destino
origen
Tipo
Datos
CRC
0-1500
- 21/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 22/313 -
http://www.javahispano.org
- 23/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Espaol
Carta
Destino
Almacenamiento
Sobres y
sellos
Buzn
Transporte Barajas
Furgoneta
Sobre con
direccin
Charles de
Gaulle
- 24/313 -
http://www.javahispano.org
Por sencillas que nos parezcan las soluciones tengamos en cuenta que
cualquiera de nosotros sabe desde nio cmo funciona un servicio de correos, las
preguntas que hemos hecho se vuelven a plantear para el transporte de informacin
entre redes (el cual no solemos conocer desde nios).
Las soluciones descritas, que aparecen en azul, son protocolos. Dependiendo de
las circunstancias, se usar un protocolo u otro. As, si una carta tiene su origen y
destino en la misma ciudad, lo normal ser llevarla en motocicleta (al menos, eso me
ha asegurado el funcionario de Correos a quien he preguntado). Usar furgonetas o
motocicletas equivale a usar protocolos distintos para un mismo subproblema.
La estratificacin en capas de los protocolos es consecuencia lgica de la
estratificacin del problema en capas: todos los protocolos que resuelven
subproblemas de una misma capa se agrupan dentro de esa capa.
El desarrollo en capas de los protocolos de comunicaciones proporciona ventajas
substanciales. Por un lado, las capas permiten modelar y simplificar el estudio y
desarrollo de los protocolos, lo que facilita desarrollarlos. Por otro lado, la divisin de
los protocolos en capas fomenta la interoperabilidad.
Las dos mejores definiciones de interoperabilidad que conozco proceden del
proyecto IDEAS ("la capacidad de un sistema o un producto para trabajar con otros
sistemas o productos sin especial esfuerzo de parte del cliente") y de la norma ISO
16100 ("la capacidad para compartir e intercambiar informacin usando una sintaxis y
una semntica comunes para conseguir una relacin funcional especfica mediante el
uso de una interfaz comn").
La estratificacin en capas de los protocolos permite que un sistema que use los
protocolos de una capa N pueda comunicarse con otros sistemas que tambin usen
protocolos de esa capa, sin que importen los detalles exactos de las capas N-1, N-2,
etc., ni las diferencias entre ambos sistemas (arquitecturas, software, hardware,
perifricos, etc.). En consecuencia, dado un protocolo de la capa N, se pueden cambiar
las caractersticas internas de los protocolos de las capas inferiores, o cambiarlos por
otros, sin que se necesite modificar los de la capa N. Esta propiedad se encuadra a la
perfeccin dentro de las definiciones anteriores de interoperabilidad.
Nota: Por precisin, conviene sealar que la interoperabilidad derivada del uso de
capas es una interoperabilidad dbil. Nadie nos asegura que los datos intercambiados
sean debidamente procesados o comprendidos. Si se usa XML, se puede asegurar
que existe interoperabilidad en cuanto a los datos, pero no en cuanto a la semntica:
el receptor y el emisor pueden entender las etiquetas XML de formas muy distintas.
Para una interoperabilidad completa se necesita usar ontologas. Para tener un primer
contacto con las ontologas, recomiendo consultar esta direccin:
http://protege.stanford.edu/publications/ontology_development/ontology101-noymcguinness.html . Disfruten del Ctes dOr.
- 25/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Capa N
- 26/313 -
http://www.javahispano.org
- 27/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Espa
Ruso
Tcnico
en claves
Telegrafista
AXh782R3XVjY
Libro de claves
Secuencia Morse
Tcnico
en claves
Telegrafista
Codificacin Morse
Telgrafo
sin hilos
pulsos elctricos
Secuencia pulsos em
Oscilaciones campo
electromagntico
pulsos em
Telgrafo
sin hilos
pulsos elctricos
Miguel ngel Abin, Marzo 2004
- 28/313 -
http://www.javahispano.org
- 29/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Capa de aplicacin
Capa de transporte
Capa de red
Capa de enlace
- 30/313 -
http://www.javahispano.org
La World Wide Web, que usa el protocolo HTTP, obedece fielmente al modelo
cliente-servidor. Los clientes son las aplicaciones que permiten consultar pginas web
(navegadores); y los servidores, aquellas que suministran (sirven) pginas web.
Cuando un usuario introduce una direccin web en el navegador (un URL), ste
solicita, mediante el protocolo HTTP, la pgina web al servidor web que se ejecuta en
el ordenador servidor donde reside la pgina. El servidor web enva la pgina por
Internet al cliente (navegador) que se la solicit, y este ltimo la muestra al usuario.
Miguel ngel Abin, Julio 2004
- 31/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Navegador
web
Internet
Pginas
web
(HTML)
Servidor
web
CGI
Lgica de la
aplicacin
Bases de
datos
Figura 12b. Otra vista de la figura 12a
- 32/313 -
http://www.javahispano.org
HTTP
SMTP
DNS
Capa de
Telnet
aplicacin
FTP
Protocolos
TCP
Capa de
UDP
transporte
IP
ARP
Capas
Capa de
red
aaa
aaa
a
Ethernet
Token
ring
FFDI
Capa de
enlace
- 33/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Cliente
Web
Protocolo HTTP
Servidor
web
Capa de
aplicacin
TCP
Capa de
transporte
Protocolo TCP
TCP
Procesos
del sistema
operativo
IP
Driver
Ethernet
Protocolo IP
Protocolo Ethernet
IP
Driver
Ethernet
Capa de red
Capa de enlace
- 34/313 -
http://www.javahispano.org
Esquema de un datagrama
Cabecera
Versin
IHL
Tipo de servicio
Identificacin
Longitud total
Flags
Offset de fragmentacin
Comprobacin de la cabecera
Direccin IP origen
Direccin IP destino
Opciones
Relleno
- 35/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
slo se inspiran en las realidades ms dramticas para dar nombres a sus conceptos:
nadie usa lovegram, peacegram o trminos similares).
Bajo el prrafo anterior subyace una importante pregunta: cmo se pueden
construir comunicaciones fiables sobre un protocolo base (IP) carente de toda
fiablilidad? La respuesta se ver cuando se explique el protocolo TCP.
Cada anfitrin en una red TCP/IP (o, simplemente, IP) se identifica mediante, al
menos, una direccin IP (existen protocolos que transforman las direcciones fsicas en
direcciones IP, y viceversa). Estas direcciones son lgicas, no fsicas: son
independientes del hardware y de la naturaleza fsica de las redes.
Cada direccin IP tiene dos partes; una identifica a una red, y la otra a un anfitrin
o nodo dentro de la red. Actualmente, la versin en vigor de este protocolo es la IPv4,
que utiliza 4 bytes (32 bits) para cada direccin IP. En formato decimal, una direccin
IP consiste en cuatro nmeros enteros, menores de 256, separados por puntos (por
ejemplo, 147.156.203.5).
Que una mquina tenga ms de una direccin IP es, en ocasiones, imprescindible.
Una mquina que acte como encaminador, por ejemplo, interconecta redes distintas.
Como una direccin IP implica una red, resulta imprescindible que el encaminador
tenga varias direcciones IP, cada una correspondiente a una conexin de red.
Mediante el DNS (Domain Name Service: servicio de nombres de dominio), los
usuarios pueden referirse a los anfitriones con nombres (por ejemplo, www.aidima.es)
en lugar de con ristras de nmeros. DNS es un servicio de nombres distribuido que
permite a los usuarios de Internet referirse a los anfitriones con nombres sencillos de
recordar en lugar de con direcciones IP. La representacin de direcciones IP mediante
nombres de dominio resulta muy conveniente para los usuarios; pero no es empleada
por el protocolo IP, que slo maneja direcciones IP. As pues, en toda peticin hecha
con un nombre de dominio debe convertirse el nombre de dominio en una direccin IP
usando el protocolo DNS.
Aunque muchos autores usan datagrama para cualquier paquete de datos que
viaje por una red, no me parece que sea una eleccin acertada: creo que ocasiona
problemas conceptuales y que resulta beneficioso precisar un poco ms y manejar con
cautela los trminos. Ninguna red transmite directamente datagramas: en realidad, por
el medio de transmisin se transmiten tramas fsicas (physical frames) o tramas
fsicas de red; cuando un datagrama viaja por una red, lo hace encapsulado dentro de
la trama fsica usada por la red que lo alberga. Una trama fsica es la representacin
fsica (mediante seales elctricas, pulsos de lser, ondas electromagnticas, etc.) de
una secuencia de bits bien delimitada; la secuencia de bits constituye la trama, a
secas. Una trama es un paquete que ha sido codificado para ser enviado por un medio
fsico. Los protocolos de la capa de enlace definen la forma de las tramas y se
encargan de la correcta representacin de la informacin digital en las tramas fsicas
correspondientes al medio fsico subyacente. En el caso de un mdem, cuando recibe
una trama fsica (analgica), la convierte en una trama (digital).
Una trama fsica lleva dentro de ella un datagrama encapsulado, pero no es un
mero datagrama. Por decirlo de una manera simplificada, un datagrama siempre es un
viajero lgico en una trama fsica. Si la informacin que contiene un datagrama tiene
que pasar de una red a otra mediante un encaminador (router), se extrae el datagrama
de la trama fsica que lo alberga y se pone en una nueva trama fsica de la otra red
(que puede ser completamente distinta a la primera). Como un datagrama es un
concepto lgico, no fsico, puede viajar, con distintas tramas fsicas, entre redes
Miguel ngel Abin, Julio 2004
- 36/313 -
http://www.javahispano.org
Ethernet, Token ring, ATM, X2.5, etc. El vehculo cambia, es de quitaipn, pero el
mensajero siempre es el mismo. Vagones de metro pintarrajeados de graffitis que
cualquiera raspara con saa si apareciesen en su casa, motocicletas, autobuses que
circulan por vas de peaje, bicicletas, motocicletas, aviones militares, etc.: todos estos
medios de transporte, convenientemente traducidos al mundo digital, sern usados
tarde o temprano por casi todos los mensajeros.
Si al lector le agrada la metfora antropomorfa del mensajero, puede considerar
que todo datagrama es un mensajero encargado de viajar a lejanos lugares para
entregar un mensaje (los datos) que siempre lleva consigo. La capa de enlace da
visado al pasajero y lo embute, amable pero firmemente, en un medio de transporte. El
mensajero, por supuesto, siempre tiene que tener a mano el visado, pues se lo exigen
cada vez que cruza una frontera (encaminador). Si el visado se deteriora (por ejemplo,
si se borra el lugar de nacimiento o el de destino), el mensajero queda en una posicin
comprometida, pues tendr problemas para salir de la zona donde se encuentra.
Asimismo, si pierde o deteriora el mensaje que transporta, su viaje pasa a carecer de
sentido.
Para diferenciar entre datos correspondientes a distintas capas de TCP/IP,
recomiendo usar esta terminologa para las unidades de datos:
- 37/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 38/313 -
http://www.javahispano.org
Capa de transporte
Cabecera
Datos
Datos
Datos
Capa de red
Cabecera
Capa de enlacee
Cabecera
Datos
Datos
Datos
Frame
- 39/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
encaminadores). En todas las comunicaciones se pueden perder tramas (y, por tanto,
datagramas) o pueden quedarse hurfanas: las redes fsicas pueden fallar, las
mquinas de destino (o de origen) pueden desconectarse de Internet, de la intranet o la
extranet, etc. Cuando uno aprende de qu manera se encaminan los datagramas por
Internet, suele preguntarse si de verdad este catico juego de ping-pong da lugar a
comunicaciones fiables. Pues las da: muy mal deben de estar las redes intermediarias
para que se registre ms de un cinco por ciento de paquetes perdidos. Sea cual fuere
el estado de las redes que acten como infraestructuras de telecomunicacin (siempre
que exista alguna, por supuesto), existen maneras de garantizar la entrega y recepcin
de paquetes, tal como veremos ms adelante.
Mquina destino
Capa de aplicacin
Capa de aplicacin
Capa de transporte
Capa de transporte
INTERNET
INTERNET
Capa de red
Capa de red
Capa de enlace
Capa de enlace
Router
Router
Subred
Subred
- 40/313 -
http://www.javahispano.org
- 41/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
TCP: 1335
Servicio
HTTP
TCP: 1336
TCP: 80
Servicio
Canal de datos FTP
Canal de control FTP
Telnet
Simple Mail Transfer
Gopher
Finger
Hipertexto (HTTP)
USENET
Nmero Puerto
20
21
23
25
70
79
80
119
- 42/313 -
http://www.javahispano.org
- 43/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
del otro, la ruta de viaje puede variar por muchsimos motivos: un puente puede
haberse hundido, una zona puede haber quedado inundada, una autopista puede tener
menos trfico que antes, etc.
2)
3)
4)
5)
6)
7)
8)
9)
- 44/313 -
http://www.javahispano.org
Cliente
Capa de
aplicacin
Capa de
transporte
Capa de
red
Capa de
enlace
HTTP Peticin
Capa
fsica
Servidor
Mensaje
Capa de
aplicacin
HTTP Peticin
Capa de
Segmento transporte
Datagrama
Capa de
red
Trama
Capa de
enlace
Trama
fsica
Capa
fsica
- 45/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
TCP es el complemento perfecto de IP: ste enva los paquetes desde el origen
hacia el destino con la mxima velocidad que puede, pero no garantiza su correcta
entrega. TCP realiza las comprobaciones oportunas; en el caso de que algn paquete
se haya perdido o haya llegado en mal estado, avisa al origen para que vuelva a
enviarlo. Cuando hay problemas en la transmisin o recepcin de un paquete, IP lo
descarta y enva un mensaje genrico de error a la mquina origen. TCP interpreta el
error y se encarga de que la mquina que envi el paquete con problemas lo reenve.
Cuando se dice que se ha instalado TCP (o TCP/IP) en un ordenador, no se
quiere decir que se ha instalado slo el protocolo TCP (o TCP e IP). En realidad, se
busca significar que se ha instalado software que realiza todas las funciones del
conjunto de protocolos TCP/IP (IP, en la capa de red; TCP/UDP, en la capa de
transporte; HTTP, FTP, Telnet, etc., en la capa de aplicacin). Conviene no olvidar que
TCP/IP es un conjunto de protocolos, esto es, un conjunto de reglas, no un software
especfico. Muchos fabricantes implementan estos protocolos de formas muy diversas.
- 46/313 -
http://www.javahispano.org
- 47/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 48/313 -
http://www.javahispano.org
2.5. El modelo de referencia OSI estaba vestido para el xito, pero el xito no le
lleg
El modelo de capas TCP/IP no es el nico existente. La ISO (International
Standard Organization: organizacin internacional de normas), encargada de la
elaboracin de normas internacionales, desarroll un modelo para las conexiones entre
sistemas que estn abiertos a comunicaciones con otros sistemas, conocido como
modelo de referencia OSI (Open System Interconnection: interconexin de sistemas
abiertas).
Este modelo tiene siete capas: capa fsica, capa de enlace de datos, capa de red,
capa de transporte, capa de sesin, capa de presentacin y capa de aplicacin. Las
tres ltimas vendran a equivaler a la capa de aplicacin del modelo TCP/IP. Parece
que el nmero de capas no obedece a ninguna lgica conceptual: sorprende que la
especificacin del modelo OSI dedique tanto espacio a la capa fsica y a la de enlace
de datos, y tan poco a las de presentacin y aplicacin. Es ms: en casi todas las
implementaciones del modelo y de los protocolos asociados, la capa de presentacin
no existe y la presencia de la de aplicacin es testimonial. La nica explicacin que he
encontrado a este hecho se encuentra en Computer Networks 3rd Edition [Andrew S.
Tanenbaum, 1998] y la traduzco a continuacin:
A pesar de que casi nadie lo admite pblicamente, el verdadero motivo por el
que el modelo OSI tiene siete capas es que en el momento en que se dise, IBM
tena un protocolo patentado de siete capas llamado SNA (Systems Network
Architecture: arquitectura de redes de sistemas). En esa poca, IBM dominada la
industria de la computacin hasta tal punto que todo el mundo, incluidas las empresas
telefnicas, las de ordenadores de la competencia e incluso los principales gobiernos
tenan miedo de que IBM usase su fuerza en el mercado para obligar a todos,
prcticamente, a emplear SNA, que podra ser modificado en el momento que se
quisiese. Con OSI se pretenda crear un modelo de referencia y una pila de protocolos
semejante al de IBM que pudieran convertirse en el estndar mundial y que estuvieran
controlados no por una empresa, sino por una organizacin neutral: la ISO.
Como ya se dijo, TCP/IP se usa tanto para designar a un modelo de capas como a
una familia de protocolos. En consecuencia, es legtimo y exacto hablar de la
arquitectura TCP/IP, pues una arquitectura de comunicaciones es un modelo de capas
y un conjunto de protocolos, cada uno asociado a una capa. El modelo OSI, en cambio,
es slo un modelo, no una arquitectura de comunicaciones, puesto que no define los
protocolos que puede usar cada capa. Existen normas ISO que s especifican los
protocolos que cada capa debe tener, pero no forman parte del modelo OSI. Por lo que
he podido ver en el Perinorm (un programa de bsqueda de normas de todos los
pases del mundo), hace mucho tiempo que no se han revisado.
Si bien he credo interesante mencionar el modelo OSI, no voy a extenderme
mucho en sus detalles, pues hace ya tiempo que las redes eligieron caballo ganador:
TCP/IP. El modelo OSI slo se usa ya en los libros de texto (especialmente en los
europeos).
Las principales diferencias internas entre ambos modelos son stas:
Dentro del modelo OSI, se trabaja con conexiones; por tanto, cada
aplicacin que desea comunicarse con otra debe establecer primero un
camino hasta el extremo de destino. Como hemos visto, TCP/IP trabaja
con paquetes.
Miguel ngel Abin, Julio 2004
- 49/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 50/313 -
http://www.javahispano.org
- 51/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Y tambin que
[...] las funciones colocadas en los niveles bajos del sistema deben ser
redundantes o de poco valor cuando se comparan con el coste de proporcionarlas
en ese bajo nivel. Los ejemplos comentados en este artculo incluyen la supresin
de los mensajes duplicados y la confirmacin de la entrega.
- 52/313 -
http://www.javahispano.org
- 53/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 54/313 -
http://www.javahispano.org
2.7. Sockets
2.7.1. Introduccin. Todo empez en UNIX
Las abstracciones vistas en los subapartados anteriores (incluidos los puertos) no
bastan para permitir las comunicaciones en red. Mientras se ejecutan, las aplicaciones
o procesos de usuario permanecen dentro del espacio de memoria reservado para el
usuario. El software que implementa a TCP/IP, en cambio, forma parte del sistema
operativo. La situacin se torna ms complicada cuando consideramos aplicaciones
que se ejecutan en distintas plataformas, pues deben comunicarse procesos que se
ejecutan sobre arquitecturas de hardware y sistemas operativos diferentes.
Para que haya comunicacin se necesita una API comn (Application
Programming Interface: interfaz de programacin de aplicaciones) entre las
aplicaciones de usuario y los protocolos de transporte. Una API define cmo los
programadores deben usar una cierta caracterstica o funcin de un sistema, sea de
software o hardware. La API ms utilizada para la comunicacin en redes es la API
Socket, que fue diseada inicialmente para la versin 4.1 de UNIX BSD (Berkeley
Software Distribution), desarrollado en la Universidad de California (Berkeley). La
versin 4.2 de UNIX BSD (1983) fue la primera en introducir la familia de protocolos
TCP/IP dentro del sistema operativo; TCP/IP haba sido introducido en UNIX BSD ya
en 1981, pero no como parte del SO.
Las malas lenguas dicen que no es casualidad que el LSD y el UNIX BSD
surgieran en la Universidad de Berkeley. Tras indagar en las reacciones que provoc
en la comunidad UNIX la aparicin de la API Socket, puedo asegurar que la reaccin
que tuvieron muchos programadores se ve magnficamente representada por el rostro
alucinado del soldado de la pelcula Apocalypse Now que, al poco de tomar cido,
contemplaba extasiado y ensimismado las explosiones areas y el fuego de artillera,
absorto en la catarata de sonidos e imgenes en que se transmutaba, por obra y gracia
de la farmacologa moderna, la desoladora realidad blica. Quizs nadie en Apocalypse
Now supiera quin era el oficial al mando, ni siquiera Francis Ford Coppola; pero los
usuarios de UNIX reconocieron en la API Socket al oficial al mando.
Como Java usa el mismo modelo de sockets que UNIX BSD (hoy da, la API
Socket es un estndar de facto), vale la pena recordar su origen en UNIX. En este
sistema operativo, antes de que un proceso de usuario realice cualquier operacin de
E/S, se llama a un mtodo open() para especificar qu archivo o dispositivo (en UNIX,
todo es un archivo) va a usarse y obtener el permiso necesario. La llamada al mtodo
devuelve un entero (el descriptor de archivo); cuando un proceso ejecuta operaciones
de E/S como read() o write(), el descriptor del archivo se usa como uno de los
argumentos de la operacin. La secuencia de pasos que se realiza en UNIX para
trabajar con la E/S se conoce como Abrir-Leer-Escribir-Cerrar (Open-Read-WriteClose).
Los sockets (enchufes) no son ms que una generalizacin del mecanismo que
usa UNIX para manipular archivos, adecuada para manejar comunicaciones de red: si
para acceder a un archivo o a un dispositivo se necesita un descriptor de archivo, para
permitir comunicaciones entre procesos (estn o no en mquinas distintas) se
necesitan descriptores de sockets. Ahora bien, un descriptor de archivo nace vinculado
a un archivo o dispositivo; mientras que un descriptor socket puede corresponder a
sockets no enlazados a direcciones especficas de destino (dicho de otro modo, no
vinculados a pares direccin IP-nmero de puerto). Al igual que sucede con los
archivos y dispositivos de UNIX, con los sockets pueden usarse mtodos como read(),
write() y close(). No hay, en definitiva, grandes diferencias entre las operaciones de
transferencias de datos para sockets y para archivos. En un archivo, por ejemplo,
write() transfiere datos de una aplicacin o proceso de usuario al archivo: en un socket,
Miguel ngel Abin, Julio 2004
- 55/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Semiplano de las
aplicaciones para
HTTP usuarios
FTP
Telnet
E-mail
Socket
Socket
Socket
Socket
API SOCKET
Semiplano del sistema
operativo
TCP/IP
Drivers
Mdem / Adaptador de red
Miguel ngel Abin, Marzo 2004
- 56/313 -
http://www.javahispano.org
- 57/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Los protocolos TCP y UDP utilizan sockets para comunicar programas entre s en
una arquitectura cliente-servidor. Todo socket tiene asociado la direccin IP del
anfitrin donde se ejecuta el programa servidor o cliente y la direccin del puerto
utilizado por el programa cliente o servidor.
UDP y TCP usan sockets, pero los sockets UDP y TCP son muy distintos. Un
socket TCP est ligado a una sola mquina y permite la transmisin bidireccional de
datos mediante flujos de datos (despus, la capa de red los convierte en datagramas).
En cambio, un socket UDP puede estar ligado a muchas mquinas y permite el envo o
recepcin de datos siempre unidireccional en forma de paquetes discretos que a
veces tambin se llaman como los paquetes definidos por la capa de red (datagramas).
Los sockets TCP (tambin conocidos como sockets de flujo) ofrecen, entre otras,
las funciones que aparecen en la siguiente tabla:
Accin
Descripcin
SOCKET
socket()
BIND
bind()
Asignacin de una
direccin IP a un socket
CLOSE
close()
Cierre de la conexin
Creacin de un socket
Declaracin de
aceptacin de
LISTEN
listen()
conexiones entrantes
Figura 17. Ejemplo de conexin cliente-servidor
Espera hasta que llegue
ACCEPT
accept()
alguna conexin
Intento de establecer
CONNECT
connect()
conexin
Envo de datos por
SEND
send()
medio de la conexin
Recepcin de datos por
RECEIVE
recv()
medio de la conexin
Figura 25. Algunas funciones de los sockets TCP
En el modelo cliente-servidor, al cliente le corresponden las funciones socket(),
connect(), send()/recv() y close(); al servidor, socket(), bind(), listen(), accept() y close().
La funcin accept() permite usar las funciones recv()/send() y close() sobre los sockets
que crea. Aunque no incluyo las funciones write() y read(), tambin se pueden usar;
pero ofrecen menos control sobre la tranmisin de datos que send() y recv(), ms
especializadas en las comunicaciones entre procesos.
En una comunicacin TCP, los clientes crean sockets activos (por brevedad, omito
TCP) y los conectan a sockets activos del servidor generados a partir de sockets
pasivos del servidor. A su vez, cada socket est asociado a una dupla con dos
componentes: direccin IP y nmero de puerto. Como hay conexin, no se precisa
Miguel ngel Abin, Julio 2004
- 58/313 -
http://www.javahispano.org
CLIENTE
socket()
listen()
Se abre conexin
connect()
accept()
recv()/read()
send()/write()
close()
close()
- 59/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 60/313 -
http://www.javahispano.org
Ejemplo 1: ServidorSaludo.java
Puerto por el que escucha
import java.net.*;
import java.io.*;
SOCKET, BIND
y LISTEN
Espera peticiones
(ACCEPT)
}
class Conexion extends Thread {
private Socket socketCliente;
private PrintWriter salida;
public Conexion(Socket socketCliente) {
this.socketCliente = socketCliente;
}
}
Miguel ngel Abin, Julio 2004
- 61/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
En este sencillo ejemplo vemos que las clases ServerSocket y Socket ofrecen
al programador un InputStream o un OutputStream, mediante mtodos como
getOutputStream(). Las clases InputStream y OutputStream, as como
muchas de sus subclases, se explicarn en el apartado 3.
- 62/313 -
http://www.javahispano.org
Accin
Descripcin
SOCKET
socket()
BIND
bind()
Asignacin de una
direccin IP a un socket
CLOSE
close()
SEND TO
Sendto()
RECEIVE FROM
recvfrom()
Creacin de un socket
Envo de datos
Recepcin de datos
- 63/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
SERVIDOR
socket()
socket()
bind()
bind()
sendto()
sendto()
close()
close()
- 64/313 -
http://www.javahispano.org
import java.net.*;
import java.io.*;
Socket
activoUDP
Socket activo
UDP
- 65/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
socket.send(datagrama);
socket.close();
CLOSE
SEND TO
}
catch (IOException e) {
e.printStackTrace();
}
}
- 66/313 -
http://www.javahispano.org
- 67/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 68/313 -
http://www.javahispano.org
- 69/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 70/313 -
http://www.javahispano.org
conexin entre el administrador y cada agente, lo cual resulta muy razonable: las
comunicaciones del tipo consulta-respuesta suelen ser espordicas y tienen pocos
datos para intercambiar. Ahora bien, la falta de fiabilidad obliga a que el administrador
SNMP compruebe cada cierto tiempo todos los nodos bajo su control, para detectar
sucesos inesperados (conexiones y desconexiones de nodos, pongamos por caso).
Todos los sucesos relevantes de los agentes son transmitidos al administrador, el cual
se encarga de averiguar los detalles exactos mediante consultas a los agentes.
Obvio aqu cualquier consideracin de seguridad, pues es una materia bastante
compleja. Con todo, el lector puede imaginarse la importancia que tiene la seguridad en
la administracin de redes. Si los agentes no dispusieran de un modo de asegurarse de
que los mensajes vienen de la mquina donde se ejecuta el administrador SNMP,
podran dar informacin de su estado y de sus caractersticas a cualquier mquina que
lo solicitara. Consecuentemente, una mquina ajena a la red podra controlar todos los
dispositivos, suplantando a la verdadera mquina administradora.
Nmero de 3 digitos
Respuesta de texto
- 71/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Advertencia: Para que se pueda interpretar que una orden est completa (sea
de este protocolo o de otro), debe ir seguida de uno o varios caracteres que
indiquen un salto de lnea. Casi todos los sistemas usan uno o dos caracteres
de control (no mostrables por pantalla) para ese propsito: <LF> o <CR>, o
<CR> seguido de <LF>. <LF> denota avance de lnea (Line Feed); <CR>,
retorno de carro (Carriage Return). Windows, por ejemplo, usa <CR><LF>
para indicar una nueva lnea; UNIX emplea <LF>.
En la codificacin US-ASCII, <CR> tiene el cdigo 13 en decimal y el 0D en
hexadecimal. Asimismo, <LF> tiene el cdigo 10 en decimal y el 0A en
hexadecimal.
En lenguajes como C, C++ y Java, \r denota un retorno de carro (<CR>) y \t
un avance de lnea.
- 72/313 -
http://www.javahispano.org
21
Conexin de
datos
Transferencia de datos
20
Transferencia de datos
Datos de archivos
- 73/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Puerto nmero 21
PORT 192,168,1,20,1,100\r\n
Puerto nmero 20
Servidor FTP
Puerto nmero 21
2
Puerto nmero 20
Comienzo
conexin de
datos
Servidor FTP
Conexin de
control
Puerto nmero 21
RETR sagan.txt\r\n
Puerto nmero 20
Servidor FTP
Puerto nmero 21
Puerto nmero 20
Conexin de
datos
Cliente FTP
Servidor FTP
- 74/313 -
Conexin de
control
http://www.javahispano.org
Puerto nmero 21
Puerto nmero 20
Conexin de
datos
Cliente FTP
Servidor FTP
Puerto nmero 21
6
Puerto nmero 20
Cliente FTP
Servidor FTP
Conexin de
control
Fin conexin de
control
Puerto nmero 20
Servidor FTP
- 75/313 -
Puerto nmero 21
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Para que el lector aprecie las posibilidades del FTP, incluyo aqu unas cuantas
rdenes de este protocolo. Lo normal hoy da es usar aplicaciones FTP que
proporcionen una interfaz amigable al usuario; pero siempre se pueden usar
directamente las rdenes.
STOR (Store). Hace que el servidor acepte los datos transferidos por el
cliente y que los almacene en un directorio del anfitrin servidor
(siempre que se tengan los permisos necesarios).
- 76/313 -
http://www.javahispano.org
LIST. Hace que el servidor enve al cliente una lista de todos los
archivos y subdirectorios dentro del directorio actual de trabajo.
- 77/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Significado
Direccin o direcciones de correo electrnico de los
destinatarios primarios.
Direccin o direcciones de correo electrnico de los
destinatarios secundarios.
Direccin o direcciones con copia oculta
Persona que cre el correo
Direccin de correo del remitente
Lnea aadida por cada agente de transferencia a lo largo de la
ruta de destino
Especifica una ruta de retorno al remitente
- 78/313 -
http://www.javahispano.org
Cabecera:
Date:
Reply-To:
Message-Id:
In-Reply-To:
References:
Keywords:
Subject:
Significado:
Fecha y hora de envo del mensaje.
Direccin de correo a la que dirigir la contestacin
Nmero nico que sirve para referirse al mensaje
Identificador del mensaje al cual responde este
mensaje
Otros identificadores del mensaje
Palabras clave elegidas por el usuario
Descripcin breve del mensaje
- 79/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
MIME define cinco nuevas cabeceras de mensaje (se describen en el RFC 2045):
Cabecera MIME
MIME-Version:
Content-Type:
Content-Description:
Content-Id:
Content-TransferEncoding:
Significado
Identifica la versin MIME
Tipo del mensaje
Cadena legible que describe el contenido del mensaje.
Identificador nico
Especifica cmo se codifica el cuerpo del mensaje
- 80/313 -
http://www.javahispano.org
0A
1B
2C
3D
4E
5F
6G
7H
8I
9J
10 K
11 L
12 M
13 N
14 O
15 P
16 Q
17 R
18 S
19 T
20 U
21 V
22 W
23 X
24 Y
25 Z
26 a
27 b
28 c
29 d
30 e
31 f
32 g
33 h
34 i
35 j
36 k
37 l
38 m
39 n
40 o
41 p
42 q
43 r
44 s
45 t
46 u
47 v
48 w
49 x
50 y
51 z
52 0
53 1
54 2
55 3
56 4
57 5
58 6
59 7
60 8
61 9
62 +
63 /
010000
010001
000011
- 81/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
ISA*00*
*00*
*01*987654321
*12*8005551234
607*0111*U*00200*110000777*0*T*>
GS*PO*987654321*8005551234*920501*2032*7721*X*002003
ST*850*000000001
BEG*00*NE*MS1112**920501**CONTRACT#
REF*IT*8128827763
N1*ST*MAVERICK SYSTEMS
N3*3312 NEW HAMPSHIRE STREET
N4*SAN JOSE*CA*94811
PO1*1*25*EA***VC*TP8MM*CB*TAPE8MM
PO1*2*30*EA***VC*TP1/4*CB*TAPE1/4INCH
PO1*3*125*EA***VC*DSK31/2*CB*DISK35
CTT*3
SE*11*000000001
GE*1
*7721
IEA*1*110000777
*910=
Tipo
text
image
audio
video
application
message
Subtipo
plain
richtext
gif
jpeg
basic
mpeg
octet-stream
postscript
rfc822
partial
externalbody
Descripcin
Texto sin formato
Texto que incluye rdenes simples de
formato
Imagen en formato GIF
Imagen en formato JPEG
Archivo de audio
Archivo en MPEG
Secuencia de bytes sin interpretacin
Documento imprimible en Postscript
Mensaje MIME RFC 822
Mensaje dividido para la transmisin
El mensaje mismo debe obtenerse de la red
- 82/313 -
http://www.javahispano.org
- 83/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
El conjunto de rdenes que puede usar un cliente SMTP se detalla en esta tabla:
Orden
HELO nombre_anfitrion
MAIL FROM: <direccion_anfitrion>
RCPT TO: <direccion_destino>
DATA
RSET
QUIT
HELP
EXPN <direccion_correo>
VRFY <direccion_correo>
Significado
Identifica el origen de la conexin
Identifica al remitente
Identifica al destinatario
Seala el comienzo de la introduccin de datos
Aborta la conexin con el servidor SMTP
Cierra la conexin con el servidor SMTP
Muestra ayuda sobre las rdenes aceptadas
Expande una lista de correo
Comprueba la existencia de una direccin de
correo.
- 84/313 -
http://www.javahispano.org
Cuando comenz a usarse SMTP, era comn abrir sesiones Telnet en una
mquina remota donde se ejecutaba un servidor SMTP y escribir el correo electrnico
tal y como se detalla en el ejemplo. Enseguida fueron apareciendo programas cliente
(agentes de usuario) que liberaban al usuario de la tarea de conocer y escribir las
rdenes, aunque la interfaz grfica de los primeros clientes era tan amigable como
suave es el puercoespn. Hoy da, los clientes de correo ofrecen interfaces grficas
excelentes, que ponen el correo electrnico a disposicin de quien desee usarlo.
Adems, ofrecen utilidades impensables para aquellos clientes que se ejecutaban en
pantallas monocromas y sin ratn. A saber: filtros, reglas de seleccin y
almacenamiento, mensajes predefinidos (Estoy de vacaciones. Volver el 28 de
agosto.), etc.
Siento cierta nostalgia por los programas UNIX de correo con que trabaj en mi
tesina. Funcionaban exclusivamente por teclado y su interfaz grfica pareca sacada de
un terminal tonto que hubiera escapado del desguace. Con todo, an los empleo de
vez en cuando, por razones que no vienen al caso. Vindolos en retrospectiva, debo
reconocer que permiten hacer el 90 por ciento de las cosas que hacen los modernos
clientes de correo, llenos de colorines y grficos y empeados en consumir unos
recursos desproporcionados si los comparamos con aqullos.
- 85/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 86/313 -
http://www.javahispano.org
Significado
Identifica al usuario
Identifica la contrasea del usuario
Devuelve el nmero de mensajes y sus tamaos
en bytes
Lista los mensajes en el buzn y sus tamaos
Lee un mensaje
Marca un mensaje para borrarlo al cerrar la
sesin
Acaba la sesin. Cuando se ejecuta, se borran
todos los mensajes marcados.
Lista la cabecera del mensaje ms las lneas del
cuerpo que se marcan
- 87/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
MIME-version: 1.0
Content-Rype: text/plain; Charset=iso-8859-1
Content-Transfer-Encoding: 7 bit
Hola, Miguel ngel:
Tienes ya algo preparado para la convencin en Riga? An falta,
pero ms vale tenerlo en cuenta.
Dime algo.
QUIT
Como puede suponerse, no es usual emplear directamente las rdenes, puesto
que los agentes de usuario proporcionan interfaces grficas mucho ms cmodas para
tratar con los servidores POP3 y descargar mensajes. Existen, sin embargo, algunas
ocasiones en las que puede venir bien establecer una sesin de Telnet en un servidor
POP3 e introducir a pelo las rdenes:
Cuando se quieren leer los correos desde cualquier parte del mundo sin
necesidad de navegadores (hay servicios que permiten conectarse al
buzn de correo de uno mediante un navegador web). Por qu
complicarse tanto la vida con POP3 en lugar de usar un navegador y
uno de esos servicios? Existen motivos de seguridad para ello, pero
aqu no me voy a extender en ellos: no es propsito del tutorial desvelar
las vulnerabilidades de ningn sistema.
- 88/313 -
http://www.javahispano.org
Servidor de correo
del destinatario
SMTP
SMTP
POP3
Agente de
usuario
Agente de
usuario
Para acceder a los correos, se pueden
usar otros protocolos: IMAP o
DMSP, por ejemplo.
Figura 43. Esquema del uso combinado de los protocolos SMTP y POP3
Adems de POP3, existen otros protocolos ms modernos y perfeccionados para
el envo de correo electrnico desde el servidor a la mquina local empleada por el
usuario. Dos de ellos son el IMAP (Interactive Mail Access Protocol: protocolo
interactivo de acceso al correo) y el DMSP (Distributed Mail System Protocol: protocolo
de sistema de correo distribuido).
El IMAP se define en el RFC 1064. A diferencia del POP3, no copia el correo en la
mquina local del usuario, pues se dise para que el usuario pueda acceder a su
correo desde cualquier mquina (un PC, una agenda electrnica, un ordenador porttil,
etc.). Los servidores de correo que usan IMAP siempre mantienen un depsito de
mensajes al cual los usuarios autorizados tienen acceso desde cualquier mquina.
Adems, IMAP permite guardar los mensajes mediante atributos (fecha de envo,
nombre del remitente, palabras clave, etc.). As, el correo puede consultarse con
rdenes que equivalen a Mustreme todos los mensajes recibidos el 23/07/04,
Mustreme todos los mensajes de Fulanito, etc.
El DMSP se describe en el RFC 1056. A diferencia del IMAP, permite descargar
correo del servidor a una mquina local. Sin embargo, no acaba ah su trabajo: una vez
descargado el correo y cerrada la conexin, los usuarios pueden leer su correo y
contestarlo; cuando reabran su conexin, todo el nuevo correo se transferir al servidor
y se sincronizarn los mensajes en el servidor y en la mquina local. Por ejemplo, los
correos borrados mientras el usuario estaba desconectado desaparecern del servidor
cuando se establezca una reconexin.
Miguel ngel Abin, Julio 2004
- 89/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
HTML
Capa de aplicacin: HTTP
Capa de aplicacin: SMTP, FTP, POP3...
Capa de transporte
Capa de red
Capa de enlace
Miguel ngel Abin Julio 2004
- 90/313 -
http://www.javahispano.org
- 91/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Para localizar un recurso en la Web, se usan los URL (Uniform Resource Locator:
localizador uniforme de recursos), que vienen a ser punteros a los recursos de la Web.
Los URL ya han sido mencionados antes e incluso se adelant una definicin
provisional en el subapartado 2.1. En un URL hay la siguiente informacin:
- 92/313 -
http://www.javahispano.org
otro sitio. Los URN permiten referirse a los recursos mediante nombres, sin decir dnde
estn aqullos. He aqu un ejemplo de un URN:
urn:isbn:0232343789
Los URI (Uniform Resource Identifier: identificador uniforme de recursos) son otra
vuelta de tuerca a concepto de URL: constituyen una abstraccin que incluye a los URL
y URN. Un URI asigna un nombre a un recurso, lo describe y permite encontrarlo.
En la arquitectura cliente-servidor de la Web, los clientes suelen usar
navegadores web (web browsers). Un navegador es una aplicacin que se encarga de
obtener los recursos web, de interpretar las etiquetas HTML y de mostrarlas por
pantalla.
Los navegadores se comunican con los servidores web mediante el protocolo
HTTP, que veremos ms adelante, y usan los URL para localizar los recursos. Casi
todos permiten el uso de otros protocolos (FTP, HTTPS, etc.) adems del HTTP. En
2004, los navegadores ms populares son Internet Explorer, Opera, Safari y los
basados en Mozilla.
La guerra de navegadores entre Microsoft y Netscape (comprada por AOL a
finales de 1998) provoc la aparicin de extensiones del HTML no del todo
compatibles, lo cual ha retrasado mucho la estandarizacin del lenguaje de marcado.
Un perfecto ejemplo de la falta de interoperabilidad nos lo dan los letreros del tipo
Optimizado para Internet Explorer 5.0 y para una resolucin de 800x600.
En la parte del servidor de la Web encontramos servidores web. Un servidor web
es una aplicacin o proceso que implementa al protocolo HTTP para recuperar
recursos que vienen identificados por sus URL. En consecuencia, servidor web es
sinnimo de servidor HTTP. Estos servidores se implementan mediante demonios; por
ejemplo, en UNIX los servidores web se llaman Httpd (la letra d es de demonio).
Tambin se usa servidor web para referirse a los anfitriones encargados de servir
recursos (casi siempre pginas web) mediante el protocolo HTTP.
El servidor web ms popular es Apache, seguido por el Internet Information
Server, de Microsoft. En la actualidad, a cualquier servidor HTTP serio se le debe
pedir que sea capaz de realizar estas tareas:
Llevar el registro de las actividades (conexiones, desconexiones, fallos,
intentos de acceso no autorizado, etc.)
Permitir la identificacin de los usuarios.
Permitir enviar datos a subrutinas o procedimientos que los procesen.
Encargarse de la creacin y gestin de directorios virtuales.
Permitir trabajar con otros protocolos adems del HTTP: HTTPS, SSL,
FT, Gopher, etc.
Un sitio web (website) es una coleccin de pginas web, que tiene un comn la
raz de sus URL. No necesariamente tienen que estar localizadas fsicamente en un
mismo anfitrin, aun cuando esto es lo usual.
- 93/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Un cuerpo (optativo).
- 94/313 -
http://www.javahispano.org
- 95/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
De todos modos, TCP permite el envo de flujos de bytes; por tanto, una imagen o
un archivo binario se pueden enviar como una secuencia de ceros y unos.
Una de las grandes mejoras de la versin 1.1 del protocolo HTTP frente a la
versin 1.0 consiste en que las conexiones TCP permanecen abiertas hasta que el
cliente o el servidor las cierran (lo cual suele ocurrir cuando pasa un cierto tiempo sin
que se enven mensajes).
En la versin 1.0, cada peticin HTTP implicaba una nueva conexin. Por ejemplo,
si una pgina web tena muchas imgenes, se necesitaba una conexin TCP para cada
una (ms la asociada a la pgina en s), lo cual provocaba una sobrecarga por la
apertura y cierre de conexiones TCP. Como una pgina puede tener imgenes
estticas, animadas, marcos, applets, etc, la versin 1.1 ahorra tener que abrir y cerrar
muchas conexiones para mostrar una sola pgina.
Mtodo
GET
HEAD
POST
Significado
Permite acceder a recursos del servidor.
El formato es similar al de GET pero se solicita al servidor
que conteste slo con cabeceras, no con cuerpos. Suele
ser til para conocer las caractersticas de un recurso sin
tener que transferirlo al cliente.
Se usa para enviar datos al servidor. Esos datos pueden
proceder de un formulario HTML o pueden estar
destinados a algn programa en el servidor (CGI)
C D IG O S D E C O N T R O L D E H T T P
200
201
202
204
301
302
304
400
401
OK
C reated
A ccepted
N o C ontent
M oved Perm anently
M oved T em porarily
N ot M odified
B ad R equest
U nauthorized
403
404
500
501
502
503
F orbidden
N ot F ound
Internal Server E rror
N ot Im plem ented
B ad G atew ay
S ervice U navailable
- 96/313 -
http://www.javahispano.org
Las siglas CGI (Common Gateway Interface: interfaz comn de pasarelas) tienen
un doble sentido. Por un lado, es un estndar para ejecutar programas desde
servidores web. CGI especifica cmo pasar a un programa en ejecucin argumentos
como parte de una peticin HTTP, y define una serie de variables que dependen del
software y hardware empleados. Por otro lado, CGI designa a un programa que se
ejecuta en un servidor web y que puede aceptar argumentos de los clientes.
Generalmente, un programa CGI devuelve un documento HTML (una confirmacin
de la compra de un producto, por ejemplo) que se genera en funcin de los argumentos
pasados por el cliente. Luego, el servidor enva el documento al cliente. En los
sistemas UNIX, los servidores de HTTP (Httpd) suelen requerir que los programas
CGI residan en un directorio /cgi-bin.
Antes de los programas CGI, los servidores HTTP eran estticos: se limitaban a
entregar a los clientes las pginas web solicitadas mediante URL.
Los programas CGI obtienen los datos que necesitan mediante los mtodos POST
y GET del protocolo HTTP. Cuando un usuario rellena el formulario de una pgina web
y aprieta el botn Enviar, el navegador enva estos datos al CGI. Si se usa POST, los
datos se entregan al CGI por la entrada estndar; si se usa GET, el CGI recibe los datos
del formulario mediante la variable de entorno QUERY_STRING.
En una llamada a un CGI, ocho son los pasos intermedios:
1. El usuario aprieta el botn Enviar de un formulario web, mostrado
por un navegador web.
2. El navegador web recoge los datos introducidos en el formulario y
los ensambla en una cadena de texto. A continuacin, crea una
peticin HTTP con los datos y la enva al URL que figura en la
etiqueta ACTION del formulario.
3. El servidor web recibe la peticin y usa los datos que hay en ella
para configurar las variables de entorno.
4. El servidor web arranca el programa CGI especificado en la
peticin HTTP del cliente.
5. El CGI recibe el cuerpo de la peticin HTTP mediante la entrada
estndar o mediante la variable de entorno QUERY_STRING, y
extrae de l los datos del formulario.
6. El CGI realiza los clculos o comprobaciones pertinentes y
devuelve al servidor, por la salida estndar, una pgina HTML o un
archivo codificado con MIME.
7. El servidor web acepta el archivo enviado por el CGI, aade las
cabeceras correspondientes y enva el resultado al navegador del
usuario.
8. El navegador muestra al usuario el archivo.
Con la aparicin de tecnologas como ASP, JSP o los servlets, la popularidad de
los CGI ha ido disminuyendo.
- 97/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 98/313 -
http://www.javahispano.org
Figura 47b. Esquema de una comunicacin HTTP con CGI. En el apartado 4.1
veremos que corresponde a una arquitectura cliente-servidor de cuatro
capas
- 99/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 100/313 -
http://www.javahispano.org
Antes de abordar ninguna clase, conviene entender cmo procesa Java la entrada
y la salida: trabaja con flujos o corrientes (streams), que son secuencias ordenadas
de bytes de longitud indeterminada. Los bytes pueden representar caracteres, cadenas
o cualquier otro tipo de datos, ya sea primitivo o definido por el usuario.
En Java, todo objeto del que podamos leer una secuencia de bytes es un flujo de
entrada (input stream); asimismo, cualquier objeto en que podamos escribir una
secuencia de bytes es un flujo de salida (output stream). Los flujos de entrada mueven
bytes desde una fuente externa de datos a un programa Java; los de salida, de un
programa Java a algn receptor externo. Existen flujos que mueven bytes entre partes
de distintos programas (pipes), pero no se van a tratar aqu.
Los flujos de entrada y salida basados en bytes se modelan en Java mediante las
clases java.io.InputStream y java.io.OutputStream (ambas son abstractas),
que se explicarn en este apartado. RMI y CORBA, tecnologas que se vern en los
prximos apartados, trabajan con flujos de entrada y salida mediante clases que
heredan de las dos anteriores.
(String camino)
(String padre, String hijo)
(File padre, String hijo)
(URI uri)
- 101/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
angel\Mis
Java admite el uso de "/" o "\" para rutas de acceso en cualquier plataforma, lo
admita sta o no (Solaris y Mac, por ejemplo, slo usan "/"). Aunque Java se encarga
de realizar la conversin necesaria, lo ms recomendable es usar
File.separatorChar en lugar de "/" o "\"; File.separatorChar es una variable
esttica que devuelve un valor String que corresponde al separador de archivos en el
sistema utilizado.
Advertencia: Java interpreta "\" dentro de un String como un carcter de escape.
Por ello, si se quiere indicar la ruta de un archivo Windows situado en
C:/temporal/temp.txt,
ser
necesario
usar
un
String
"C:\\temporal\\temp.txt". Tambin podran usarse las siguientes opciones:
File archivo = new File("C:/temporal/temp.txt");
File archivo = new File("C:" + File.separatorChar + "temporal" +
File.SeparatorChar + "temp.txt");
El mtodo public boolean exists() throws SecurityException
permite saber si el archivo o directorio representado por un objeto File existe. Como
un objeto File puede referirse a un archivo o a un directorio, se proporcionan mtodos
Miguel ngel Abin, Julio 2004
- 102/313 -
http://www.javahispano.org
Ejemplo 3: ListadoDirectorio.java
import java.io.*;
public class ListadoDirectorio {
public static void main(String args[]) throws IOException {
File directorio = new File(args[0]);
if ( (directorio.exists()) && (directorio.isDirectory()) ) {
String[] lista = directorio.list();
for (int i = 0; i < lista.length; i++ )
System.out.println(lista[i]);
} else {
System.out.println("El directorio no existe");
}
}
}
Ejemplo 4: InformacionArchivo.java
import java.io.*;
import java.util.*;
public class InformacionArchivo {
public static void main(String args[]) throws IOException {
Miguel ngel Abin, Julio 2004
- 103/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 104/313 -
http://www.javahispano.org
Ejemplo 5: CrearDirectorioYArchivo.java
import java.io.*;
public class CrearDirectorioYArchivo {
private static String DIR = "c:/temporal"; // directorio en formato Windows
private static String ARCHIVO = "temporal.txt";
private static void crearArchivoYDirectorio (String dir, String archivo) {
boolean dirCreado = false;
File temp = new File(dir);
if ( (temp.exists()) && (temp.isDirectory()) ) {
crearArchivo(dir, archivo);
} else {
dirCreado = crearDirectorio(dir);
if (dirCreado) {
crearArchivo(dir, archivo);
}
}
}
private static boolean crearDirectorio (String dir) {
boolean dirCreado = false;
dirCreado = (new File(dir)).mkdir();
if (dirCreado) {
System.out.println("Directorio creado.");
return true;
} else {
System.out.println("No pudo crearse el directorio.");
return false;
}
}
private static void crearArchivo(String dir, String archivo) {
boolean archCreado = false;
try {
archCreado = new File(dir, archivo).createNewFile();
}
catch (IOException e) {
System.out.println("No pudo crearse el archivo.");
}
if (archCreado) {
System.out.println("Archivo creado.");
} else {
System.out.println("No pudo crearse el archivo porque ya existe.");
}
}
public static void main(String args[]) throws Exception {
// Si no se le dan argumentos, toma valores por defecto
Miguel ngel Abin, Julio 2004
- 105/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
longitud)
El primer mtodo lee un byte sin signo del flujo de entrada y devuelve el valor int
del byte sin signo. En el caso de que no haya ms datos que leer porque se ha
alcanzado el final del flujo, devuelve 1.
El segundo intenta leer del flujo de entrada los bytes suficientes para llenar el
array datos y devuelve el nmero de bytes ledos. Si encuentra el final del flujo,
devuelve 1.
El tercero lee hasta longitud bytes del flujo de entrada y los almacena en el
array datos, comenzando en la posicin indicada por el entero offset. Devuelve el
nmero de bytes ledos, 1 si se encuentra ante un final de flujo.
Los tres mtodos son bloqueantes, pues bloquean la E/S del programa hasta que
se d una de estas tres situaciones: a) disponibilidad de datos de lectura; b) conclusin
del flujo; c) lanzamiento de una excepcin. Este carcter bloqueante tendr importantes
consecuencias para desarrollar programas con el paquete java.net.
El mtodo public void close() throws IOException se encarga de
cerrar el flujo de entrada y de liberar los recursos del sistema usados por el flujo. Esta
clase proporciona un mtodo public int available() throws IOException
que devuelve el nmero de bytes que pueden leerse sin bloqueo del flujo de entrada.
- 106/313 -
http://www.javahispano.org
El programa lee los datos de la entrada, y usa los valores int devueltos para
obtener los caracteres de la entrada, que se presentan separados por espacios en
blanco. Java ofrece un objeto InputStream (cuya referencia es System.in) ya
definido y abierto por el sistema y que representa a un flujo de entrada que viene por el
teclado. Este cdigo es tremendamente ineficaz, pues lee byte a byte; podra mejorarse
la eficiencia usando el mtodo public int read(byte[] datos), lo que permitira
leer de golpe un nmero mximo de bytes igual al tamao del array datos; pero
java.io ofrece mejores soluciones, tal como veremos enseguida.
- 107/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 108/313 -
http://www.javahispano.org
if (byteLeido == -1) {
System.out.println("Se ley todo el flujo. FIN DEL PROGRAMA.");
System.exit(0);
}
salida.write(byteLeido);
}
}
}
- 109/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 110/313 -
http://www.javahispano.org
- 111/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
un flujo a otro. Pueden usarse para almacenar datos en buffers, leer tipos primitivos
retroceder hacia atrs en un flujo, etc; adems, pueden combinarse de modo que la
salida de una instancia sea la entrada de otra.
Bytes
Archivo
FileInputStream(String file)
read(byte []);
close();
Manera ms simple de
leer los bytes de un
archivo con la clase
FileInputStream
- 112/313 -
http://www.javahispano.org
- 113/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
El primer objeto enva al objeto que envuelve la informacin que pudiera tener
almacenada.
Se llama al mtodo close() del objeto envuelto.
- 114/313 -
http://www.javahispano.org
- 115/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Consejo: Es recomendable cerrar los flujos derivados de archivos (ya sean de entrada o
salida) de la manera que aparece en el cdigo anterior.
Si se cerraran de esta manera:
try {
// Resto cdigo
entrada = new BufferedInputStream(
new FileInputStream(archivo));
// Cdigo tratamiento de la E/S
entrada.close();
}
catch (IOException e) {
// Tratamiento del error
}
- 116/313 -
http://www.javahispano.org
- 117/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 118/313 -
http://www.javahispano.org
hay que tener en cuenta que, con la primera llamada a write(), los nuevos datos se
escribirn sobre los que ya tena el archivo, con su consiguiente prdida.
Si se desea que los nuevos datos se aadan tras los ya existentes, se deber usar
este constructor:
FileOutputStream fos = new FileOutputStream(fichero, true);
La clase PrintStream incluye varios mtodos public void print() y
public void println() para imprimir (en el sentido de mostrar al usuario por la
salida estndar) cualquier valor de un objeto o un tipo primitivo.
Los mtodos print() convierten el argumento en un String y luego lo
transforman en bytes de acuerdo con la codificacin por defecto del sistema; despus
estos bytes se escriben del modo descrito para los mtodos write().
Los mtodos println() hacen exactamente lo mismo que los print(), pero
incluyen un carcter de nueva lnea ("\n", "r" o "r\n"; depende de la plataforma).
Los objetos PrintStream presentan una curiosa propiedad con respecto a las
dems clases de E/S: no lanzan excepciones. El motivo para este comportamiento
reside, probablemente, en que tal como ya se dijo, System.out (el flujo de entrada
estndar) y System.err (el flujo de salida estndar de los errores) son objetos
PrintStream. Sera bastante incmodo para un programador tener que escribir
cdigo para manejar las excepciones cada vez que escriba lneas inofensivas como
System.out.println("JAVA"). Que esta clase no lance excepciones no quiere
decir que no las pueda producir; lo que ocurre es que las gestiona internamente. Para
comprobar si se ha producido algn error se llama al mtodo public boolean
checkError().
Un objeto BufferedOutputStream puede decorar a un OutputStream,
dndole la posibilidad de que los bytes ledos se almacenen en un buffer y se escriban
cuando el buffer est lleno (salvo que se use flush(), que fuerza a escribir, est o no
lleno). Su funcionamiento no difiere mucho del correspondiente a la clase
BufferedInputStream, vista en el subapartado anterior: las llamadas a write()
van almacenando los datos en el buffer, que slo se escribir cuando est lleno (o se
llame a flush()). A continuacin, se muestra un ejemplo del uso combinado de las
clases BufferedOutputStream y FileOutputStream, el cual escribe N veces las
letras A y B en un archivo.
Ejemplo 9: EscribirCaracter.java
import java.io.*;
public class EscribirCaracter {
private final static int N=200; // Nmero de escrituras.
public static void main(String[] args) {
// Se crea un archivo y se escribe en l N veces la letra A.
// Luego, se escribe N veces la letra B.
BufferedOutputStream salida = null;
Miguel ngel Abin, Julio 2004
- 119/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 120/313 -
http://www.javahispano.org
- 121/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 122/313 -
http://www.javahispano.org
import java.io.*;
public class LeerPersona {
public static void main(String args[]) {
FileInputStream archivo = null;
ObjectInputStream entrada = null;
try {
archivo = new FileInputStream("personas.txt");
entrada = new ObjectInputStream(archivo);
Object tmp = entrada.readObject();
while (tmp != null) {
Persona persona = (Persona) tmp;
System.out.println (persona.toString());
tmp = entrada.readObject();
}
}
catch (EOFException e1) {
System.out.println("Archivo ledo");
}
catch (Exception e2) {
System.out.println("Imposible abrir el archivo o leer de l.");
e2.printStackTrace();
}
finally {
try {
entrada.close();
}
catch (Exception e3) {
System.out.println("No pudo cerrarse el flujo");
}
} //fin del bloque try-catch-finally
}
}
- 123/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 124/313 -
http://www.javahispano.org
- 125/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 126/313 -
http://www.javahispano.org
Direccin IP de
la mquina local
(localhost)
- 127/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Otra vez han vuelto a resucitar los escritores, de una manera que nunca hubieran
imaginado.
Como resulta muy til la propiedad de serializar a la vez conjuntos de objetos
vinculados, creo pertinente incluir un ejemplo, muy sencillo, en el cual se serializa un
objeto HashMap y luego se recuperan sus elementos, que son de tipos distintos.
- 128/313 -
http://www.javahispano.org
- 129/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 130/313 -
http://www.javahispano.org
- 131/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 132/313 -
http://www.javahispano.org
ISO 8859-1
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
sp
0
@
P
`
p
! # $ %
1 2 3 4 5
A B C D E
Q R S T U
a b c d e
q r s t y
NBS
P
& ( )
6 7 8 9
F G H I
V W X Y
f g h i
v w x y
* + , : ; < =
J K L M
Z [ \ ]
j k l m
z { | }
. /
> ?
N O
^ _
n
~
o
DE
L
Figura 60. Juego de caracteres ISO 8859-1 (ingls, alemn, francs, italiano...)
- 133/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Latin-1
ISO 8859-2
Latin-2
ISO 8859-3
Latin-3
ISO 8859-4
Latin-4
ISO 8859-5
Cirlico
ISO 8859-6
rabe
rabe
ISO 8859-7
Griego
Griego
ISO 8859-8
Hebreo
Hebreo
ISO 8859-9
Latin-5
ISO 8859-10
Latin-6
ISO 8859-11
Tailands
Tailands
ISO 8859-13
Latin-7
ISO 8859-14
Latin-8
Lenguas clticas
ISO 8859-15
Latin-9
ISO 8859-16
Latin-10
- 134/313 -
http://www.javahispano.org
U+0048
U+0065
U+006C
U+006C
U+006F
- 135/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 136/313 -
http://www.javahispano.org
Figura 62. Archivo escrito en ruso (texto sacado de una pgina rusa sobre
Unicode)
- 137/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 138/313 -
http://www.javahispano.org
String
offset,
int
longitud)
- 139/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Cada vez que se llame a un mtodo read(), se leern los caracteres que
correspondan segn la codificacin ISO 8859-7 a los bytes introducidos desde el
teclado.
Otro ejemplo: si se quiere convertir un archivo escrito con la codificacin ISO
8859-5 (usada para caracteres cirlicos) en caracteres Unicode, de modo que sean
manipulables por los programas Java, habr que usar cdigo similar a ste:
FileInputStream archivo = new FileInputStream("ruso.txt");
InputStreamReader entradaCaracteres = new InputStreamReader(
archivo, " ISO-8859-5");
Para leer el primer carcter cirlico de ruso.txt y mostrarlo en pantalla, se podra
escribir esto:
char c = (char) entradaCaracteres.read();
System.out.println(c);
En un sistema con fuentes cirlicas, se mostrara el primer carcter (por ejemplo,
).
Nota: Java usa internamente el formato UCS2 (un tipo de
UFT-16) para almacenar cadenas de texto y caracteres; pero
la capacidad de una mquina para mostrarlos reside en las
fuentes que tenga instalada en su sistema operativo. Por
ejemplo, si en un sistema no se han instalado fuentes chinas
no se podrn mostrar correctamente caracteres chinos.
- 140/313 -
http://www.javahispano.org
- 141/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
nombreArchivo,
boolean
anyadir)
- 142/313 -
http://www.javahispano.org
- 143/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 144/313 -
http://www.javahispano.org
Una manera muy visual de entender las clases de E/S de Java es imaginar que
son ros (la palabra filtro de las clases FilterXXX slo me hace pensar en filtros de
caf y en filtros pasabanda, pasabaja, etc). Un objeto como BufferedReader es
como un ro con un cauce ms grueso que el de un objeto InputStreamReader. As
pues, el ro InputStreamReader cabe dentro del ro BufferedReader. Cada vez
que un ro es engullido dentro de otro, este ltimo le proporciona ms caudal (es decir,
ms funciones o funciones ms especializadas), pero sigue usando el caudal del
engullido (sus mtodos).
- 145/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 146/313 -
http://www.javahispano.org
- 147/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
PrintWriter(Writer out)
PrintWriter(Writer out, boolean autoFlush)
PrintWriter(OutputStream out)
PrintWriter(OutputStream out, boolean autoFlush)
- 148/313 -
http://www.javahispano.org
- 149/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
LineNumberFileStream
LineNumberPipedInputStream
LineNumberSringBufferInputStream
DataFileInputStream
Estas clases no existen: gracias al
DataPipedInpudStream,
patrn decorador no son necesarias
BufferedPipedInputStream
BufferedFileInputStream
BufferedPipedInputStream
BufferedStringBufferInputStream
...
Algo falla, verdad? El nmero de clases necesarias se disparara. El problema
radica en que cualquier combinacin de los siguientes factores es posible cuando se
trabaja con E/S:
Miguel ngel Abin, Julio 2004
- 150/313 -
http://www.javahispano.org
Entrada o salida.
- 151/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Como una imagen vale ms que mil palabras, voy a abordar un ejemplo donde la
decoracin es visible. Para ello, abandono momentneamente el paquete java.io y
planteo este problema: cmo se podran incorporar bordes rectangulares y
redondeados a los elementos grficos (widgets) de Swing? (es ste un ejemplo donde
la decoracin es grfica)
Una solucin sera extender cada componente grfico de Swing. Se tendran
clases como
public
public
public
public
public
public
- 152/313 -
http://www.javahispano.org
}
}
}
- 153/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 154/313 -
http://www.javahispano.org
- 155/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 156/313 -
http://www.javahispano.org
BD
Interfaz de usuario
Clientes
- 157/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Las aplicaciones monolticas tenan sentido cuando los clientes eran poco ms
que pantallas verdes, pero tenan numerosos problemas. No quiero hacer lea del rbol
cado (aunque ste no ha cado del todo), pero citar los tres ms relevantes:
El coste de los mainframes era muy elevado. Pocas pequeas y
medianas empresas podan permitirse uno.
Como las tres funciones de la aplicacin estaban entremezcladas, el
cdigo de la interfaz grfica se mezclaba con el que implementaba la
lgica de la aplicacin o con el de acceso a datos. En consecuencia, a)
cualquier modificacin de la aplicacin resultaba difcil; y b) el cdigo se
deslizaba a marchas forzadas hacia la ilegibilidad.
La escalabilidad y eficacia de las aplicaciones estaba muy limitada. Las
mejoras solo se producan aumentando la memoria del mainframe o
aadindole procesadores, lo cual era muy costoso e implicaba cambios
en el hardware. Cada vez que se introduca un nuevo terminal, se
tornaban ms lentas las contestaciones a cada usuario.
Los mainframes llevaron a que se plantearan las preguntas que subyacen tras los
sistemas distribuidos. Cuando una organizacin se vea forzada a comprar un segundo
mainframe (para repartir la carga de trabajo, para otras oficinas, etc.), tena que
plantearse estas preguntas: cmo se puede repartir el cdigo de la aplicacin entre
dos mquinas?, cmo se pueden repartir las tareas del sistema entre dos
mainframes?, cmo puede hacerse que dos mquinas trabajen de forma sinrgica, de
modo que el rendimiento de las dos sea superior a la suma de los rendimientos
individuales? Estas preguntas, muy difciles de contestar en un entorno de mainframes
y terminales tontos, deben ser respondidas por todo sistema distribuido.
Con la llegada de los primeros PC, se dispuso de ordenadores en los que se
podan colocar parte de las funciones desempeadas por los mainframes. Por ejemplo,
se poda trasladar a los clientes la lgica de la presentacin, as como parte de la lgica
de la aplicacin.
La redistribucin de las funciones tuvo importantes consecuencias econmicas:
como los PC quitaban trabajo a los mainframes, se hizo posible poder sustituirlos por
mquinas ms baratas, como servidores UNIX. Estos servidores no tenan la potencia
o capacidad de un mainframe, pero tampoco las necesitaban: ya no tenan la
necesidad de mantener a decenas o cientos de terminales sin capacidades de clculo o
de procesado de datos. La era de los grandes dinosaurios tocaba a su fin (bueno,
algunos an sobreviven escondidos tras CORBA).
A las aplicaciones cuyas funciones se repartan entre un servidor y los PC se las
llam de tipo cliente-servidor (ahora se llaman aplicaciones cliente-servidor de dos
capas). El trmino cliente-servidor, explicado en 2.3, apareci al principio de la
dcada de los ochenta, y se hizo popular en la industria informtica a finales de esa
dcada. En el sentido ms general posible, se usa el trmino para designar a una
aplicacin susceptible de ser dividida lgicamente en dos o ms procesos donde cada
uno es cliente o servidor. Los clientes hacen peticiones y los servidores las atienden.
En las arquitecturas cliente-servidor de dos capas, el cliente (primera capa) se
comunica directamente con los servidores (segunda capa). Uso el trmino capa en el
mismo sentido en que se us para la arquitectura TCP/IP: una capa es una abstraccin
donde se agrupa a un conjunto de subproblemas relacionados entre s, relativos a
Miguel ngel Abin, Julio 2004
- 158/313 -
http://www.javahispano.org
algn aspecto de las comunicaciones en red. La ventaja de trabajar con capas es que
cada una puede desarrollarse e implementarse de forma independiente de las otras. El
cliente (primera capa) se encarga de todos los problemas asociados con hacer
peticiones; el servidor (segunda capa) trata las cuestiones vinculadas a contestar las
peticiones del cliente. En las aplicaciones en red, suele identificarse explcita o
implcitamente los trminos capa e implementacin de la capa.
Las separacin en capas es una divisin lgica, y no conlleva necesariamente
ninguna opcin de distribucin fsica de las capas (el cliente y el servidor podran
ejecutarse como procesos independientes en una misma mquina). Lo importante en
una capa es que est estructurada de manera que su implementacin pueda
desarrollarse y mantenerse con independencia de las otras, no su ubicacin
fsica. No obstante lo dicho, en el caso de aplicaciones en red, lo usual es que las
capas se implementen en mquinas o anfitriones distintos. Muchos autores de textos
sobre redes suelen dar por sentado que las capas lgicas corresponden a la
separacin fsica entre anfitriones o dispositivos. Esta correspondencia no es del todo
cierta, pero resulta admisible si slo nos referimos a entornos de red.
En la figura 72 se muestra un ejemplo de la arquitectura c-s de dos capas,
correspondiente a una situacin muy comn: el cliente se encarga de la interfaz grfica
y de parte de la lgica de la aplicacin; el servidor se encarga de la lgica de acceso a
datos y de parte de la lgica de la aplicacin.
En la figura 73 se muestran los cuatro tipos de arquitecturas c-s de dos capas. El
caso extremo de las aplicaciones de dos capas donde el servidor realiza todas las
tareas nos conduce de vuelta a las aplicaciones monolticas o centralizadas, de una
sola capa (el servidor se encarga de todo; no hay cliente, pues el terminal tonto no
ejecuta procesos).
La figura 74 muestra un ejemplo de una aplicacin de dos capas con clientes
gordos. Un cliente de este tipo se encarga de la interfaz de usuario, de la lgica de la
aplicacin y de parte de la lgica de acceso a datos. En el ejemplo concreto de la
figura, se encarga de enviar las consultas a la base de datos.
La figura 75 se muestra una aplicacin basada en la estructura mostrada en la
figura 72.
- 159/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
BD
Clientes
Interfaz de
usuario
Lgica de la
aplicacin
- 160/313 -
http://www.javahispano.org
Centralizada o monoltica
Cooperativa
- 161/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Servidor de archivos
Figura 74. Un ejemplo del tipo d) de la figura 73. Extrado de una propaganda
comercial
Figura 75. Un ejemplo del tipo c) de la figura 73. La aplicacin SIGEF ha sido
desarrollada por el Ministerio de Economa y Finanzas de Ecuador
- 162/313 -
http://www.javahispano.org
Cada capa se implementa como una aplicacin bien definida y separada. Adems,
en un contexto de red, estas aplicaciones suelen ejecutarse en anfitriones distintos. A
continuacin expongo los nombres tpicos que se dan a esas aplicaciones y anfitriones.
La aplicacin de interfaz de usuario o aplicacin GUI, que se ejecuta en el
ordenador del usuario (cliente)
La aplicacin asociada a la capa intermedia, que se ejecuta en un anfitrin
llamado servidor de aplicaciones (suele usarse este ltimo termino tambin
para la propia aplicacin).
El sistema de gestin de bases de datos o aplicacin de persistencia, que se
ejecuta en un segundo anfitrin llamado servidor de bases de datos.
Miguel ngel Abin, Julio 2004
- 163/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Aunque la situacin anterior es la ms comn, no hay motivo terico para que las
aplicaciones que implementen las tres capas no puedan ejecutarse en un mismo
anfitrin.
Las arquitecturas de dos capas se pueden ver como arquitecturas de tres capas
donde no existe explcitamente la capa intermedia: sus funciones se hallan distribuidas
entre el cliente y el servidor. La separacin en tres capas permite desarrollar
independientemente los tres grandes componentes de una aplicacin, y que los
programadores puedan dedicarse a implementar cada componente por separado.
Dicha situacin resulta imposible en una arquitectura de dos capas, donde siempre hay
capas donde se mezclan los componentes. En el caso lmite de las arquitecturas
centralizadas, los tres componentes estn en una sola capa: el servidor.
Lgica de la aplicacin
Clientes
Interfaz de
usuario
Figura 76. Ejemplo de una aplicacin de tres capas que se ejecuta en dos
mquinas
- 164/313 -
http://www.javahispano.org
Lgica de negocio
en un servidor
DBMS en un
solo servidor
Figura 77. Ejemplo de una aplicacin de tres capas que se ejecuta en tres
mquinas. Extrado de una propaganda comercial
- 165/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Internet
Lgica de la
aplicacin
Lgica de presentacin
Datos
compartidos
Figura 79. Comparacin entre una aplicacin c-s de dos capas y una de tres
capas
Miguel ngel Abin, Julio 2004
- 166/313 -
http://www.javahispano.org
Navegador web
Navegador web
HTTP
Navegador web
Navegador web
World Wide
Web
Servidor web
Capa intermedia
(Lgica de la aplicacin)
Cdigo de la aplicacin
Capa de datos
(Lgica de acceso a datos)
Achivos
DBMS
BD
- 167/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
EVOLUCIN DE LAS
ARQUITECTURAS INFORMTICAS
Sistemas c-s 2 capas
Log. presentacin
Sistemas monolticos
Log. aplicacin
Log. presentacin
Log. aplicacin
Log. aplicacin
Lgica Acc. datos
Log. aplicacin
Lgica Acc. datos
Lgica Acc. datos
Base de datos
Figura 81. Evolucin de las arquitecturas de las aplicaciones informticas
Las arquitecturas c-s de capas no terminan con las de tres capas. Se pueden
tener arquitecturas de cuatro capas, de cinco, etc. En general, de N capas. La divisin
en ms de tres capas resulta provechosa cuando interesa distribuir entre distintas
mquinas la carga de trabajo. Ms que estudiar cada una de las situaciones en las que
interesa trabajar con cuatro o ms capas, comentar a continuacin dos escenarios
comunes.
El primer escenario corresponde al caso en que se trabajan con varias bases de
datos, cada una con su DBMS. En este caso, puede que interese dividir la capa de
datos o de persistencia en varias subcapas, asociando una a cada base de datos. La
ventaja de esta aproximacin consiste en que puede ubicarse cada subcapa de datos
(mejor dicho, su implementacin) en un nodo de la red, con lo cual la aplicacin ser
fcilmente escalable cuando aumente el nmero de peticiones.
El segundo corresponde al caso de las aplicaciones de Internet. En ellas, se suele
trabajar con navegadores web que procesan etiquetas HTML y con servidores
intermedios o de aplicaciones escritos en C/C++ o Java. En estos casos, el salto entre
el HTML y un lenguaje como Java o C/C++ es muy grande: estos ltimos lenguajes
pueden usarse para generar documentos HTML o para procesar peticiones HTTP de
los clientes, pero entonces se mezcla la lgica de la aplicacin y la de la interfaz. Una
solucin habitual para reducir el salto estriba en dividir la capa intermedia en dos
subcapas: una es implementada por el servidor de aplicaciones; la otra, por uno o
Miguel ngel Abin, Julio 2004
- 168/313 -
http://www.javahispano.org
varios programas CGI (vase 2.8.5) que reciben peticiones de los clientes
(navegadores) y generan pginas HTML a partir de las respuestas que obtienen del
servidor de aplicaciones, encargado de la lgica de la aplicacin. En la figura 47b ya
vimos un ejemplo de esta arquitectura de cuatro capas.
Las arquitecturas de N capas aparecen con cierta frecuencia en las tecnologas
basadas en Java. Por ejemplo, en una aplicacin JSP/Servlet bien diseada suele
descomponerse en tres partes (subcapas) el cdigo que reside en el servidor de
aplicaciones:
Las ventajas de las arquitecturas c-s multicapa (esto es, de tres o ms capas)
sobre las arquitecturas anteriores son muchas:
La separacin entre la lgica de la aplicacin y la de
presentacin permite modificar de forma sencilla las
aplicaciones. Cuando cambia la lgica de negocio, slo hay que
modificarla en un nico lugar.
Se reduce el trfico de datos por las redes, pues la capa
intermedia slo transmite los datos imprescindibles para las
tareas de la aplicacin.
El cliente se mantiene separado de las bases de datos y de los
detalles de las redes intermedias. No necesita conocer dnde
estn los datos (pero s dnde se localizan los servidores de
aplicaciones).
Las conexiones a las bases de datos, que son costosas en
cuanto a recursos, pueden repartirse entre varios anfitriones.
La administracin de las aplicaciones es menos compleja, pues
se reparte entre varias capas.
Miguel ngel Abin, Julio 2004
- 169/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Lgica de presentacin
Lgica de aplicacin
Subcapas
Subcapas
Base de datos
Cada subcapa puede estar en una mquina. Una lgica dada puede estar repartida
entre muchos anfitriones
- 170/313 -
http://www.javahispano.org
- 171/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 172/313 -
http://www.javahispano.org
distribuidos se construyen para tratar con aplicaciones que quizs se ejecuten en miles
o millones de nodos, correspondientes a distintas plataformas (mainframes, servidores
UNIX, ordenadores personales de distintos fabricantes, telfonos mviles de distintas
empresas de telecomunicaciones, agendas electrnicas, electrodomsticos
inteligentes, etc.). Para permitir el trabajo colaborativo entre nodos de tan variada
naturaleza, se deben incorporar mecanismos ausentes en las aplicaciones multicapa.
Por ejemplo, en un sistema distribuido no resulta razonable que el cliente sepa
explictamente en qu anfitrin se ejecuta el servidor al que debe dirigir sus peticiones
(los servidores pueden cambiar de ubicacin continuamente; pueden morir y renacer
en otro nodo). En una aplicacin de N capas, si un proceso servidor cambia de
ubicacin (pasa de un anfitrin a otro), los clientes deben ser avisados; en un sistema
distribuido, los clientes jams saben dnde se ejecutan los servidores (es ms, puede
que stos no existan hasta que algn cliente los llame).
Otro ejemplo: en una aplicacin multicapa puede aceptarse que los nodos usarn
una misma representacin externa de los datos cuando los transmitan a travs de las
redes, pues siempre puede elegirse el hardware para que as sea. En un sistema
distribuido, la situacin cambia radicalmente: hay involucrados tantos tipos de hardware
que resulta absurdo suponer que todos los nodos usarn una misma representacin
externa para los datos.
As las cosas, un sistema distribuido tiene que incorporar servicios o funciones
innecesarias en un sistema multicapa. La lista de servicios puede ser tan larga como
uno quiera (como demuestra el caso de CORBA), pero hay tres fundamentales:
- 173/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 174/313 -
http://www.javahispano.org
Figura 84. Algn da, algn da desarrollar aplicaciones ser como ensamblar
componentes electrnicos.
Los componentes distribuidos favorecen la reutilizacin del software, tal y como
los circuitos integrados y chips favorecen la reutilizacin de los circuitos electrnicos.
Un componente distribuido puede ser usado por otros componentes y aplicaciones,
distribuidos o no. Un ejemplo aclarar esto: supongamos que hemos desarrollado un
componente de clculo matemtico CalcMat que necesita ejecutarse sobre mquinas
con muchos recursos (RAM, procesadores, disco duro, etc.). Si ese componente se
instalara en cada mquina de una red, muchas no cumpliran los requisitos para su
uso: en ellas, el componente no podra ejecutarse o su funcionamiento sera psimo.
Miguel ngel Abin, Julio 2004
- 175/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Mquina A
Cliente 1
Mtodo 2
Componente
CalcMat
Mquina B
Cliente 2
Mtodo 3
Mquina C
Cliente 3
Miguel ngel Abin, Mayo 2004
- 176/313 -
http://www.javahispano.org
- 177/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 178/313 -
http://www.javahispano.org
HTTP/HTML
Navegador
HTTP/HTML/DHTML
HTTP/HTML
Servidor web
Servidor de
aplicaciones
web
Servidor de
aplicaciones
Tecnologa
de objetos
distribuidos:
CORBA, RMI,
etc.
Servidor de
aplicaciones
- 179/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 180/313 -
http://www.javahispano.org
Los servicios web, tan en boga estos das, son componentes de arquitecturas
distribuidas que usan sus propias interfaces entre programas y sus propios protocolos y
servicios de registro para que cualquier aplicacin de una plataforma pueda emplear
servicios ofrecidos por otras plataformas. Se usa XML (Extensible Markup Language:
lenguaje extensible de formato) para describir el servicio, para escribir los mensajes
que genera o recibe y para registrarlo (una vez registrado, estar a disposicin de
quien desee usarlo).
Un servicio web es un componente distribuido que ejecuta procesos y ofrece a sus
clientes una interfaz bien definitiva y accesible mediante protocolos de Internet. Las
peticiones y las respuestas son mensajes XML (vase la figura 87).
Para emplear un servicio web se necesita hacer pblica la interfaz que ofrece a los
clientes (descrita en WSDL: Web Service Description Language), la cual incluye los
argumentos y el tipo de retorno de cada mtodo, y dar una manera de localizar el
servicio y su interfaz (mediante UDDI: Universal Description Discovery and Integration).
Los mensajes siguen un protocolo basado en XML: el SOAP (Simple Object Access
Protocol), que define la sintaxis de los mensajes (envoltura, cabecera y cuerpo), la
codificacin de los datos y las convenciones para representar llamadas remotas.
Los servicios web simplifican mucho el desarrollo de sistemas distribuidos: cada
componente del sistema puede desarrollarse con el lenguaje y la plataforma que uno
desee, y luego se componen mediante servicios web.
- 181/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
1. Describir y
publicar
el servicio
Directorio
servicios web
XML
(WSDL)
XML
(UDDI)
2. Localizar
el servicio
XML
(WSDL)
Suministrador de
servicios web
Cliente
Servicio
Servicio
Servicio
XML
(SOAP)
W
E
B
XML
(SOAP)
Servicio
3. Utilizar el servicio
Figura 87. Arquitectura de los servicios web. Figura de Sandra Aguirre
En la figura anterior hay tres elementos:
- 182/313 -
http://www.javahispano.org
Llamada a un
servicio web
(SOAP)
Respuesta del
servicio
(SOAP)
Argumento
de la
llamada
Valor
devuelto
por la
llamada
- 183/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
La principal diferencia entre CORBA y los servicios web estriba en que los ltimos
no trabajan con objetos, sino con mensajes. Ignoro por qu SOAP significa protocolo
sencillo de acceso a objetos, cuando no trabaja con objetos (en las ltimas
especificaciones de este protocolo no aparece ya el significado de las siglas). A
diferencia de CORBA, los servicios web no definen un mecanismo de persistencia: se
deben usar los mecanismos que proporcionan los lenguajes con los que se escriben las
aplicaciones (C++, Java, C#, etc.).
Desde una perspectiva crtica, no se puede decir que los servicios web sean muy
originales: obedecen al modelo cliente-servidor ms simple que pueda haber (un cliente
y un servidor, sin cambio de papeles). Su nica novedad consiste en usar XML.
Aunque se les ha visto como los sucesores de CORBA (y a veces como sus
enterradores), la realidad es que ambas tecnologas son muy distintas: CORBA est
orientada al desarrollo de aplicaciones seguras y escalables, mientras que los servicios
web estn orientados a ofrecer acceso a aplicaciones CORBA, J2EE, .Net, RMI.
Los servicios web permiten usar aplicaciones ya escritas, para simplificar el
acceso de los clientes a ellas; pero no se encargan de la implementacin de los
servicios, que se hace con los lenguajes tradicionales (C, C++, Java, etc.). Se puede
acceder a las aplicaciones CORBA mediante un servicio web, como hace AT&T para
dar un punto de entrada cmodo a los usuarios; pero no se pueden escribir
aplicaciones CORBA mediante los protocolos de los servicios web.
Si el lector ha trabajado con C#, el lenguaje nativo de la plataforma .Net, quiz se
pregunte qu sentido tiene usar CORBA o RMI (esta ltima tecnologa se ver en el
siguiente subapartado), cuando uno dispone en C# de la palabra clave [WebMethod].
Esta palabra, delante de un mtodo, permite exponer un servicio web basado en dicho
mtodo. Para llamar al mtodo desde una mquina remota, Visual Studio .Net genera
un cdigo que acta de intermediario, el cual debe colocarse en el anfitrin remoto.
Ms sencillo imposible.
Pero que algo sea sencillo no quiere decir que sea bueno: con [WebMethod] no
se pueden construir aplicaciones que sobrevivan a una buena dosis de realidad.
CORBA (y, en menor medida, RMI) es complicado porque se cre para fabricar
aplicaciones industriales, donde palabras como seguridad, escalabilidad, velocidad y
eficacia definen las santas virtudes de los grandes sistemas empresariales. Si la
especificacin de CORBA es tan larga (ms de 1.000 pginas en su ltima versin) no
es por casualidad: define muchas formas de funcionamiento que pueden marcar la
diferencia entre que una aplicacin sea capaz o no de manejar miles de transacciones
por segundo.
Trabajar con C# y [WebMethod] tiene sentido si uno quiere construir pequeas
aplicaciones o si quiere ver cmo se registra y se llama a un servicio web (con Visual
Studio .Net es casi trivial hacerlo); pero no si uno quiere construir aplicaciones que
atiendan muchas peticiones, que admitan modificaciones dinmicas o que deban
cumplir unos requisitos mnimos de fiabilidad y seguridad. Para esas aplicaciones,
CORBA sigue siendo una opcin muy vlida y de mucha solera.
No negar que CORBA es complicado, pero su complejidad no es innecesaria: las
aplicaciones distribuidas no son sencillas (vase la pgina 177). Las personas del OMG
que trabajan en CORBA no son tecncratas con tendencias sdicas hacia los
desarrolladores ni creen en el inters tcnico e intelectual de la complejidad. Resulta
divertido imaginrselos como personas de ojos vidriosos que escuchan Kiss the boot of
shiny, shiny leather / Shiny leather in the dark mientras se devanan los sesos
intentando complicar un poco ms la vida de los programadores; pero las cosas no son
- 184/313 -
http://www.javahispano.org
as: tienen que considerar todas las situaciones en las que puede verse envuelta una
aplicacin distribuida de tipo empresarial.
- 185/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Servidores
.NET
J2EE
Mensajes XML
CORBA
C/C++
COBOL
Smalltalk
Clientes
- 186/313 -
http://www.javahispano.org
Cuando me siento pesimista, pienso que los servicios web constituyen con
muchas matizaciones, desde luego un paso hacia atrs con respecto a CORBA o a
RMI. La falta de orientacin a objetos recuerda a las RPC (Remote Procedure Call:
llamada a procedimientos remotos), que eran comunes cuando los lenguajes
procedurales dominaban la programacin. Al no existir polimorfismo, no se pueden
hacer comprobaciones o conversiones dinmicas de tipos. De hecho, tampoco se
pueden hacer comprobaciones estticas: un cliente SOAP slo averigua que ha
enviado un argumento de un tipo incorrecto cuando el servidor SOAP que lo recibe lo
rechaza. Enviar datos a travs de redes para que el servidor descubra que no son del
tipo adecuado es un desperdicio de tiempo y de ancho de banda, desperdicio
acrecentado porque los datos en un mensaje XML no constituyen ms que una
pequea parte del mensaje (el resto corresponde a informacin XML).
Ni siquiera el protocolo HTTP es el ms adecuado para los procesos sncronos de
tipo peticin-respuesta: este protocolo fue creado para abrir una conexin, intercambiar
datos y cerrar la conexin; no para esperar pasivamente quizs durante largos
perodos respuestas. HTTP dista mucho de ser una solucin ptima para dichos
procesos, pero se usa porque es simple. Aparte de la falta de seguridad, fiabilidad y
persistencia de soluciones como [WebMethod], tambin hay que sealar que
consumen muchos recursos al usar un protocolo que, en definitiva, no es el ms
apropiado. Mantener una conexin HTTP durante milisegundos o segundos no es
problema para ninguna mquina, pero mantener cientos o miles de conexiones
simultneas durante minutos u horas s lo es.
Si piensa que escondo algn motivo poco confesable en contra de C# o de
los servicios web, le sugiero que haga la siguiente prueba: escriba un mtodo
remoto con [WebMethod] que permanezca varios minutos haciendo clculos antes de
devolver una respuesta (con un bucle dentro del mtodo, por ejemplo). Despus, haga
que unos cuantos clientes (diez, pongamos por caso) accedan a l simultneamente
(mediante hilos, por ejemplo). Por ltimo, vaya aumentando el nmero de clientes: cien,
doscientos, mil, dos mil, etc. Si usa un PC normal y corriente, estoy seguro de que le
sorprendern los resultados. Como puede intuirse, la situacin empeora si se
consideran los tiempos de latencia de las redes y los retrasos por reenvos de paquetes
defectuosos.
Si escucha que los servicios web pueden abrir de forma automtica los sistemas
empresariales a otros sistemas (de clientes, de socios, etc.), tal y como dos personas
aprenden conversando lo que una puede ofrecer a otra, tenga por seguro que no le
estn hablando con la voz de la razn. Para entender una interfaz, hay que saber
cules son sus significados para las partes implicadas y si son coincidentes (vase la
nota sobre ontologas en la pgina 25). Por ahora, slo las personas pueden adquirir
ese tipo de conocimiento.
Un ejemplo muy sencillo bastar para poner los puntos sobre las es. Suponga
que un servicio web descubre automticamente que una organizacin ofrece un
servicio web con una interfaz del tipo double calcularAmortizacion1987
(double importe). De qu le servir al usuario final esa informacin si no sabe
qu clase de amortizacin se calcula (puede ser financiera o de un bien) o que algo
especial pas en 1987? Mientras un ser humano no conozca el significado de la
interfaz, de bien poco servir sta. Por ahora, el uso automtico de agentes que
descubran y comprendan las interfaces de los sistemas empresariales es quimrico.
Suele argumentarse que CORBA es una tecnologa complicada (lo cual es
innegable); y que los servicios web son mucho ms simples porque se basan en XML.
Ante esa afirmacin, una balanza que midiera la simplicidad caera del lado de los
servicios web; pero otra que midiera la veracidad de la afirmacin se rompera: los
Miguel ngel Abin, Julio 2004
- 187/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
servicios web usan XML, pero tambin usan muchas tecnologas asociadas, como
XSL/XSLT Acaso es sencillo trabajar con XSL/XSLT?
Algunos de los errores que se cometieron con CORBA se estn repitiendo con los
servicios web, en lo que parece otra confirmacin de que lo nico que nos ensea la
Historia es que la Historia no nos ensea nada. Por ejemplo, las API disponibles para
SOAP carecen de interoperabilidad entre s (como suceda con los primeros ORB de
CORBA). Un programador que desarrolle un servicio web con una herramienta basada
en una determinada implementacin de SOAP no podr llevarse el cdigo a otra
herramienta basada en otra implementacin de SOAP (aunque el lenguaje de
programacin no vare): se ver obligado a volver a escribir el cdigo en la segunda
herramienta, porque los mtodos de cada API son propios de ella. Todo parece
interoperable cuando las cosas se mantienen en el aire; pero cuando se ponen en el
suelo y llega la hora de escribir cdigo, aparecen problemas de interoperabilidad y de
portabilidad del cdigo entre los productos, bibliotecas y frameworks SOAP.
As las cosas, me pregunto qu habra sucedido si Microsoft e IBM hubieran
apoyado a CORBA con la misma energa con que promueven los servicios web. Es una
pena que el presupuesto del OMG para mercadotecnia fuera tan reducido.
- 188/313 -
http://www.javahispano.org
Cualquier plataforma para la que exista un JDK (1.1 o posterior) puede usar
la RMI.
- 189/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 190/313 -
http://www.javahispano.org
import java.rmi.*;
public interface CalcMat extends Remote {
import java.rmi.*;
import java.rmi.server.*;
public class CalcMatImp extends UnicastRemoteObject
implements CalcMat {
public double hacerCalculoMuyComplicado(double a,double b)
throws remoteException {
// Cuerpo del mtodo
}
// Resto de declaraciones de mtodos y mtodo main
}
Un cliente que deseara acceder al servicio de clculo matemtico se conectara
as:
CalcMat cm = new Registro("anfitrion", "nombreObjeto");
cm.hacerCalculoMuyComplicado(2.5656, 3.14159265358972);
Registro sera una clase encargada de conectar con el anfitrin donde se
ejecute CalcMat, de localizar el objeto remoto nombreObjeto, instancia de la clase
CalcMatImp, y de instanciar en el anfitrin cliente un objeto representante (proxy) del
objeto remoto en el espacio de direcciones del objeto local (cm). La necesidad de que
se realicen estos tres pasos y la manera como se realizan se irn explicando en el
resto de este apartado. No obstante, adelanto ya que no es necesario programar la
clase Registro: RMI proporciona todo lo necesario.
A veces se dice que RMI (o CORBA) es middleware. Esta trmino es una de esas
entraables palabras anglosajonas que significan lo que a uno le conviene que
signifiquen (scattering es mi favorita). Segn el libro Client / Server Survival Guide Third
Edition [R. Orfali, D. Harkey y J. Edwards, 1999],
Middleware es un trmino indefinido que abarca a todo el software distribuido
necesario para el soporte de interacciones entre clientes y servidores. Imagnelo
como el software que ocupa la parte intermedia del sistema de cliente/servidor. Es
el enlace que permite que un cliente obtenga un servicio de un servidor. Dnde
empieza y dnde acaba el middleware? Empieza en el mdulo de la API en la
parte del cliente que se emplea para invocar un servicio y comprende la
Miguel ngel Abin, Julio 2004
- 191/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Figura 93. Ubicacin del middleware en una arquitectura c-s de dos capas
- 192/313 -
http://www.javahispano.org
- 193/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 194/313 -
http://www.javahispano.org
IMPLEMENTACIN DE LA INTERFAZ
REMOTA
Interfaz remota
MVJ LOCAL
MVJ REMOTA
implementa
implementa
Objeto
cliente
Stub
Skeleton
Objeto
servidor
- 195/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Tanto los adaptadores como los esqueletos implementan las interfaces remotas
de los objetos a los cuales estn asociados. Examinemos lo que sucede cuando un
adaptador recibe una llamada de un objeto local (para los esqueletos el proceso es
similar): mediante la serializacin de objetos, su implementacin del mtodo llamado
produce un flujo ordenado de bytes, independiente de cualquier plataforma, donde
graba las descripciones de las clases de los objetos que se pasan como argumento, las
secuencias de bytes que representan a los objetos y la informacin sobre los lugares
desde donde se pueden cargar los bytecodes de dichas clases.
En el subapartado 3.3 se escribi que en el proceso de serializacin se guarda la
descripcin de las clases de los objetos serializados, adems de la informacin
correspondiente al estado de los objetos; pero no se mencion que se grabase
informacin sobre la ubicacin de las clases. Antes al contrario: se afirm que haba
que configurar el CLASSPATH local para que hiciera referencia a los archivos .class
necesarios. Esta aparente discrepancia conduce a dos preguntas: qu clases se usan
en la RMI para serializar y deserializar objetos?; por qu se guarda informacin sobre
la localizacin de los .class?
La contestacin a la primera es que se utilizan unas subclases de
java.io.ObjectOutputStream y de java.io.ObjectInputStream, no estas
clases. Por ejemplo, se usa la subclase de ObjectOutputStream
sun.rmi.server.MarshalOutputStream. ObjectOutpuStream define un
mtodo protected
void
annotateClass
(Class
clase)
throws
IOException que no hace nada (no est implementado). Pese a ello, siempre que
ObjectOutputStream escribe las descripciones de las clases, llama a
annotateClass(). Si se incluye este mtodo es con vistas a que los programadores
y la RMI puedan implementarlo en las subclases de ObjectOutputStream. La
infraestructura de la RMI, al redefinir este mtodo y otros, adapta a sus necesidades
el proceso de serializacin de objetos, incluyendo en el flujo informacin (anotaciones)
sobre el lugar o lugares desde donde pueden cargarse los bytecodes necesarios. Con
respecto a ObjectInputStream, la subclase encargada del proceso de
deserializacin
redefine
el
mtodo
protected
Class
resolveClass(ObjectStreamClass descripcion) throws IOException,
ClassNotFoundException, que por defecto carga las clases locales cuyas
descripciones aparecen en el flujo, y permite que las clases puedan ser cargadas
desde cualquier otra fuente. Internamente, la RMI crea y maneja las subclases
derivadas de ObjectInputStream y ObjectOutputStream; el programador no
necesita preocuparse por serializar y deserializar explcitamente.
La respuesta a la segunda deriva de que la RMI trabaja con entornos distribuidos.
En una aplicacin que se ejecuta en una sola mquina, cuando se deserializa el flujo se
busca, para cada descripcin de clase que se encuentra en l, su archivo .class en el
directorio actual y en los incluidos en el CLASSPATH. Como todos las clases se
compilan en la misma mquina, lo lgico es que se encuentren en ella. Si algn archivo
no se encuentra es porque no ha sido compilado o porque el CLASSPATH est ml
configurado. En una aplicacin distribuida no podemos esperar que todos los archivos
.class de la aplicacin estn en los sistemas locales de archivos de todos los
anfitriones donde se ejecuta. Por ello, las subclases de ObjectOutputStream que
usa RMI redefinen el mtodo annotateClass()para que permita grabar en el flujo de
bytes informacin sobre la codebase (especificada en la propiedad
Miguel ngel Abin, Julio 2004
- 196/313 -
http://www.javahispano.org
- 197/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Proceso cliente
Serializacin
referencia
llamada
Deserializacin
stub
mtodo A
skeleton
mtodo C
010010101001
Objeto cliente
TCP/IP
Objeto servidor
Red fsica
- 198/313 -
http://www.javahispano.org
Los objetos remotos que estn exportados (esto es, preparados para
aceptar peticiones de los clientes por un puerto; ya veremos ms
adelante cmo se exportan los objetos remotos) nunca se envan, en
su lugar se envan referencias a ellos (instancias de una clase
adaptadora o stub). Lo mismo aplica para los valores de retorno. Estos
objetos se pasan, pues, por referencia. Si estos objetos, aun siendo
remotos, no estn exportados, se pasan por valor.
- 199/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
MVJ
public int suma (int a,
int b) {
return (a + b);
La referencia empleado
a un objeto Empleado se
pasa por valor
}
suma(2, 5);
2 y 5 se pasan por
valor
2 y 5 se pasan por
valor
MVJ remota
Plantilla plantilla
suma(2, 5);
= new Plantilla();
Objeto local
Objeto remoto
Empleado empleado
= new Empleado();
subirSueldo(empleado);
plantilla
empleado se pasa por
valor: se copia en la
MVJ remota usando
la serializacin de
objetos
Figura 98. Argumentos que se pasan por valor en una llamada remota
Miguel ngel Abin, Julio 2004
- 200/313 -
http://www.javahispano.org
MVJ remota
Comprador comp
GestorCompra gestorCompra
= new GestorCompra()
= new Comprador();
producto:getProducto()
comp
Objeto local
MVJ remota
gestorCompra
Objetos
remotos
producto
Figura 99. Argumentos que se pasan por referencia en una llamada remota
Que los objetos locales se pasen por valor resulta inevitable: si slo se pasaran
referencias a los objetos locales (adaptadores o stubs), los remotos tendran que
consultar a la mquina local (que para ellos sera remota, pues se ejecuta en otra
MVJ).
Supongamos, para clarificar la situacin, que un cliente enviara como argumento
del mtodo remoto guardarEmpleado(Empleado empleado) un adaptador del
objeto empleado en lugar de una copia de empleado. El objeto remoto al cual va
dirigida la llamada podra necesitar informacin sobre la instancia empleado: edad,
sueldo, tipo de contrato, etc. Necesitara, pues, consultar al objeto cliente y llamar a
mtodos como getEdad(), getSueldo(), etc.; porque, a fin de cuentas, tendra una
referencia remota al objeto local, no una copia. En qu se traducira todo esto? En un
continuo ir y venir de mensajes a travs de la red o de las redes que mediaran entre
ambos objetos. Esta estrategia resulta inviable por dos motivos; a saber: los tiempos de
latencia asociados a las transmisiones en red y los fallos de las redes.
- 201/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Nota: Java pasa argumentos slo por valor, sean tipos primitivos u objetos.
Muchas veces se confunde el paso por valor de referencias a objetos con el
paso por referencia. El primero es el mecanismo que usa Java; C++ utiliza el
segundo. Cuando se dice que los objetos remotos Java se pasan por
referencia en las llamadas remotas, se busca expresar que se pasan stubs o
adaptadores, los cuales vienen a ser referencias a los verdaderos objetos
remotos. Y estas referencias se pasan por valor mediante serializacin.
RMI usa el paso por valor de adaptadores para simular el paso por referencia,
inexistente en Java. Cmo lo hace? Cuando el cliente llama al servidor con
un argumento que es un objeto remoto exportado, se enva, en lugar del
objeto remoto, un adaptador. Cuando el servidor llama al cliente, en realidad
llama al adaptador (que es local para l). Como el adaptador apunta al objeto
remoto del cliente, existe un vnculo entre el servidor y el verdadero objeto
remoto.
La confusin entre paso por valor de referencias y paso por referencia es muy
frecuente, tanto entre expertos como entre nefitos. En la bibliografa sobre
sistemas distribuidos, siempre se usa paso por referencia para designar a
las dos posibilidades anteriores. Aun siendo consciente de la inexactitud, uso
paso por referencia en ocasiones donde se trata de paso por valor de
referencias. Intento as no discrepar de la terminologa usada por la mayor
parte de los textos.
La copia por valor se realiza mediante la serializacin de objetos de Java, vista en
el apartado dedicado al paquete java.io y que ya se ha mencionado en este
subapartado. Mediante ella, los objetos pueden ser enviados por los clientes en forma
de flujos de bytes, y pueden ser reconstruidos en los servidores, que crearn en sus
espacios de direcciones las nuevas instancias (idnticas a las serializadas en los
clientes), basndose en la informacin contenida en los flujos. Aparte de la
serializacin, Java no incorpora ningn otro mecanismo para copiar objetos de forma
automtica. Con esta potente herramienta, se asegura adems que, si un objeto
contiene referencias a otros objetos, stas se conservarn en sus copias. Sin la
serializacin, una llamada a un objeto remoto en la que se llamara internamente a un
mtodo de algn objeto al cual se tuviera una referencia, obligara a que existiera
comunicacin con la MVJ donde residiera este ltimo objeto. Se producira, pues, un
trasiego innecesario y peligroso de mensajes entre la red o las redes intermedias.
Cuando se pasan objetos remotos exportados (o se devuelven como valores de
retorno), la copia se realiza por referencia. Internamente, se sigue usando la
serializacin de objetos, pero la RMI da el cambiazo: incluye en el flujo objetos
adaptadores o stubs en lugar de los verdaderos objetos remotos. As pues, la copia por
valor de los objetos remotos se sustituye por la copia por valor de sus referencias
remotas (adaptadores, los cuales saben en qu mquina est el verdadero objeto
remoto y mediante qu puerto pueden acceder a l). Como las clases adaptadoras
implementan la interfaz java.io.Serializable, no hay ningn problema para que
sus instancias sean serializadas y deserializadas. Para sustituir los objetos remotos
exportados por sus adaptadores correspondientes se usa una redefinicin del mtodo
protected Object replaceObject(Object objeto) throws IOException
de la clase java.io.ObjectOutputStream.
- 202/313 -
http://www.javahispano.org
- 203/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
ARQUITECTURA SIMPLIFICADA DE
LA RMI DE JAVA
MVJ LOCAL
MVJ REMOTA
Objeto
Objetocliente
cliente
Objeto
Objetoservidor
servidor
Stub
adaptador)
Stub(adaptador)
(adaptador)
Skeleton
esqueleto)
Skeleton(esqueleto)
(esqueleto)
CAPA
CAPAREMOTA
REMOTAOORMI
RMI
CAPA
CAPADE
DETRANSPORTE
TRANSPORTE
Miguel ngel Abin, Mayo 2004
Capa de los
adaptadores (stubs)
Capa de los
esqueletos (skeletons)
Capa de referencia
remota (RMI)
Capa de referencia
remota (RMI)
Capa de transporte
Capa de transporte
Capa de red
Capa de red
Capa de enlace
Capa de enlace
Red fsica
Comunicacin virtual
Miguel ngel Abin, Mayo 2004
Comunicacin real
- 204/313 -
http://www.javahispano.org
- 205/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
MVJ remota
Objeto cliente
Objeto servidor
Queda
registrado
con un
nombre
Objeto adaptador
(stub)
Red
Comunicacin virtual
Objeto esqueleto
(skeleton)
Comunicacin real
Figura 102. Vista simplificada de una llamada remota (se tiene en cuenta el
servicio de registro RMI)
Con carcter general, para las comunicaciones en la arquitectura de la RMI se
siguen estos pasos (algunos son realizados por los usuarios, otros por la RMI):
- 206/313 -
http://www.javahispano.org
- 207/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Anfitrin servidor
Servidor de registro remoto
Socket
Servidor
Anfitrin servidor
miObjeto_Skeleton
Objecto
remoto
Socket
Servidor
Se llama al registro
para localizar el
objeto miObjeto
Objecto
cliente
Puerto X
miObjeto_Stub
1
Se exporta el objeto; a
partir de entonces
escuchar peticiones
por un puerto X
4
Anfitrin cliente
El skeleton
enva la
llamada al
obj. remoto
Se
devuelve un
stub
Socket
Cliente
El stub enva la llamada
al skeleton
Figura 103. Procesos que subyacen bajo una llamada remota con RMI
- 208/313 -
http://www.javahispano.org
java.rmi
java.rmi.registry
java.rmi.server
java.rmi.activation
java.rmi.dgc
Como los dos ltimos paquetes trabajan con aspectos avanzados de la RMI, no
desglosar las clases e interfaces que contienen. No obstante, incluyo ms adelante
una breve descripcin de estos paquetes.
java.rmi
El paquete java.rmi proporciona la interfaz Remote y las clases
MarshalledObject, Naming y RMISecurityManager, as como unas cuantas
excepciones.
La interfaz Remote carece de mtodos. Toda clase remota debe implementarla;
en caso contrario, Java no la considera como tal.
La clase MarshalledObject apareci por primera vez en el JDK 1.2. Una
instancia de ella contiene el flujo de bytes serializado de un objeto. Sus mtodos son
utilizados internamente por la RMI.
La clase Naming incluye mtodos para obtener y almacenar referencias a objetos
remotos mediante el URL de la RMI. Los mtodos ms usados son
public static void bind(String nombre,
Remote objeto) throws AlreadyBoundException,
MalformedURLException, RemoteExceptionBinds
public static void rebind(String nombre, Remote
objeto) throws RemoteException, MalformedURLException
public static Remote lookup(String nombre) throws
NotBoundException, MalformedURLException,
RemoteException.
El mtodo bind() asocia un nombre a un objeto remoto mediante un URL de la
RMI (lo registra); as, ese nombre podr usarse para localizar el objeto remoto. Todos
los argumentos nombre de los mtodos de Naming deben ser Strings con la forma
de los URL de la RMI.
- 209/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Protocolo
Por ejemplo:
rmi://www.uv.es:9000/ListaNotas
En el caso de que el URL incluya un protocolo que no sea rmi, se obtendr una
excepcin java.net.MalformedURLException. El anfitrin o host y el puerto son
opcionales. Si no se incluye el anfitrin, se toma el anfitrin local; si no se especifica el
puerto, se toma el puerto TCP 1099, que est asignado por defecto al rmiregistry
de la RMI. Una llamada tpica a bind() tiene esta forma:
MiClase instancia = new MiClase(...);
Naming.bind(rmi://anfitrion:puerto/directorio, instancia);
Dicho cdigo registra una instancia de Miclase con el nombre instancia en un
URL.
Para el ejemplo de CalcMat del subapartado 4.1, el registro, que se hace en el
servidor, podra tomar esta forma:
CalcMatImp calculo = new CalcMatImp();
Naming.bind(rmi://www.uv.es:9000/CentroCalculo, calculo);
El mtodo rebind() funciona como bind(), pero permite volver a asociar un
nombre a un objeto remoto, reemplazando al que ya tena. Si se intenta registrar con
bind()
un
objeto
ya
registrado,
se
lanzar
una
excepcin
java.rmi.AlreadyBoundException.
El mtodo lookup() devuelve una referencia al objeto remoto especificado en el
URL introducido en su argumento nombre. Con esa referencia, se puede llamar a sus
mtodos remotos. Gracias a este mtodo, la MVJ local averigua qu MVJ proporciona
o sirve al objeto remoto. Una vez conseguida la referencia al objeto remoto (un
adaptador o stub), la MVJ local usar el anfitrin y el puerto incluidos en la referencia
para abrir con sockets una conexin con la MVJ remota cada vez que llame a algn
mtodo remoto. Una llamada tpica a lookup() tiene la forma
Naming.lookup(rmi://anfitrion:puerto/nombreobjetoremoto);
Para buscar la instancia calculo de CalcMat registrada pocas lneas ms
arriba, debera escribirse en el cliente
Naming.lookup(rmi://www.uv.es:9000/CentroCalculo/calculo);
- 210/313 -
http://www.javahispano.org
java.rmi.registry
El paquete java.rmi.registry proporciona las interfaces Registry y
RegistryHandler, as como la clase LocateRegistry.
La interfaz Registry define los mtodos bind(), lookup(), rebind(),
unbind() y list() de la clase Naming, y define la constante public static
final int REGISTRY_PORT, correspondiente al puerto TCP que se usa para
registrar objetos.
La interfaz RegistryHandler figura en la documentacin de Sun como
deprecated (censurada o desaprobada) desde la versin 1.2 del JDK y no debe
utilizarse.
La clase LocateRegistry se usa para recuperar objetos Registry de un par
anfitrin-puerto o para crear objetos Registry a partir de un nmero de puerto o de
puertos y de factoras de sockets RMI. Los mtodos getRegistry() se encargan de
recuperar los objetos Registry; y los mtodos createRegistry() de crearlos. Las
factoras de sockets RMI, introducidas en JDK 1.3, permiten usar sockets que codifican
o comprimen datos, y sockets que no sean TCP.
java.rmi.server
Este paquete proporciona clases (ObjID, RemoteObject, RemoteServer,
RemoteStub, RMIClassLoader, RMIClassLoaderSpi, RMISocketFactory, UID
y UnicastRemoteObject) e interfaces (RemoteRef, RMIClientSocketFactory,
RMIFailureHandler, RMIServerSocketFactory, ServerRef y Unreferenced),
as como un conjunto de excepciones, para la parte de servidor de las aplicaciones con
RMI. Slo he mencionado aquellas clases e interfaces que no figuran como deprecated
en el JDK 1.4. Mientras escribo estas lneas, el JDK 1.5 est en versin beta (Sun ha
cambiado el nombre de JDK 1.5 por JDK 5.0).
- 211/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 212/313 -
http://www.javahispano.org
java.rmi.activation
Aadido en el JDK 1.2, este paquete permite activar remotamente objetos,
desactivarlos cuando no se est trabajando con ellos y reactivarlos cuando se precise,
conservando el estado que tenan antes de ser desactivados.
Este paquete resulta muy til cuando se desarrollan aplicaciones distribuidas con
miles de objetos distribuidos por muchas mquinas, pues permite aprovechar al
mximo los recursos de las mquinas, que no tienen que cargar con objetos que
temporalmente no usan.
java.rmi.dgc
Proporciona las clases e interfaces que utiliza el recolector de basura (distribuida)
de la RMI. Rara vez el programador tendr que bregar con este paquete, salvo que
decida sustituir el sistema de recoleccin de basura de la RMI por otro propio, prctica
esta desaconsejable por completo.
- 213/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Object
RemoteObject
implements
extends
RemoteServer
Remote
Miguel ngel Abin Julio 2004
RemoteStub
UnicastRemoteObject
Interfaz remota del cliente
Implementacin de
la interfaz remota
- 214/313 -
http://www.javahispano.org
5.4. Ejemplo completo del desarrollo e implementacin de una aplicacin con RMI
En este subapartado se explicarn los pasos que hay que seguir para construir
una aplicacin distribuida con la RMI de Java. Para ello, se desarrollar una aplicacin
de clculo vectorial que toma un vector tridimensional y devuelve su mdulo y el vector
unitario asociado.
Todo el ejemplo se va a implementar considerando que el cliente y el servidor se
ejecutan en el mismo anfitrin; es decir, que todos los ficheros .class de la aplicacin
se encuentran en una misma mquina. En el siguiente subapartado dar las directrices
para distribuir los .class cuando clientes y servidores residen en anfitriones distintos.
La secuencia de pasos para desarrollar una aplicacin con RMI se representa en
la siguiente figura.
a)
Se implementa la
interfaz remota
b)
c)
javac ...
d)
rmic ...
Anfitrin servidor
Se generan archivos
.class para la
interfaz remota y
para la clase que
implementa la
interfaz remota
g)
Se genera el .class
de la clase cliente
e)
Anfitrin cliente
h)
i)
javac ...
f)
Se genera el fichero .class del
adaptador (stub)
- 215/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Paso a) En primer lugar, se escribe la interfaz remota del servidor. Toda interfaz
remota debe declararse como public y debe extender la interfaz java.rmi.Remote,
incluida en el paquete java.rmi. Dicha interfaz debe definir los mtodos a los que el
servidor permitir el acceso remoto.
Cada mtodo de la interfaz remota tiene que capturar la excepcin
java.rmi.RemoteException o declararla con throws.
- 216/313 -
http://www.javahispano.org
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
/** Esta clase se usar para generar (con rmic) los
* ficheros stub y skeleton.
*/
public class CalculoVectorialImp extends UnicastRemoteObject implements
CalculoVectorial {
// Esta clase implementa a la interfaz CalculoVectorial.
/** El constructor debe lanzar la excepcin RemoteException.
*/
public CalculoVectorialImp() throws RemoteException {
super();
try {
// Se registra la clase con el servidor de registro de RMI en el anfitrin local
// con el nombre "CalculosVector". Al no indicarse puerto, se usar el
// puerto TCP 1099.
Naming.rebind("rmi://localhost/CalculosVector", this);
}
catch (AccessException e1) {
System.out.println("Se rechaz el acceso. Su sistema no tiene los permisos " +
" necesarios para realizar la operacin remota." );
System.exit(-1);
}
catch (java.net.MalformedURLException e2) {
System.out.println("La URL para el registro no es vlida.");
System.exit(-1);
}
}
/** calcularModulo es un mtodo no remoto y privado que devuelve el mdulo de un vector 3D.
*
* @param x,y,z son los tres coordenadas (en formato double) del vector.
* @return devuelve el mdulo como un double.
*/
private double calcularModulo (double x, double y, double z) {
return (Math.sqrt(x*x + y*y + z*z));
}
/** calcularUX es un mtodo no remoto y privado que calcula la coordenada X del vector
* unitario asociado al que se le pasa como argumento.
* @param x,y,z son las tres coordenadas (en formato double) del vector.
* @return devuelve la coordenada X como un double.
*/
private double calcularUX (double x, double y, double z) {
return (x/calcularModulo(x, y, z));
}
/** calcularUY es un mtodo no remoto y privado que calcula la coordenada Y del vector
Miguel ngel Abin, Julio 2004
- 217/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 218/313 -
http://www.javahispano.org
- 219/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 220/313 -
http://www.javahispano.org
- 221/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 222/313 -
http://www.javahispano.org
throw e;
} catch (java.rmi.RemoteException e) {
throw e;
} catch (java.lang.Exception e) {
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
}
}
- 223/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 224/313 -
http://www.javahispano.org
- 225/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 226/313 -
http://www.javahispano.org
- 227/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 228/313 -
http://www.javahispano.org
e4.printStackTrace();
}
}
}
- 229/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Desde luego, si uno se toma todo este trabajo para devolver el mdulo de un
vector, a su jefe le acudir enseguida a la cabeza la temida frase Despido procedente
y alguna que otra maldicin dirigida a quien le entrevist para el puesto (aunque
seguramente fue l); pero hay que tener en cuenta que es un mero ejemplo.
Un servidor RMI que lea datos de una base de datos (mediante JDBC) y que los
ofrezca a los clientes para que los consulten, los modifiquen y, luego, le transmitan las
modificaciones es un ejemplo tpico de aplicacin RMI empresarial. RMI se integra muy
bien con la versin empresarial de Java (J2EE) y resulta muy sencillo integrarla con los
Enterprise Java Beans. JINI, una tecnologa Java destinada a la gestin de perifricos
en red, usa RMI.
5.5. Distribucin de las aplicaciones RMI: carga dinmica de clases con RMI
En el ejemplo del apartado anterior he considerado que todas las clases se hallan
en una misma mquina. En una aplicacin distribuida, esa situacin slo suele darse
durante el proceso de depuracin. En teora, es posible colocar en cada mquina las
clases de la aplicacin, de manera que cada anfitrin pueda acceder a ellas
configurando adecuadamente su CLASSPATH local. Aun cuando se puede trabajar de
dicha manera, en muchos casos no constituye una solucin viable. Imaginemos que
tenemos una aplicacin distribuida cuya implementacin cambia a menudo, pero cuya
interfaz no. Cada vez que se modificara la implementacin, habra que distribuir los
nuevos archivos entre todos los clientes. Dependiendo del nmero de stos, de sus
ubicaciones y de la frecuencia de las actualizaciones, la tarea de distribucin podra
volverse sumamente compleja y pesada.
La RMI de Java, al permitir la carga dinmica de clases, simplifica el proceso de
distribucin y hace posible que los clientes RMI puedan acceder a nuevos versiones de
los servicios RMI sin necesidad de distribuir a los clientes los archivos .class del
cdigo cada vez que se se modifica el cdigo fuente. CORBA est mucho ms limitado
que Java en cuanto a la distribucin de las aplicaciones y la carga dinmica de clases.
En una aplicacin con RMI, lo habitual es distribuir los ficheros .class asociados
a las clases e interfaces de la aplicacin entre varios anfitriones, de modo que los
clientes y servidores puedan acceder a ellos.
En el cliente, el cargador de clases debe poder acceder a los archivos.class de
los siguientes elementos:
La interfaz remota.
La interfaz remota.
- 230/313 -
http://www.javahispano.org
Anfitrin
delServer
servidor
Object
host
Directorio
servidor
object
serverdel
directory
object client
Directorio
deldirectory
cliente
SomeInterface.class
Interfaz.class
Servidor.class
SomeServer.class
SomeInterface.class
Interfaz.class
Implem_Stub.class
SomeImpl.class
SomeClient.class
Cliente.class
Implemen_Skel.class
SomeImpl_Skel.class
SomeImpl_Stub.class
Implem_Stub.class
- 231/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 232/313 -
http://www.javahispano.org
- 233/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 234/313 -
http://www.javahispano.org
e.getMessage());
e.printStackTrace();
}
}
}
- 235/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
*
on <b>port</b>.
*/
protected ClassServer(int port) throws IOException
{
this.port = port;
server = new ServerSocket(port);
newListener();
}
/**
* Returns an array of bytes containing the bytecodes for
* the class represented by the argument <b>path</b>.
* The <b>path</b> is a dot separated class name with
* the ".class" extension removed.
*
* @return the bytecodes for the class
* @exception ClassNotFoundException if the class corresponding
* to <b>path</b> could not be loaded.
* @exception IOException if error occurs reading the class
*/
public abstract byte[] getBytes(String path)
throws IOException, ClassNotFoundException;
/**
* The "listen" thread that accepts a connection to the
* server, parses the header to obtain the class file name
* and sends back the bytecodes for the class (or error
* if the class is not found or the response was malformed).
*/
public void run()
{
Socket socket;
// accept a connection
try {
socket = server.accept();
} catch (IOException e) {
System.out.println("Class Server died: " + e.getMessage());
e.printStackTrace();
return;
}
// create a new thread to accept the next connection
newListener();
try {
DataOutputStream out =
new DataOutputStream(socket.getOutputStream());
try {
// get path to class file from header
DataInputStream in =
new DataInputStream(socket.getInputStream());
String path = getPath(in);
System.out.println(path);
// retrieve bytecodes
byte[] bytecodes = getBytes(path);
Miguel ngel Abin, Julio 2004
- 236/313 -
http://www.javahispano.org
- 237/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Para utilizar con RMI el elemental servidor web de Sun, hay que compilar las
clases y ejecutar ClassFileServer especificando el puerto elegido para escuchar
peticiones HTTP y el camino donde se almacenan los archivos .class que se quieran
poner a disposicin de clientes y servidores (stubs). Por ejemplo:
java server.ClassFileServer 8080 /home/ejemplosRMI/clases
har que el servidor HTTP de Sun escuche por el puerto 8080 y que sirva los ficheros
sitos en la ruta de acceso (relativa) /home/ejemplosRMI/clases.
Cargar dinmicamente clases provenientes de sistemas remotos requiere algunas
consideraciones en cuanto a seguridad (despus de todo, se ejecuta cdigo que
proviene de otra mquina). Para que RMI permita ejecutar un .class descargado de
una mquina remota, Java exige que la MVJ de destino tenga instalado un gestor de
seguridad. El gestor de seguridad por defecto puede instalarse as:
System.setSecurityManager(new RMISecurityManager());
RMISecurityManager es un gestor muy restrictivo, y en general conviene definir
una poltica de seguridad personalizada. La poltica se almacena en un archivo
(seguridad.policy, por ejemplo) y se instala as:
java -Djava.rmi.server.codebase=http://www.miservidorweb.com/
-Djava.security.policy=seguridad.policy Nomina
As, cualquier descarga de bytecodes que necesite Nomina se descargar de
http://www.miservidorweb.com/ (si esos bytecodes no aparecen en el
CLASSPATH local) y se tendr en cuenta la poltica de seguridad definida en el archivo
seguridad.policy.
Miguel ngel Abin, Julio 2004
- 238/313 -
http://www.javahispano.org
Todas las clases de Java pueden establecer una conexin de red con el
anfitrin anfitrion.dominio.com por el puerto TCP 1025.
- 239/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 240/313 -
http://www.javahispano.org
- 241/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 242/313 -
http://www.javahispano.org
- 243/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 244/313 -
http://www.javahispano.org
- 245/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
EmpleadoImp.class
Anfitrin cliente
EmpleadoImp_Skel.class
Empleado.class
RegistroEmpleados.class
ClienteRegistroEmpleados.class
Seguridad.policy
RegistroEmpleadosImp_Skel.class
ServidorRegistroEmpleados.class
RegistroEmpleadosImp.class
Seguridad.policy
Espacio en blanco
Llamada HTTP
Registro RMI
(rmiregistry)
RegistroEmpleadosImp_Stub.class
EmpleadoImp_Stub.class
Llamada HTTP
Miguel ngel Abin, Mayo 2004
Espacio en blanco
Miguel ngel Abin, Julio 2004
- 246/313 -
http://www.javahispano.org
Anfitrin del servidor RMI: estacin de trabajo SUN BLADE 150 con
Solaris 8.0.
Anfitrin del servidor web (con los archivos stub): PC con Red Hat 9.0 y
con el servidor Apache.
F:\JbuilderX\jdk1.4\bin>java -Djava.rmi.server.codebase=
http://www.miservidorweb.com/misclases/ -Djava.security.policy= seguridad.policy
ServidorRegistroEmpleados
obtuve esta salida (en vez de http://www.miservidorweb.com/misclases/
escrib el URL asociado al directorio del PC con Red Hat donde coloqu los .class
stub y para el cual configur Apache):
Si el lector quiere probar el ejemplo en una sola mquina (que actuar, por tanto,
como servidor, cliente y servidor web), deber cambiar en el cdigo
"rmi://www.miservidorRMI.com:9000/Plantilla" por "rmi://localhost:9000/Plantilla".
- 247/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
RMI slo usa Java. Esta limitacin era un problema al principio; pero,
con el JDK 1.3, Sun incluy la posibilidad de trabajar con el protocolo
IIOP de CORBA, lo cual permite una cierta interoperabilidad de las
aplicaciones RMI con las aplicaciones CORBA escritas en otros
lenguajes (COBOL, C/C++, Smalltalk, etc.).
Falta de metainformacin. Al igual que los sockets, RMI no tiene un
sistema de metainformacin que almacene los servicios disponibles y
sus API (esto es, los nombres de los mtodos, los argumentos de
cada uno, los valores de retorno, etc.).
Paso de objetos por valor. Este mecanismo penaliza la eficacia y
escalabilidad de las aplicaciones RMI. Cuanto ms aumenta el tamao
de los objetos que se envan como argumentos, ms datos hay que
codificar en JRMP y enviar. Adems, no debe olvidarse que, cuando
se serializa un objeto, se serializan tambin todos los objetos a los
cuales tiene referencias. Si el objeto corresponde a una coleccin de
Java, puede darse el caso de que haya que serializar cientos o miles
de objetos (y luego habr que deserializarlos en el servidor).
Miguel ngel Abin, Julio 2004
- 248/313 -
http://www.javahispano.org
- 249/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 250/313 -
http://www.javahispano.org
Los objetos CORBA se distribuyen como componentes binarios que pueden recibir
llamadas remotas a sus mtodos. A los clientes de un objeto CORBA les es indiferente
dnde se encuentra, en qu plataforma se ejecuta o cmo se implementa. CORBA es
una tecnologa de integracin; no se encuentra atada a ningn lenguaje o plataforma.
CORBA usa el IDL (Interface Definition Language: lenguaje de definicin de
interfaces) del OMG para definir las interfaces a las que pueden acceder los clientes. A
veces, uno encuentra escrito IDL de CORBA en lugar de IDL del OMG. A mi juicio,
la primera denominacin frisa el desacierto: ni el IDL del OMG se usa slo con CORBA
ni es un lenguaje atado a CORBA. Por brevedad, usar casi siempre IDL para
referirme al IDL del OMG; pero el lector debe saber que existen otros IDL (por ejemplo,
Microsoft tiene el suyo propio para su tecnologa DCOM). El IDL del OMG es un mero
lenguaje declarativo, basado en C++, no un lenguaje de implementacin. Los mtodos
Miguel ngel Abin, Julio 2004
- 251/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
especificados en una interfaz escrita con IDL pueden implementarse ms tarde con
otros lenguajes.
El OMG define traducciones o conversiones oficiales para COBOL, C, Ada 95,
Smalltalk, C++, Java, Lisp, Python, IDLScript y PL/I (haba intencin de hacer lo mismo
para C#, pero la traduccin se ha desestimado por motivos no bien aclarados). Por lo
que he podido averiguar, existen conversiones IDL no oficiales para otros diecisis
lenguajes, entre los que destacan Delphi, Pascal, Perl y Visual Basic. Una traduccin
de IDL a un lenguaje define cmo se transforman las estructuras sintcticas del IDL en
las del lenguaje de destino.
Utilizar un lenguaje declarativo neutro aade complejidad, pero reporta una
ventaja en absoluto desdeable: clientes y servidores pueden comunicarse con
independencia de los lenguajes en que estn escritos.
- 252/313 -
http://www.javahispano.org
distintos
tipos
(distintos
- 253/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
TypeCode y para saber si dos Typecodes son iguales o equivalentes. Este tipo resulta
til para CORBA, que lo usa para pasar entre mquinas datos que se describen a s
mismos. En general, los programadores nunca tienen que trabajar directamente con
este tipo.
Entity
Object reference
Basic Value
Constructed Values
Union
Array
Struct
Sequence
Any
Boolean
Octet
Short
Long
LongLong
UShort
ULong
ULongLong
Float
Double
LongDouble
Fixed
Char
WChar
String
WString
Enum
He optado por mantener en ingls los nombres de todas las entidades que aparecen en la documentacin del OMG
Miguel ngel Abin Julio 2004
- 254/313 -
http://www.javahispano.org
- 255/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 256/313 -
http://www.javahispano.org
- 257/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 258/313 -
http://www.javahispano.org
Compilador IDL
Depsito de
implementaciones
Sirviente
Cliente
Comunicacin
lgica
Esqueleto
Adaptador
DII
Interfaz
ORB
Interfaz
ORB
DSI
Adaptador de objetos
IIOP
TCP/IP
Miguel ngel Abin Julio 2004
Figura 114. Lo que nos mostraran los rayos-X si CORBA no fuera virtual
El IDL (Interface Declaration Language: lenguaje de declaracin de interfaces), ya
mencionado, especifica las interfaces que ofrecern los servidores CORBA a sus
clientes. En consecuencia, define los atributos y mtodos de los objetos distribuidos en
una aplicacin CORBA. Para cada tipo de objeto distribuido de CORBA, se define una
interfaz con el IDL (estas interfaces equivaldran a las interfaces que extienden
java.rmi.Remote en RMI). En las especificaciones de CORBA se definen
traducciones de las interfaces IDL a construcciones de lenguajes como C, C++, Java,
COBOL, etc. Como puede imaginarse el lector, las traducciones a uno u otro lenguaje
poco se parecern, pues los lenguajes que se usan con CORBA son francamente
heterogneos. Por ejemplo, COBOL o C no manejan objetos, mientras que Java o C++
s.
Si miramos con lupa bajo el IDL, evitando tocar el polvo, notaremos que es
interesante no tanto por la sintaxis como por el mecanismo de abstraccin que
proporciona para separar las interfaces de las implementaciones. El IDL acta como un
contrato entre clientes y servidores. Viene a decir al servidor: Debe respetar esta
interfaz. Asimismo, viene a decir a los clientes: Si quiere obtener respuesta, debe
Miguel ngel Abin, Julio 2004
- 259/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
attribute
context
FALSE
interface
octet
readonly
struct
unsigned
wstring
boolean
default
fixed
long
oneway
sequence
switch
union
case
char
double enum
float
in
module
out
short
TRUE
void
- 260/313 -
http://www.javahispano.org
exception Excepcion{};
interface Salario {
double getSalario() raises(Excepcion);
// salario es el argumento de setSalario
void setSalario (in double salario);
};
};
- 261/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
GENERACIN DE ADAPTADORES Y
ESQUELETOS
El compilador IDL
genera los adaptadores y
los esqueletos en un
cierto lenguaje de
programacin (Java,
C++, etc.)
Definiciones
IDL
Compilador
IDL
Adaptador
Esqueleto
- 262/313 -
http://www.javahispano.org
- 263/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
COBOL
C++
Java
COBOL
C++
IDL
IDL
IDL
IDL
IDL
IDL
IDL
IDL
Cliente
Servidor
ORB
Miguel ngel Abin Julio 2004
- 264/313 -
http://www.javahispano.org
Compilador IDL
Depsito
Implementaciones
operacion(args)
Cliente
Dynamic
Invocation
Interface
Ref.
Obj.
IDL
Stubs
Objeto CORBA
resultado(args)
ORB
Interface
(Sirviente)
IDL
Dynamic
Static
Skeleton
Skeletons Interface
Adapt.
objetos
- 265/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 266/313 -
http://www.javahispano.org
- 267/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Peticin
del cliente
ORB
POA
Sirvientes
POA
- 268/313 -
http://www.javahispano.org
Informacin del
extremo
Figura 123. Ejemplo de una IOR. Una referencia interoperable a un objeto puede
enviarse por correo electrnico o almacenarse en una base de datos o en un
fichero de texto (vase el problema del Ocano Pacfico en 6.6)
Miguel ngel Abin, Julio 2004
- 269/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Los tres componentes conceptuales de una IOR (mostrados en la figura 103a) son
- 270/313 -
http://www.javahispano.org
Las IOR persistentes permiten identificar objetos aunque el proceso servidor que
las gener se haya detenido una o ms veces. Estas referencias sobreviven a los
apagados del servidor. Una IOR persistente apunta a un objeto CORBA que siempre
existe conceptualmente. Uso conceptualmente porque el objeto puede estar guardado
en una base de datos o en un archivo de texto mientras no se necesita.
Como vimos, existe una clara separacin entre los tiempos de vida de objetos y
sirvientes. Cuando un proceso servidor se para, se destruyen todos los sirvientes que
haba creado; pero no sus objetos, que son virtuales (siempre que sean persistentes,
claro est). Una IOR persistente deja de funcionar solamente cuando se destruye el
objeto (virtual) que la tiene asociada, no cuando se destruye la implementacin del
objeto.
Cada vez que se detiene y se vuelve a arrancar un proceso servidor, puede
ejecutarse en otro anfitrin. Incluso en el caso de que el nuevo proceso se ejecute en la
misma mquina, lo habitual es que use otro puerto. En consecuencia, en una IOR
persistente no basta con grabar un nombre del anfitrin y un nmero de puerto, tal
como se hace con las IOR transitorias. Si se desea un mecanismo de persistencia,
debe existir algn modo de que los clientes sepan, tras la parada de un servidor, a qu
puerto y a qu mquina dirigir sus peticiones.
La solucin adoptada es que, cuando se crea una IOR persistente, el servidor
CORBA guarda en ella el nombre del tipo del objeto (o identificador del depsito), el
nombre del adaptador del objeto, el nombre del objeto y la direccin del depsito de
implementaciones (nombre de la mquina donde se ejecuta y nmero de puerto por el
que escucha).
Un depsito de implementaciones (Implementation Repository) es una especie
de contenedor donde se guardan las implementaciones de todos los objetos
registrados en una aplicacin CORBA. Gracias a l, un ORB puede conocer el nombre
de los servidores en ejecucin, los nombres de las mquinas que los albergan y el
nmero de puerto que usa cada uno.
Durante la creacin de una IOR persistente, el servidor CORBA establece
contacto con el depsito de implementaciones y le enva el nombre del objeto (Obj13,
p. ej), el nombre del adaptador del objeto (Adapt1, p. ej.), as como el nombre de la
mquina donde se ejecuta (aidima2.aidima.es, p. ej.) y el puerto por el que
escucha peticiones (1025, p. ej.). Por as decirlo, todo servidor hace una presentacin
en toda regla ante un depsito de implementaciones. El servidor sabe dnde se halla el
depsito de implementaciones porque la direccin consta en la configuracin de la
mquina local.
Cuando un cliente llama a algn mtodo mediante una IOR persistente, la llamada
va al depsito de implementaciones, no al servidor CORBA que ha generado la IOR. El
depsito extrae de la IOR la direccin del servidor y la busca entre su informacin. Si la
encuentra, enva al cliente un mensaje con esta informacin: el nombre de la mquina
actual donde se ejecuta el servidor y el nmero de puerto. El cliente redirigir su
peticin a la mquina y al puerto indicados por el depsito. Puede suceder que el
depsito de implementaciones, al intentar comunicarse con el servidor, descubra que
ste no est ya en ejecucin. En dicho caso, recurrir a la activacin bajo demanda
(siempre que el servidor se haya configurado as): enviar al servidor un mensaje de
ejecucin (fork/exec) que lo pondr en marcha.
Volviendo a las comparaciones antropomorfas, cuando un servidor CORBA que
genera objetos persistentes se inicia es como si dijera al depsito de
implementaciones: Buenos das. Acabo de ser creado. Mi nombre es Servidor1; vivo
en una mquina apacible y acogedora, que se llama www.aidima.es y pueden
Miguel ngel Abin, Julio 2004
- 271/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
molestarme, perdn, consultarme, por medio del puerto 9000. Cuando el depsito
activa a un servidor bajo demanda, ste enva un mensaje a aqul que vendra a decir
Buenas tardes. Su mensaje me ha creado. Vivo en la mquina www.aidima.es y
pueden interrumpirme, perdn, consultarme, por medio del puerto 9000. A partir de
ahora pueden enviarme peticiones sin necesidad de volver a ejecutarme.
La diferencia entre el uso de una IOR transitoria y una persistente se muestra en
las figuras 124 y 125.
Cliente
IOR de un objeto
IDL:miObjeto:1.0 www.aidima.es:9000
Adapt1, Obj13
www.aidima.es:9000
Adapt1
Obj13
Obj14
Resultado de miOperacion()
Servidor
Miguel ngel Abin Julio 2004
- 272/313 -
Sirvientes
Obj12
http://www.javahispano.org
Cliente
IOR de un objeto
IDL:miObjeto:1.0
aidima2.aidima.es:1025
Adapt1, Obj13
Resultado de miOperacion()
miOperacion() [Adapt1, Obj13]
www.aidima.es:9000
www.aidima.es:9000
1
miOperacion() [Adapt1, Obj13]
Adapt1
aidima2.aidima.es:1025
Obj13
Obj14
Adapt1
\bin\server\startAdapt1
www.aidima.es:9000
Sirvientes
Obj12
Servidor
Depsito de implementaciones
Miguel ngel Abin Julio 2004
- 273/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 274/313 -
http://www.javahispano.org
- 275/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Contexto de nombrado1
Contexto de nombrado1
Objeto1
Contexto de nombrado2
Contexto de nombrado2
Objeto2
- 276/313 -
http://www.javahispano.org
NameService
ORB
Figura 127. Primer paso para obtener una referencia a un objeto CORBA
Persona
luis=IOR:X
ORB
Figura 128. Segundo paso para obtener una referencia a un objeto CORBA
- 277/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Persona
Objeto cliente
luis=IOR:X
ORB
Figura 129. Tercer paso para obtener una referencia a un objeto CORBA
NameService
Persona
Objeto cliente
luis=IOR:X
ORB
Figura 130. Cuarto paso para obtener una referencia a un objeto CORBA
Miguel ngel Abin, Julio 2004
- 278/313 -
http://www.javahispano.org
- 279/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 280/313 -
http://www.javahispano.org
Objeto sirviente
ORB
Miguel ngel Abin Julio 2004
- 281/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 282/313 -
http://www.javahispano.org
- 283/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Como ya he adelantado, IIOP permite que las aplicaciones RMI pueden acceder a
objetos CORBA, y viceversa. Se vuelve falsa, pues, la afirmacin de que las
aplicaciones RMI slo sirven cuando todas las partes estn escritas en Java. Si se
generan adaptadores y esqueletos (o slo adaptadores) que usen IIOP, cualquier
objeto CORBA podr interaccionar con ellos. Podemos tener un servidor RMI que
atienda peticiones de clientes escritos en COBOL, Smalltalk o C++, y viceversa. La
nica condicin que debemos exigir es que las interfaces de todos los
componentes de la aplicacin se hayan definido como interfaces remotas de
Java. Dicha exigencia resulta imprescindible, porque por ejemplo un servidor escrito
en C++ a partir de una interfaz IDL podra ser incapaz de entender lo que quiere decirle
un cliente Java escrito a partir de una interfaz remota Java. Por qu? Pues porque el
IDL es ms rico en contenido que Java: el cliente Java sera incapaz de entender una
respuesta del servidor C++ en la que se usaran argumentos inout (C++ s permite
estos argumentos).
Esta condicin slo constituye un ligero problema cuando se trabaja con
aplicaciones ya escritas y que no pueden modificarse: entonces hay que usar la
tecnologa IDL de Java. Supongamos que tenemos un servidor CORBA escrito en C++
y que interesa construir un cliente Java que enve peticiones al servidor. Para
conseguirlo, deberemos obtener el archivo IDL de la interfaz del servidor y compilarlo
mediante idlj (el compilador IDL de Java). La compilacin generar los archivos que
nos servirn como base para la aplicacin (adaptadores, esqueletos, etc.)
Si trabajamos con aplicaciones nuevas, an no implementadas ni distribuidas,
podemos usar RMI (con IIOP) para trabajar con objetos CORBA. En el ejemplo
anterior, lo primero que haramos sera escribir una interfaz remota RMI para el
servidor. Despus, con la aplicacin rmic, generaramos un archivo IDL para la
interfaz RMI (usando rmic -idl archivointerfazRMI). En la parte del servidor,
un compilador IDL para C++ se encargara de generar los adaptadores y esqueletos a
partir del archivo IDL generado antes. En la parte del cliente Java, aqullos se
generaran mediante rmic iiop archivointerfazRMI. Una vez implementado el
cdigo necesario en ambas partes, el servidor C++ ser un servidor CORBA puro y el
cliente Java ser un cliente RMI puro. Ambos podrn interoperar sin ningn problema.
La regla para usar la tecnologa IDL de Java o RMI es muy sencilla: para
aplicaciones CORBA ya escritas y en funcionamiento, conviene usar la primera; para
las aplicaciones CORBA an no materializadas, conviene usar RMI (con IIOP) para
todas las partes escritas en Java. Desde luego, si todos los elementos de una
aplicacin distribuida van a escribirse en Java, lo natural es usar RMI (recomendara
usar RMI con IIOP para este caso, pues nunca se sabe si algn da se necesitar
interoperabilidad con objetos CORBA).
Aunque por motivos bien distintos, CORBA y RMI tienen una desventaja comn:
su escasa eficacia para las transferencias masivas de datos. En el caso de CORBA,
por la complejidad de la arquitectura y por la conversin de los datos al formato CDR;
en el caso de RMI, por la serializacin de objetos: una llamada remota puede implicar
serializar y deserializar cientos o miles de objetos.
CORBA ha contado con el problema aadido de luchar al principio con un
enemigo muy poderoso: los cortafuegos. Como los servidores CORBA escuchan en
puertos aleatorios, suelen provocar conflictos con las polticas de seguridad de los
cortafuegos, que slo permiten que unos pocos puertos (como el de HTTP o FTP)
puedan ser accedidos desde el exterior. Este problema hizo que cundiera la
Miguel ngel Abin, Julio 2004
- 284/313 -
http://www.javahispano.org
desconfianza de las empresas hacia esta tecnologa. Ahora existen ORB que evitan los
conflictos introduciendo los mensajes IIOP en mensajes HTTP (HTTP tunneling o
pasarela HTTP); pero el problema es que no existan cuando las primeras
implementaciones de CORBA vieron la luz. RMI siempre ha permitido usar esta treta
para evitar problemas con los cortafuegos (este comportamiento por defecto puede
desactivarse con java.rmi.server.disableHttp=true).
- 285/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Nota: La versin del JDK usada para la capturas de pantallas es la 1.4.2, que
viene por defecto en el JBuilder X; pero tambin he comprobado que todo el
cdigo funcionaba en la versin 1.2 y en el JDK 1.5.0 Beta 1. Todo el cdigo
que usa CORBA se ha probado con los sistemas operativos Windows XP
Profesional (en un PC domstico), Red Hat 9.0 (en un PC domstico) y
Solaris 8.0 (en una estacin de trabajo SUN BLADE 150).
Para el ejemplo del servicio de eco, los pasos para construir la aplicacin y
ejecutarla se detallan a continuacin.
- 286/313 -
http://www.javahispano.org
- 287/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
La clase Eco no alberga mucho misterio. Es una interfaz Java normal y corriente:
package Mensajeria;
/**
* Mensajeria/Eco.java .
* Generated by the IDL-to-Java compiler (portable), version "3.1"
* from Mensajeria.idl
* lunes 26 de julio de 2004 23H52' CEST
*/
public interface Eco extends EcoOperations, org.omg.CORBA.Object,
org.omg.CORBA.portable.IDLEntity
{
} // interface Eco
La clase EcoHelper ya nos da pistas sobre lo que hace la compilacin IDL. Esta
clase sirve para crear flujos donde puedan ir mensajes IIOP, as como para introducir
datos en los flujos de salida o extraerlos de los flujos de entrado. El programador no
necesita usarla directamente, pero el IDL de Java s.
package Mensajeria;
/**
* Mensajeria/EcoHelper.java .
* Generated by the IDL-to-Java compiler (portable), version "3.1"
* from Mensajeria.idl
* lunes 26 de julio de 2004 23H52' CEST
*/
abstract public class EcoHelper
{
private static String _id = "IDL:Mensajeria/Eco:1.0";
public static void insert (org.omg.CORBA.Any a, Mensajeria.Eco that)
{
org.omg.CORBA.portable.OutputStream out = a.create_output_stream ();
a.type (type ());
Miguel ngel Abin, Julio 2004
- 288/313 -
http://www.javahispano.org
CORBA de entrada
- 289/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 290/313 -
Se devuelve el
resultado
http://www.javahispano.org
"IDL:Mensajeria/Eco:1.0"};
public String[] _ids ()
{
return (String[])__ids.clone ();
}
private void readObject (java.io.ObjectInputStream s) throws java.io.IOException
{
String str = s.readUTF ();
String[] args = null;
java.util.Properties props = null;
org.omg.CORBA.Object obj = org.omg.CORBA.ORB.init (args, props).string_to_object (str);
org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl)
obj)._get_delegate ();
_set_delegate (delegate);
}
- 291/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 292/313 -
http://www.javahispano.org
import java.util.*;
// IMPORTANTE: SLO FUNCIONAR CON J2SE 1.4 O SUPERIOR
// Clase que implementa la interfaz Eco.
class EcoImp extends EcoPOA {
private ORB orb;
public void setORB(ORB orb) {
this.orb = orb;
}
public String enviarTexto (String texto) {
return (">Ha enviado al servidor CORBA el texto: ** " + texto + " ** en la fecha " +
new Date().toString() + " (hora del servidor)");
}
}
public class ServidorEco {
public static void main (String args[]) {
try {
// Se crea y se inicia el ORB.
ORB orb = ORB.init (args, null);
// Se obtiene una referencia a la raz de POA y se lanza el gesto del POA
POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
rootpoa.the_POAManager().activate();
// Se crea un objeto EcoImp y se registra en el ORB.
EcoImp ei = new EcoImp();
ei.setORB(orb);
// Se obtiene una referencia CORBA de ei.
org.omg.CORBA.Object ref = rootpoa.servant_to_reference(ei);
Eco eco = EcoHelper.narrow(ref);
// Se registra el objeto en el servicio de nombres de CORBA y se le asigna un nombre.
// Al estar registrado, podr recibir peticiones de los clientes.
org.omg.CORBA.Object refObj =orb.resolve_initial_references("NameService");
NamingContextExt refnc = NamingContextExtHelper.narrow(refObj);
NameComponent camino[] = refnc.to_name("miEco");
refnc.rebind(camino, eco);
System.out.println("Servicio CORBA de eco activo.");
//El servidor CORBA queda a la espera de peticiones de los clientes.
orb.run();
}
catch (Exception e) {
System.out.println("Error fatal.");
e.printStackTrace ();
}
}
Miguel ngel Abin, Julio 2004
- 293/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 294/313 -
http://www.javahispano.org
- 295/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 296/313 -
http://www.javahispano.org
Como el cdigo del servidor usa la clase EcoHelper, habr que dejar
dentro del directorio Mensajeria del anfitrin servidor los archivos
EcoHelper.java y _EcoStub.java (la clase Helper hace uso de la
Stub).
- 297/313 -
Espacio
en blanco
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Mensajeria.idl
Esqueleto de
implementacin
Adaptador del
cliente
Idlj
fc
lie
a.
jeri
n sa
e
nt M
idl
idlj
Idlj
fs
erv
er M
en s
aje
ria.
i
dl
Lado del
cliente
EcoPOA.java
_EcoStub.java
EcoHelper.java
EcoHolder.java
EcoOperations.java
Eco.java
EcoOperations.java
Lado del
servidor
Eco.java
Si se usa idlj fall Mensajeria.idl se generan los archivos para el cliente y el servidor
- 298/313 -
http://www.javahispano.org
Interface
Eco
EcoHelper
extends
implements
{
private static String _id =
"IDL:Mensajeria/Eco:1.0";
_EcoStub
(Los mtodos definidos en la
interfaz Eco se implementan
en esta clase)
ClienteEco
public class ClienteEco {
usa
usa
Figura 136. Jerarqua de clases en la parte del cliente del ejemplo 19.
Si el lector no tiene ningn inconveniente en tener algn archivo de ms en el
cliente y en el servidor, los pasos anteriores se pueden simplificar en stos:
- 299/313 -
Espacio
en blanco
Espacio
en blanco
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
ORBInitialPort numpuerto.
Se arranca la aplicacin cliente en el anfitrin cliente mediante java
ClienteEco ORBInitialHost nombremaquina ORBInitialPort
numpuerto.
Espacio en blanco
Como segundo ejemplo del uso de CORBA con Java incluyo aqu el ejemplo de
una aplicacin de chat. Es una versin muy simplificada de una aplicacin que constru
hace unos aos para un club de deportes de nieve. En esta versin uso POA y el
modelo de delegacin (tambin conocido en la documentacin de Sun como Tie
Model: modelo de ligadura).
En el ejemplo anterior, hemos usado implcitamente el modelo de herencia, en el
cual se implementa la interfaz IDL mediante una clase sirviente (EcoImp) que tambin
extiende al esqueleto generado por el compilador IDL para Java. Este modelo tiene el
inconveniente de que, como Java no admite herencia mltiple, no se puede heredar del
esqueleto y de una clase sirviente. El modelo de delegacin permite heredar de una
clase sirviente, posibilidad inexistente en el otro modelo.
Al trabajar con el modelo de delegacin y con POA, hay que ejecutar dos veces al
compilador idlj (al usar fall, considero que quiero generar los archivos para el
servidor y el cliente):
idlj fall interfazIDL.idl
idlj fallTie interfazIDL.idl
La segunda ejecucin de idlj generar un archivo de tipo
interfazIDLPOATie.java.
Si todos los archivos estn en el fichero bin del JDK y todos los procesos se
ejecutan en la mquina local, los pasos para ejecutar la aplicacin de chat son
similares a los de la aplicacin de eco. La nica diferencia reside en que, en el paso b),
serviciochat.idl debe compilarse as:
idlj fall serviciochat.idl
idlj fallTie serviciochat.idl
- 300/313 -
http://www.javahispano.org
Eco
extends
EcoOperations
Eco
Interfaces
generados
implements
EcoPOA
Clases
Java
generadas
extends
implements
EcoPOATie
extends
delega
EcoTieImpl
Clases Java
escritas por
el usuario
EcoImpl
Modelo de herencia
Figura 137. Jerarqua parcial de clases en el lado del servidor del ejemplo 19,
con ambos modelos: el de herencia y el de delegacin.
He escogido este ejemplo de un chat porque me permite ilustrar con cdigo el
funcionamiento de las retrollamadas (callbacks). Una retrollamada es una llamada del
servidor a algn mtodo implementado en un cliente remoto (quizs ubicado en otro
anfitrin o en otro proceso dentro de la misma mquina). Como ya se dijo en 2.3,
cliente y servidor son papeles en una comunicacin, y pueden variar: por ejemplo,
un objeto que se comporta como cliente para otro puede ser servidor para un tercero.
Con frecuencia, las retrollamadas se usan cuando los clientes necesitan acceder
de forma peridica a alguna informacin de servidor o averiguar si se ha lanzado algn
evento en ste. Imaginemos, por ejemplo, una aplicacin informtica encargada de
controlar el aterrizaje y despegue de los aviones en un aeropuerto. Sera ineficaz que el
mdulo de control de la aplicacin tuviera que enviar seales a cada avin, cada cierto
perodo de tiempo, para saber dnde est cada uno. Si muchos aviones estuvieran
inactivos, se perdera mucho tiempo de CPU comprobando posiciones inalteradas. Es
mucho ms lgico que, cada cierto tiempo, los aviones informen al mdulo de control
de los cambios en su posicin (si ha lugar). As se evita que los aviones inactivos
consuman tiempo y recursos de la aplicacin.
En una retrollamada, el objeto que actuaba como servidor pasa a actuar como
cliente. Debe, por tanto, conseguir una referencia al objeto cliente y usarla para hacer
sus peticiones. En CORBA hay dos maneras para obtener las referencias de los
objetos: usar un servicio de nombres que el servidor pueda consultar o escribir el
cdigo del cliente de forma que se llame a un mtodo del servidor pasndole como
Miguel ngel Abin, Julio 2004
- 301/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
argumento el propio cliente. En la segunda opcin, no hay que olvidar que CORBA no
pasa realmente objetos: pasa referencias a los objetos. En el ejemplo de la aplicacin
de chat, la referencia al objeto cliente se pasa en este fragmento de cdigo:
Envio al servidor de una referencia a
s mismo
try {
servidor.registrarUsuario(tie._this());
}
catch (Exception e) {
System.out.println("Error al intentar registrar el usuario");
e.printStackTrace();
}
La llamada del servidor al cliente se produce en
public synchronized void enviarATodos(ClienteChat usuario,
String texto) {
// Nombre por defecto de los usuarios no registrados: "Annimo"
String nombreUsuario = "";
try {
nombreUsuario = usuario.getIdentificador();
if ( nombreUsuario.equals("") )
nombreUsuario = "Anonimo";
Iterator it = usuarios.iterator();
ClienteChat tmp =null;
while (it.hasNext()) {
tmp = (ClienteChat) it.next();
try {
// No enva el mensaje a aquel usuario que lo ha enviado.
if ( !(tmp.equals(usuario)) )
tmp.enviar(nombreUsuario + ": " + texto);
}
Retrollamada
catch (Exception e1) {
// Si hay problemas al enviar el texto a un
// usuario se le borra de la lista de
// usuarios activos.
it.remove();
} // fin del try-catch interno
}
}
catch (Exception e2) {
System.out.println("Error desconocido.");
e2.printStackTrace();
}
}
- 302/313 -
http://www.javahispano.org
- 303/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 304/313 -
http://www.javahispano.org
NamingContextExt nc =
NamingContextExtHelper.narrow(orb.resolve_initial_references("NameService"));
NameComponent [] nombreComponente = new NameComponent[1];
nombreComponente[0] = new NameComponent("miChat", "");
nc.bind(nombreComponente, ref);
poaMgr.activate();
System.out.println("Se ha arrancado el servidor CORBA de chat.");
orb.run();
}
catch (Exception e) {
System.out.println("Error al intentar arrancar el servidor.");
e.printStackTrace();
}
}
}
- 305/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
- 306/313 -
http://www.javahispano.org
- 307/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Adaptadores del
a
cliente
ens
tM
_ClienteChatStub.java
ClienteChatHelper.java
serviciochat.idl
Idlj
l
a.id
jeri
idlj
lien
fc
j
l
Id
_ServidorChatStub.java
Idlj
fs
er
Esqueletos de
implementacin
ver
ser
vic
ioc
hat
rTi
.id l
es
erv
icio
cha
t. i d
l
fs
erv
e
ClienteChatHolder.java
ServidorChat.java
ClienteChatOperations.java
ClienteChatOperations.java
Lado del
servidor
ServidorChatPOATie.java
ServidorChatHelper.java
ClienteChatPOATie.java
ServidorChatOperations.java
ServidorChatHolder.java ServidorChatOperations.java
- 308/313 -
http://www.javahispano.org
- 309/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Tanto en este ejemplo como en el anterior, los pasos para distribuir las
aplicaciones pueden simplificarse si se almacenan algunos archivos en un servidor
HTTP o FTP y se descargan dinmicamente, tal como vimos en 5.5. Esta descarga
dinmica slo es posible en Java: si trabajamos con CORBA mediante lenguajes como
Ada o C++, no hay manera de cargar dinmicamente los adaptadores o esqueletos.
La distribucin ms sencilla para los clientes consiste en que los clientes CORBA
sean applets. Si se opta por esta solucin, hay que colocar los archivos que necesiten
los clientes en un servidor web, dentro de una pgina HTML con una etiqueta APPLET.
Los pasos que se seguiran para ejecutar un applet CORBA seran stos:
El usuario utiliza un navegador web compatible con Java para acceder a
una pgina web con el applet CORBA.
Se arranca el applet.
El applet descarga mediante HTTP los bytecodes de todas las clases
que necesita (correspondientes al cliente CORBA) y los ejecuta.
Las peticiones de los usuarios son conducidas por el applet hasta el
servidor CORBA.
- 310/313 -
http://www.javahispano.org
Anfitrin
Navegador web
IIOP
IIOP
ORB
ORB
MVJ
Archivos
de clases
Java
Servidor
web
Puerto
IIOP
ORB
Applet
Figura 140. Representacin de una aplicacin CORBA con Java que usa clientes
de tipo applet
En la figura de la pgina siguiente se muestra el cdigo que hay que escribir en la
pgina HTML con el applet y en el cliente CORBA si se opta por distribuir una
aplicacin CORBA con clientes de tipo applet.
En una aplicacin de este tipo, lo habitual es usar applets firmados o configurar en
el lado del cliente un nivel de seguridad para cada anfitrin del cual se puedan
descargar archivos.
- 311/313 -
Java y las redes. Introduccin a las redes, a java.io, java.zip, java.net, java.nio, a RMI y a CORBA
Figura 141. Cdigo para usar applets en el lado del cliente como medio de
distribucin de las aplicaciones CORBA escritas en Java
Copyright (c) 2004, Miguel ngel Abin. Este documento puede ser distribuido slo
bajo los trminos y condiciones de la licencia de Documentacin de javaHispano v1.0
o posterior (la ltima versin se encuentra en http://www.javahispano.org/licencias/).
- 312/313 -
http://www.javahispano.org
- 313/313 -