Java Redes 1
Java Redes 1
(1 Parte de 3)
Introduccin a las redes, a [Link], [Link], [Link],
[Link], a RMI y a CORBA
Miguel ngel Abin
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 2/313 -
JAVA Y LAS REDES
(1 Parte de 3)
Resumen: En este tutorial, dividido en tres partes, se presenta un panorama general de las
comunicaciones en red mediante Java y de la E/S de Java. Para ello se explican las redes,
los paquetes [Link], [Link], [Link] y [Link], as como RMI y CORBA, desde un
planteamiento sinrgico y pragmtico; pero permitiendo la consulta independiente de los
apartados dedicados a cada paquete. Se presentan muchos ejemplos del funcionamiento de
esos paquetes (un navegador, un servidor HTTP, ejemplos de E/S, de RMI, de CORBA,
etc.) y el ejemplo principal de un chat (con [Link]/CORBA, con [Link]/[Link] y, despus,
con [Link]/[Link]).
Abstract: In this tutorial, divided in three parts, a general view of network communications
using Java and Java I/O is presented. For this, networks, the packages [Link], [Link],
[Link] and [Link], and also RMI and CORBA, are explained from a pragmatic and
synergic point of view; but allowing the independent consultation of the sections dedicated to
each package. Many examples of code using these packages are presented (a browser, a
HTTP server, I/O examples, RMI examples, CORBA examples, etc), together with the main
example of a chat application (using [Link]/CORBA, using [Link]/[Link] and, after, using
[Link]/[Link]).
Keywords: [Link], [Link], [Link], [Link], [Link], NIO, protocols, API Socket, layer,
TCP/IP, OSI, FTP, SMTP, POP3, HTTP, CGI, Unicode, UTF-8, UTF-16, socket,
interoperability, client-server, distributed computing, distibuted objects, client-server,
[WebMethod], N-tier, RMI, RMI registry, remote invocation, CORBA, POA, servants, CORBA
objects, IOR, transient IOR, persistent IOR, web services, server socket, non-blocking
sockets, channels, buffers, chat
La imagen de la pgina anterior corresponde a un goteado de J ackson Pollock y el copyright pertenece a sus herederos o a
cualquier institucin que los represente. Se reproduce sin nimo de lucro.
[Link]
Miguel ngel Abin, Julio 2004 - 3/313 -
NDICE DE LA PRIMERA PARTE
1. Introduccin Pgina 5
2. Fundamentos de las comunicaciones en red Pgina 15
2.1. Algunas definiciones Pgina 15
2.2. Protocolos de comunicaciones Pgina 22
2.3. TCP/IP: Un modelo de capas Pgina 23
2.4. TCP/IP: Un conjunto de protocolos Pgina 33
2.5. El modelo de referencia OSI estaba vestido para el xito,
pero el xito no le lleg
Pgina 49
2.6. El principio de extremo a extremo Pgina 52
2.7. Sockets Pgina 55
2.7.1. Introduccin. Todo empez en UNIX Pgina 55
2.7.2. Sockets. Tipos de sockets Pgina 56
2.7.3. Un ejemplo de sockets en C Pgina 67
2.7.4. Ventajas e inconvenientes de los sockets Pgina 69
2.8. Algunos servicios de la capa de aplicacin en la
arquitectura TCP/IP
Pgina 70
2.8.1. Introduccin Pgina 70
2.8.2. El servicio de administracin de redes Pgina 70
2.8.3. El servicio de transferencia de archivos Pgina 71
2.8.4. El servicio de correo electrnico Pgina 77
2.8.5. La World Wide Web Pgina 90
3. El paquete [Link] de Java Pgina 100
3.1. La clase [Link] Pgina 101
3.2. La jerarqua de clases [Link] Pgina 106
3.3. La jerarqua de clases [Link] Pgina 117
3.4. Cuando un byte no basta: comunicaciones en un
mundo plurilinge
Pgina 131
3.5. La clase [Link] Pgina 139
3.6. La clase [Link] Pgina 141
3.7. La clase [Link] Pgina 143
3.8. La clase [Link] Pgina 146
3.9. La clase [Link] Pgina 148
3.10. El patrn decorador y el paquete [Link] Pgina 150
4. Aplicaciones y sistemas distribuidos Pgina 156
4.1. Introduccin. De los mainframes a los sistemas
distribuidos
Pgina 156
4.2. Aplicaciones y sistemas distribuidos Pgina 175
4.3. Dos ejemplos de arquitecturas distribuidas: CORBA y
los servicios web
Pgina 180
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 4/313 -
5. RMI: llamando desde lugares remotos Pgina 189
5.1. Fundamentos de la RMI: el modelo de objetos
distribuidos de Java
Pgina 189
5.2. Anatoma de las aplicaciones RMI: adaptadores y
esqueletos. La arquitectura RMI. El servicio de registro
remoto RMI
Pgina 194
5.2.1. Anatoma de las aplicaciones RMI: adaptadores
y esqueletos
Pgina 194
5.2.2. La arquitectura RMI Pgina 203
5.2.3. El servicio de registro remoto RMI Pgina 205
5.3. Recorrido rpido por el paquete [Link] Pgina 209
5.4. Ejemplo completo del desarrollo e implementacin de
una aplicacin con RMI
Pgina 215
5.5. Distribucin de las aplicaciones RMI: carga dinmica de
clases con RMI
Pgina 230
5.6. Ventajas e inconvenientes de la RMI Pgina 248
6. CORBA: llamando desde ms lejos an. CORBA y Java Pgina 250
6.1. Introduccin. Para qu se usa CORBA? Pgina 250
6.2. El modelo de objetos de CORBA Pgina 252
6.3. Vocabulario bsico de CORBA Pgina 256
6.4. Dentro de la arquitectura de CORBA Pgina 259
6.5. CORBA y RMI: puntos de interseccin, puntos de fuga Pgina 282
6.6. El problema del ocano Pacfico: nufragos en los
mares de CORBA
Pgina 285
6.7. Java y CORBA: un par de ejemplos Pgina 286
[Link]
Miguel ngel Abin, Julio 2004 - 5/313 -
JAVA Y LAS REDES
Introduccin a las redes, a [Link], [Link], [Link],
[Link], a RMI y a CORBA
(1 Parte de 3)
Fecha de creacin: 27.07.2004
Miguel ngel Abin
mabian AT aidima DOT es
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:
[Link]
[Link]
[Link]
[Link] (incorporado con JDK 1.4 y mantenido en JDK 1.5 o 5.0)
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 [Link]
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 6/313 -
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
[Link] o [Link] 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 [Link], 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 [Link].
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 [Link]. Casi todas las clases del
paquete [Link] permiten abrir objetos [Link] o
[Link], que pueden usarse directamente para el intercambio de
datos. El trabajo en red con Java resulta asombrosamente sencillo: basta usar la clase
apropiada de [Link], 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
[Link] y [Link], indispensables para permitir comunicaciones
plurales en cuanto al lenguaje, y en el papel que desempea el patrn decorador como
estructura interna de [Link]. 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
[Link]
Miguel ngel Abin, Julio 2004 - 7/313 -
un buen conocimiento de este paquete, puede pasar directamente al siguiente
apartado.
Los sistemas distribuidos se tratan en el apartado 4. Para comprender por qu son
necesarios los modernos sistemas distribuidos, se parte de los sistemas monolticos
(basados en mainframes y terminales tontos) y se acaba en los ejemplos de CORBA
y los servicios web. Entre el punto de inicio y el final, se explican las arquitecturas
cliente-servidor de dos y tres capas, de N capas y se definen los conceptos en que se
basan las aplicaciones distribuidas y los problemas ms acuciantes con los que tienen
que tratar.
Quizs mis opiniones finales sobre los servicios web o sobre el [WebMet hod] de
C# sean un tanto polmicas. Podra haberlas omitido y as no levantara suspicacias
sobre mis intereses u opiniones; pero no tengo dios ni patria ni amo en cuanto a
tecnologas informticas: carezco de cualquier inters por vender o promocionar un
producto, o por predisponer al lector a favor de una o en contra de otra (los vendedores
y promotores de los servicios web, que florecen cual almendros en primavera, no
pueden decir lo mismo). Mis opiniones se basan en criterios tcnicos, en
comparaciones con otras tecnologas y en pruebas. La venta y la propaganda no me
interesan; ya hay demasiada gente dedicada a ellas. No negar que no hay ninguna
tecnologa perfecta, pero algunas son ms imperfectas que otras.
La invocacin remota de mtodos (RMI: Remote Method Invocation) de Java se
aborda en el apartado 5. El paquete [Link] es demasiado extenso y complejo
como para tratarlo de forma completa aqu; pero se exponen las clases e interfaces
ms usadas para desarrollar aplicaciones distribuidas. Supongo que los creadores de
RMI, cuando la acabaron, haran lo mismo que Frank Sinatra tras interpretar una buena
cancin: aflojarse el nudo de la corbata, sonrer con picarda y encender un cigarrillo (lo
ltimo, dicho de paso, no es muy popular en estos tiempos). Es un paquete del cual los
ingenieros de Sun pueden, con razn, sentirse orgullosos.
La RMI de Java es una obra maestra de la ingeniera del software; est bien
diseada, bien implementada y bien documentada. Por aadidura, funciona muy
eficazmente y sin la complejidad de arquitecturas distribuidas como CORBA. Si se
explica antes del paquete [Link] es porque se basa en la serializacin de objetos,
explicada en el apartado anterior.
El apartado 6 est dedicado a CORBA, una arquitectura para la construccin de
sistemas distribuidos que ha influido mucho en todas las tecnologas distribuidas
actuales. En este apartado se explica por qu usar CORBA, cul es su estructura,
cmo se integra con Java. Adems, se presentan dos ejemplos del uso de CORBA con
Java (el segundo corresponde a una aplicacin de chat).
Sun ha basado en parte su J2EE en CORBA y se ha preocupado, junto con IBM,
en conseguir la mayor integracin posible entre los productos Java y la tecnologa
CORBA.
En el apartado 7 se estudia el paquete [Link]; si bien ste no se utiliza en las
comunicaciones en red tanto como se debera, resulta muy til cuando se desea
ahorrar tiempo de transmisin. Gracias a l, se puede usar GZIP o ZIP para comprimir
la informacin que se enva a la red, ya sea mediante flujos de E/S o mediante el envo
de objetos serializados. Cuanto mayor es la redundancia de los datos, mayor es la
reduccin del tiempo de transmisin y del trfico en la red.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 8/313 -
En el apartado 8 se explica el paquete [Link]; todas las clases de este ltimo
paquete (Ser ver Socket , Socket , Dat agr amSocket , URL, etc.) se ilustran con
muchos ejemplos (un primitivo navegador, un servidor HTTP, etc.). En el apartado 9 se
presenta el ejemplo de una aplicacin cliente-servidor de tipo chat.
En el apartado 10 se explican las novedades de [Link], incluido por vez
primera en el JDK 1.4, y se aborda su utilizacin para las comunicaciones en red.
Conceptos como selectores, canales, buf f er s (instancias de las clases Byt eBuf f er ,
I nt Buf f er , Doubl eBuf f er , etc.) y sockets sin bloqueo se ven con detenimiento en
dicho apartado. Cualquier programador que use Java para programar aplicaciones en
red debera tener muy en cuenta el paquete [Link], pues proporciona E/S sin
bloqueo, caracterstica que permite programar aplicaciones sumamente escalables
usando sockets. Gracias a ella, se evitan los problemas derivados de usar mltiples
hilos que aparecen cuando la E/S s es bloqueante: sobrecarga del sistema, violaciones
de la seguridad de los hilos, bloqueos, etc. En el apartado 11 se presenta el ejemplo de
una aplicacin cliente-servidor de tipo chat escrita con [Link], y se compara con la
versin del apartado 9.
Todo el cdigo de los ejemplos puede conseguirse envindome un correo (mabian
AT aidima DOT es) con el asunto Java y las redes.
Desde luego, este tutorial no trata de unir dos puntos (las redes y Java) mediante
un arabesco o un ocho; pero tampoco intente trazar una lnea absolutamente recta,
pues hay ideas y conceptos que no caen en el segmento recto entre dichos puntos, si
bien son interesantes para entender por qu Java es como es y para desarrollar
aplicaciones tiles y eficaces.
Incluir un apartado dedicado a [Link] no es tarea ociosa. Si bien Java incluye
el paquete [Link] para trabajar en red, las entradas y salidas que corresponden a
las conexiones mediante sockets, a la clase URL y a las clases HTTP acaban usando
clases del paquete [Link] (o de [Link], si as lo desea el programador). Como
el modelo de E/S utilizado por Java no presta atencin al lugar de donde proceden los
datos, resulta conveniente conocer bien unas cuantas clases del paquete [Link].
Aparte, la mayor parte de los libros dedican poco espacio a las codificaciones de
caracteres y a la forma en que Java trata los caracteres Unicode, caractersticas muy
importantes a la hora de construir aplicaciones en red para usuarios que usen
distintos idiomas. En algunos casos, las simplificaciones de los textos llevan a
engao. As, en muchos sitios de la documentacin oficial de Java y de Windows se
afirma que Unicode es un sistema de codificacin de diecisis bits, lo cual es
manifiestamente falso (tal y como se ver en el apartado 3).
Por supuesto, dar una explicacin completa y exhaustiva del paquete [Link]
aqu queda fuera de lugar; pero se han tratado los aspectos ms ligados con las
comunicaciones en red. Pese a que no parece que haya despertado mucho inters en
los programadores, es un paquete con muchsimas mejoras importantes con respecto a
[Link], y que acerca a Java al sueo de ser un lenguaje tan vlido como C/C++ para
realizar computaciones complejas y programar controladores de dispositivos. Si nos
restringimos al mbito de las comunicaciones en red, su uso aporta sencillez al cdigo
y mejora espectacularmente el rendimiento (mejoras del 50%-80% son frecuentes).
[Link]
Miguel ngel Abin, Julio 2004 - 9/313 -
Si bien cada apartado se ha escrito pensando en que refuerce a los otros, se
pueden consultar independientemente, de modo que el lector puede espigar a su gusto.
El lector que slo quiera saber qu ofrece un paquete puede pasar directamente al
apartado correspondiente. No obstante, para extraer el mximo provecho del tutorial
recomiendo su lectura ordenada.
En varios apartados he incluido recuadros que incluyen avisos, advertencias
curiosidades. Mi idea es advertir al lector de detalles que pueden devenir importantes o
que son fuente comn de errores o confusiones.
El dilema de escoger entre teora y prctica se ha solventado aqu mezclando
ambas a partes casi iguales, gramo ms, gramo menos. No digo que sea la mejor
manera posible, pero si es la menos mala que conozco. Se puede afirmar que hay que
conocer a la perfeccin la teora de redes para entender lo que hace Java (o C o C++),
pero discrepo de esa opinin (si pensara as, no escribira obras de divulgacin).
Aunque algunos piensen que un conocimiento a medias es peligroso, creo que esta
postura, aparte de elitista y acadmica, anda errada: es preferible sentar unas bases,
aun incompletas, siempre que no se desvirten los conceptos e ideas ni se mellen
innecesariamente las aristas y bordes de la materia, a remitir de entrada a libros
definitivos, que a menudo no pueden entenderse o valorarse hasta que uno ya tiene
experiencia en la materia tratada. Situaciones como la de emplear libros formalistas y
axiomticos para ensear termodinmica a alumnos que tienen el primer contacto con
la materia se me antojan aberrantes: ninguna disciplina nace formada y axiomatizada
(excepto las que ya nacen muertas). Olvidar para qu se desarrollan los conocimientos
cientficos y tcnicos (dicho de otro modo: desdear qu problemas quieren resolver)
es una de las tragedias de la Universidad espaola. No crean que dramatizo, que las
tragedias son muchas: no se necesita la calculadora para evaluar los reconocimientos
internacionales a la ciencia desarrollada en Espaa. El nico premio Nobel cientfico
generado a medias, pero sa es otra (larga) historia por el sistema universitario
espaol data de 1906.
La primera versin de este tutorial, que termine en febrero de 2004, ocupaba ms
de cuatrocientas pginas. Sin embargo, no me satisfaca en absoluto: haba prestado
demasiada atencin a las jerarquas de clases de los paquetes arriba mencionados, y
el tutorial casi se haba convertido en una recopilacin exhaustiva de clases y mtodos.
Sin rodeos: me haba perdido en la inmensidad de las entraas de ese sofisticado
lenguaje conocido como Java.
Afortunadamente, el camino admita retorno: decid reescribir el tutorial desde
cero, considerando estas ideas clave:
Describir slo las clases y mtodos imprescindibles para la mayora de las
comunicaciones en red.
Apoyarme, en la medida de lo posible, en ejemplos.
Hay tres motivos para obrar as: a) la documentacin de todas las clases de Java
est disponible para cualquier desarrollador (aunque por doquier hay libros que
parecen pensar que no es as); b) muchos programadores slo usan unas pocas clases
de los paquetes anteriores casi siempre las mismas; y c) los ejemplos, pese a su
incompletitud, son la mejor manera de fijar ideas y de comprender para qu puede
servir cada clase.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 10/313 -
Por su naturaleza, este trabajo peca de omisiones, pues es imposible abarcar en
un tutorial todo lo que se conoce sobre redes. Hay una omisin que lamento mucho: la
de la historia de Internet. No me refiero a la historia oficial, expurgada, beatificada y
santificada, sino a la verdadera historia de la red de redes, una historia que comienza
con un puado de hackers, de bolcheviques de saln, de hijos de Marx y de la Coca
Cola, de izquierdista de derechas, muchos de ellos californianos, y que acaba en el
NASDAQ, en la especulacin y en situaciones tan absurdas e ilgicas como ver cotizar
las acciones de Amazon a seiscientos dlares, o las de Terra a ms de cien euros.
Tal como cuenta Bruce Sterling en The Hacker Crackdown (la traduccin es ma):
[...] Las races genuinas del moderno movimiento subterrneo de los
hackers pueden rastrearse ms precisamente hasta un movimiento hippie
anarquista ahora bastante olvidado que se conoci como los Yippies. Los
Yippies, quienes tomaron su nombre del bastante ficticio Youth International
Party [Partido Internacional de los Jvenes], llevaron a cabo una ruidosa y
vitalista poltica de subversin surrealista y exagerada maldad poltica. Sus
premisas bsicas eran la promiscuidad sexual flagrante, el consumo abundante
y pblico de drogas, el derrocamiento poltico de cualquier personaje poderoso
de ms de 30 aos de edad y un final inmediato para la guerra de Vietnam,
empleando cualquier medio que fuera necesario, incluida la levitacin psquica
del Pentgono. Los dos yippies ms notorios fueron Abbie Hoffman y Jerry
Rubin. [...]
[...]
Se dice que Abbie Hoffman ha provocado que el Federal Bureau of
Investigation [FBI] acumulara la ms voluminosa ficha jams abierta a un slo
ciudadano estadounidense [...]. Fue un publicista de talento, que reconoca los
medios electrnicos como campo de juego y como arma a la vez. Disfrut de la
manipulacin activa de las cadenas de TV y de otros medios hambrientos de
imgenes, con extraas mentiras, rumores extraordinarios, disfraces y
suplantaciones y otras siniestras distorsiones, siempre con la garanta absoluta
de crear problemas y dificultades a la polica, a los candidatos presidenciales y a
los jueces federales [...].
En cuanto a relevancia poltica, los yippies fueron un completo cero a la izquierda;
saban gritar sus consignas cuando haba una cmara de televisin cerca y tenan el
aspecto que la polica presupona en cualquier sospechoso, pero ah acababa todo. En
cuanto a conciencia poltica, eran un completo fraude. Su activismo poltico estuvo ms
cercano a un espectculo bufonesco que a otra cosa. Quizs ellos creyeran que
estaban haciendo la sacrosanta Revolucin, pero fueron poca cosa ms que unos
oportunistas que saban gritar las consignas necesarias para salir en los medios de
comunicacin y para asustar a la temerosa clase media norteamericana (como Marilyn
Manson, pero sin tanto maquillaje y sin prejuicios hacia los fumadores): Mata a tus
padres (veinte aos despus, Hoffman lo convirti en Ama a tus padres), No te fes
de nadie de ms de treinta aos, seguro que se ha vendido al sistema. Entonces,
cmo se va uno a fiar de alguien de menos de treinta aos, si sabe que acabar
vendindose? Incuestionablemente, una persona como Rosa Banks la humilde
costurera de Alabama que se neg a ceder su asiento a un hombre blanco, a lo cual
estaba obligada por ley representaba un peligro un milln de veces mayor para unos
Estados Unidos blancos y anglosajones que personas como Hoffman y Rubin. Sin
embargo, stos influyeron de manera reconocible en muchas personas relacionadas
con las redes que acabaran siendo parte de lo que conocemos hoy como Internet.
Cuando se escriba la historia completa de Internet, alguien deber explicar cmo
un producto derivado de la guerra fra, al igual que la carrera espacial, se nutri del
trabajo de tanta gente que se defina como pacifista, libertaria (en el sentido
[Link]
Miguel ngel Abin, Julio 2004 - 11/313 -
estadounidense del trmino, no en el europeo) o que, cuando menos, mantena un gran
recelo hacia el control gubernamental (pese a que era el gobierno de los Estados
Unidos el que subvencionaba, directa o indirectamente, sus trabajos e investigaciones).
Muchos investigadores y hackers que se identificaban con el Captain America de Easy
Reader, con Timothy Leary o con Abbie Hoffmann participaron en un proyecto
financiado al principio por el Pentgono. Cunto influy en ello que la Internet
financiada por el Pentgono fuera pblica de verdad, esto es, de acceso libre y
gratuito?
Ese alguien tambin deber explicar por qu se puso toda la tecnologa e
infraestructura desarrollada con dinero pblico (del Pentgono y, luego, de la National
Science Foundation) en manos de unas pocas empresas privadas. Desde luego, en
Europa se ve raro (y seguramente es ilegal) que una tecnologa se pague con fondos
pblicos y que luego se regale a unas cuantas grandes empresas. Sera como obligar
al sector pblico a que gastase sumas multimillonarias en investigacin y desarrollo
para que los frutos se los quedaran unos pocos, en lugar de la sociedad. Dicho sin
tapujos tecnolgicos o econmicos: no se puede pretender que unos den de pastar a la
vaca para que otros se beban la leche de sus ubres; el dinero pblico no puede ser la
versin econmica del sastre de Campillo, que cosa de balde y pona el hilo. Por otro
lado, Europa considerara que una prctica as es competencia desleal: se perjudica
tanto a las empresas a las que no se cede esa tecnologa e infraestructura como a las
empresas de otros pases donde no hay dinero pblico para esos fines.
Afortunadamente, en el desarrollo de Internet han existido y existen muchas
personas ms preocupadas en divulgar sus conocimientos que en el lucro. Por
ejemplo, la World Wide Web existe tal como la conocemos gracias al espritu
desinteresada de su inventor, el fsico britnico Berners-Lee. En una entrevista
publicada el 30 de junio de 2004 en el diario Expansin, explica por qu entreg gratis
su invento al mundo: Si hubiese pedido dinero, hoy no hubiera existido la red mundial
WWW, sino pequeas redes aisladas en Internet. Sus palabras me recuerdan a las
que dijo Marie Curie cuando discuta la idea de conseguir la patente sobre el radio: Es
imposible e ira contra el espritu cientfico [ ... ]. Los investigadores siempre deben
publicar sus resultados por completo. Si nuestro descubrimiento tiene aplicacin
comercial, es algo de lo que no debemos sacar provecho. Si el radio va a usarse en el
tratamiento de ciertas enfermedades, me parece inadmisible beneficiarnos de ello.
Puede que Marie Curie fuera una ingenua y que Berners-Lee tambin lo sea; pero ojal
el mundo estuviera ms lleno de ingenuos.
Una historia completa de Internet tambin deber contar que algunas compaas
creadas al calor de la red no se preocuparon por sus empleados y accionistas lo que
hubiera hecho que el dinero pblico invertido en Internet repercutiera en la sociedad
que, a fin de cuentas, lo haba generado, sino que se dedicaron a llenarse los bolsillos
con el dinero de los incautos que invertan en ellas (en la bolsa suele decirse que un
ignorante y su dinero no permanecen mucho tiempo juntos). Cmo consiguieron el
dinero ajeno? Fue sencillo; gritaban con fuerza nuevos modelos de negocio, las
tcnicas tradicionales de valoracin son intiles con nuestras empresas, el potencial
de Internet es ilimitado, no pierda esta oportunidad y paparruchas por el estilo. Los
folletos de las OPV insistan en que invertir en las puntocom era peligroso: no pagaban
dividendos, no tenan beneficios ni se prevea que los tuvieran en mucho, mucho
tiempo, pero..., ya sabe lo que se dice de los ignorantes, verdad?
Quiz se pregunte usted qu relacin puede haber entre la especulacin burstil y
Java o las redes. La hay, desde luego: Sun alcanz cotizaciones jams imaginadas
gracias a la publicidad intensiva que hizo de Java. Muchas empresas pequeas y
medianas consiguieron inversores anunciando que haban trasladado todas sus
aplicaciones a Java o que ya slo iban a trabajar con Java. Algunas, faltas de
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 12/313 -
experiencia o incapaces de ver que Java no poda satisfacer sus objetivos,
protagonizaron algunos de los ms vergonzosos y sonrojantes retornos a lenguajes o
modelos de negocio tradicionales que an se recuerdan. Corel es mi ejemplo favorito,
aunque poca gente lo recuerda: la intencin de escribir todos los productos de la
empresa en Java tuvo que abandonarse tras un contundente fracaso tcnico y
econmico. Por si fuera poco, Corel no aprendi la leccin: decidi sacar todas sus
aplicaciones para el SO Linux y sacar su propia versin del SO; finalmente, ha tenido
que abandonar todos sus proyectos concernientes a Linux, tal y como hizo con los de
Java. Con respecto a las redes, el hundimiento de las puntocom ha ocasionado
recortes en los presupuestos empresariales para el desarrollo de nuevas tecnologas y
cierta reticencia en los inversores a la hora de financiar novedades. Adems, algunas
redes de fibra ptica han cambiado de manos tras la debacle. Y las nuevas manos
estn demasiado ocupadas intentando paliar las prdidas que dejaron las viejas como
para pensar en ampliar o mejorar las infraestructuras de telecomunicaciones. No se
puede negar que el agujero dejado por la economa virtual ha tenido consecuencias
relevantes en la economa real. Y las redes, no lo olvidemos, forman parte de esta
ltima.
Durante los aos noventa se pensaba que las empresas puntocom no tenan
lmites, que el cielo era la ltima frontera. Pero se olvid que, por mucho que crezca un
rbol, las ramas nunca alcanzan el cielo. Ahora todos sabemos en qu acab todo ello.
De una forma hipcrita, cas cnica, hasta el Wall Street Journal tuvo que publicar las
verdades del barquero cuando acab la fiesta y hubo que recoger los platos rotos:
Mito nmero 1: Las empresas de tecnologa pueden generar beneficios
impresionantes en ingresos, ventas y produccin durante los prximos aos.
Mito nmero 2: Las empresas tecnolgicas no estn sujetas a las fuerzas
econmicas ordinarias, como una compaa lenta o un aumento de los tipos
de inters.
Mito nmero 3: Los monopolios crean increbles oportunidades.
Mito nmero 4: El crecimiento exponencial de Internet acaba de comenzar, y
si cambia ser para acelerar.
Mito nmero 5: Las perspectivas futuras son ms importantes que los
ingresos inmediatos.
Mito nmero 6: Esta vez, las cosas sern diferentes...
Desde luego, envidio a quien escriba la historia completa de Internet. Dispondr
de un argumento que parece sacado de una comedia griega: hay pasin, rebelda,
engao, juventud, clera, avaricia, celos, envidias... Y al final, como siempre, los dioses
ridiculizarn a los avariciosos antes de destruirlos.
Si no me engao, Menndez y Pelayo escribi que el autor que comienza un libro
es discpulo del que lo termina. Aun no siendo este texto un libro, me reconozco en su
frase. Al escribirlo, he visto como muchas relaciones entre conceptos se iban
explicitando. No dudo que las relaciones estuvieran ah desde el principio; pero para
qu nos sirve aquello de lo que no somos conscientes? Al intentar tensar la red del
tutorial, he visto como unos hilos reforzaban a otros, manifestando vnculos que me
haban pasado inadvertidos hasta el momento.
Si bien el hipertexto es una estupenda herramienta, no puede hacer por nosotros
el trabajo de enlazar lgicamente datos y de buscar semejanzas o analogas.
Abundancia de datos no equivale a informacin ni a conocimiento, por ms inmediatez
[Link]
Miguel ngel Abin, Julio 2004 - 13/313 -
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.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 14/313 -
En febrero de 2003 se public en javaHispano un tutorial mo titulado Cmo
hacer un chat en Java (JDK 1.2-1.3 y JDK 1.4-1.5): fundamentos, desarrollo e
implementacin. Aunque en l se tratan parcialmente las comunicaciones en red y el
paquete [Link] y se explica cmo programar un chat, hay demasiadas
diferencias entre ambos como para que este tutorial se pueda considerar una nueva
versin o una ampliacin de aqul:
El propsito de este tutorial no es solamente hacer un chat: es aprender
a usar Java para las comunicaciones en red. Con todo, no he
renunciado al ejemplo de un chat, pues es difcil encontrar problemas
donde se manejen a un tiempo tantos conceptos de comunicaciones en
red.
El apartado comn de fundamentos de las comunicaciones en red se ha
ampliado. Ahora ocupa ms espacio que el tutorial Cmo hacer un chat
en Java. Aparte del inters que la materia que muestra tiene por s
misma, resulta absurdo intentar programar para redes sin saber qu hay
bajo ellas.
Se han incluidos apartados inexistentes en aqul. As, los dedicados a
[Link], [Link], [Link], a los sistemas distribuidos, a RMI y a
CORBA.
Se trata a fondo la internacionalizacin con [Link], imprescindible
para escribir aplicaciones multilinges.
Se ha aadido mucho cdigo (ejemplos de E/S, un primitivo navegador,
un sencillo servidor HTTP, etc), no relacionado con lo que se precisa
para programar un chat.
Se ha mejorado mucho el cdigo dedicado al chat (sincronizacin de
mtodos, control de los tiempos de conexin sin actividad, eliminacin
de hilos muertos, etc.), para que el lector entienda las complejidades
que se presentan al escribir aplicaciones para redes.
Se ha incluido el cdigo completo de un chat en [Link], el cual
apenas estaba esbozado en el tutorial del chat. Tambin se incluye el
cdigo de un chat basado en CORBA.
Por lo dicho, considero que este tutorial es independiente del otro. Java y las
redes resulta ms idneo para quienes deseen una introduccin al abultado
hexagrama [Link]/ [Link]/ [Link]/ [Link]/ RMI/CORBA. Cmo
hacer un chat en Java se orienta ms hacia quienes slo deseen echar un vistazo a
[Link] para ver si les interesa o no. Mi idea es mantener ambos en
javaHispano.
[Link]
Miguel ngel Abin, Julio 2004 - 15/313 -
2. Fundamentos de las comunicaciones en red
2.1. Algunas definiciones
Para entender cmo se producen las comunicaciones en Internet o en cualquier
red TCP/IP, conviene definir de entrada ciertos conceptos bsicos (casi todos se
detallarn con ms exactitud conforme avance el tutorial):
Un proceso es un programa en ejecucin; cada proceso es
independiente de los otros y tiene reservado un cierto espacio de
direcciones de memoria. En general, los procesos son controlados por
el sistema operativo. Un proceso consiste en a) un espacio de memoria
virtual para el cdigo ejecutable y los datos; b) unos recursos del
sistema operativo; c) un estado del procesador (especificado por los
valores que toman las direcciones de memoria fsica, los registros, etc.);
y d) una especificacin de seguridad, en la que se almacenan los
permisos del proceso y de su propietario. En las redes, los sockets son
un mecanismo para permitir la comunicacin entre procesos.
Un mquina o equipo es un hardware capaz de ejecutar procesos. A
veces, tambin se usa sistema o dispositivo con ese sentido.
Una red es un conjunto de mquinas o equipos (no necesariamente
ordenadores: pueden ser telfonos mviles, agendas electrnicas,
electrodomsticos, etc.) que comparten un mismo medio fsico de
comunicacin (cable coaxial, fibra ptica, ondas de radio, lser, etc.) y
un mismo conjunto de reglas para comunicarse entre ellos. Si los
dispositivos estn todos en una zona geogrfica limitada y no muy
extensa por ejemplo, un edificio o un campus, se habla de redes de
rea local o LANs (Local Area Networks); en caso contrario, se habla
de redes de rea extensa o WANs (Wide Area Networks). Por ejemplo,
los ordenadores de las sucursales de un banco forman parte de una
WAN.
Un anfitrin (host) es una mquina (habitualmente, un ordenador)
conectada a una red. Dicho de otro modo: es un nodo de la red. Este
trmino tambin suele usarse para referirse a mquinas que ofrecen
servicios a otros computadores (FTP, Telnet, etc.), caso en que
equivale a servidor u ordenador central. En los textos anglosajones
suele llamarse host address a la direccin de Internet o direccin IP de
un nodo.
Un protocolo es un conjunto de reglas y procedimientos necesario
para que dos mquinas intercambien informacin. Existen muchos
conjuntos de protocolos para las comunicaciones en red entre
ordenadores: IBM desarroll SNA (Systems Network Architecture) y
APPN (Advanced Peer-To-Peer-Networking); DEC desarroll DNA
(Digital Network Architecture); Apple cre Appletalk; Novell usa su
SPX/IPX (Sequenced Packet Exchange/Internet Packet Exchange);
Xerox usa XNS (Xerox Network Services), etc. Sin embargo, el conjunto
ms popular de protocolos de red es TCP/IP, que se estudiar en los
siguientes subapartados.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 16/313 -
Un protocolo fiable es, desde el punto de vista de las comunicaciones,
un protocolo que incluye deteccin de errores y, a menudo, correccin
de errores.
Una tarjeta de red o una tarjeta adaptadora de red es el hardware
que se conecta fsicamente con el cableado de la red. La tarjeta se
gestiona con el software del controlador de la tarjeta. Las tarjetas de red
se encargan de la transferencia fsica de la informacin entre las
mquinas de la red.
Una direccin fsica o de hardware es un cdigo que identifica
unvocamente un nodo o anfitrin de una red. En las redes que siguen
los estndares IEEE 802 (como Ethernet), cada tarjeta de red tiene su
propio identificador nico, de 48 bits de longitud: la direccin MAC
(Media Access Control), grabada en un chip dentro de ella. Por ejemplo,
el nmero hexadecimal 00:A0:C9:12:C3:25 corresponde a una direccin
MAC vlida, asociada a una tarjeta de red fabricada por Intel
Corporation. La direccin MAC de un ordenador es la direccin MAC de
su tarjeta de red. Otras redes usan como direcciones fsicas direcciones
DLC (Data Link Control).
Ethernet es la tecnologa dominante para redes de ordenadores del
tipo LAN. Viene definida por el protocolo IEEE 802.3 y especifica
exactamente el cableado y las seales elctricas que debe usar la red.
Toda mquina en una red Ethernet tiene asignado un nmero nico de
48 bits, conocido como direccin Ethernet o direccin MAC. La
asignacin de direcciones Ethernet se hace de modo que no existan
dos mquinas con la misma direccin MAC. Actualmente, las redes
Ethernet utilizan cable coaxial delgado (10Base-2), cable coaxial grueso
(10Base-5), cable de par trenzado (10Base-T) y fibra ptica (10Base-F).
Internet es la mayor red pblica TCP/IP que existe. Est formada por la
interconexin de un gran nmero de redes de ordenadores de
diferentes tipos, capaces de interoperar gracias al uso comn de la
familia de protocolos TCP/IP. En Internet se emplean distintos lenguajes
de programacin, sistemas operativos, redes, hardware, conectores,
etc.; sin embargo, TCP/IP hace que todas estas diferencias no
importen.
Una intranet es una red privada, perteneciente a una organizacin, que
utiliza los protocolos TCP/IP. Las intranets son parte de Internet, pero
se administran independientemente y suele tener fronteras
configurables en cuanto a seguridad y acceso. Habitualmente, se
componen de varias redes LAN enlazadas entre s. Tcnicamente, una
Intranet viene a ser una versin en miniatura de Internet. Cualquier
aplicacin o servicio disponible en Internet est disponible en las
intranets.
Una extranet es la unin de dos o ms intranets. Las extranets estn
usndose para permitir el comercio electrnico entre empresas y para
integrar partes de sus sistemas informticos. Por ejemplo, la aplicacin
que controla el sistema de produccin de un fabricante puede integrase
mediante una extranet con la aplicacin que gestiona los pedidos de un
distribuidor.
[Link]
Miguel ngel Abin, Julio 2004 - 17/313 -
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
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 18/313 -
que mueven datos entre diferentes conjuntos de protocolos (por
ejemplo, entre TCP/IP y el SNA de IBM), y encaminador (router) para
los que mueven datos entre subredes que operan con los mismos
protocolos.
Un cortafuegos (firewall) es un medio de regulacin del acceso a una
red, ya sea mediante hardware o software. Su principal misin es limitar
el acceso a intranets o extranets (aunque se usan cada vez ms para
proteger anfitriones aislados) filtrando los paquetes que entran y salen,
de forma que slo se permita el flujo de paquetes autorizados. Un
cortafuegos puede, por ejemplo, impedir el paso de paquetes
procedentes de ciertas mquinas o el envo de paquetes a otras.
Los flujos o corrientes (streams) son tuberas o canales de
comunicaciones: tienen dos extremos entre los cuales fluyen los datos
de manera continua. Obedecen literalmente la ley de Bennet (Si un
cable tiene un extremo, probablemente tiene otro).
Una plataforma es una combinacin especfica de hardware y de
sistema operativo. Por ejemplo, un PC con una arquitectura Pentium y
con el sistema operativo Red Hat pertenece a la plataforma Intel/Linux.
Mainframe equivale a macroordenador, gran ordenador, ordenador
central o servidor corporativo. Viene a ser un trmino industrial para los
ordenadores grandes. Las mquinas con la arquitectura 390 de IBM son
un ejemplo de mainframe. La palabra viene de los armazones metlicos
donde se guardan estos ordenadores. Hoy da, los mainframes no se
caracterizan por ser voluminosos, sino por su eficiencia a la hora de
acceder a sistemas de almacenamiento (discos) y de transferir los datos
del disco a la mquina.
Un demonio (daemon o demon) es un programa o proceso al que no
se llama explcitamente, pero que permanece en estado latente hasta
que se cumplen ciertas condiciones. El trmino viene de UNIX. Los
demonios se usan mucho en procesos relacionados con redes, porque
permanecen a la espera de peticiones de los clientes sin impedir la
ejecucin de otros programas. En ingls, daemon es la grafa antigua
para demon (demonio, o espritu bueno o malo). En los textos de
telecomunicaciones se usa a veces dragn (dragon) como sinnimo de
demonio.
Un RFC (Request For Comments: peticin de comentarios) es un
documento relacionado con algn estndar de Internet o de los
sistemas relacionados con ella. Protocolos como HTTP, SMTP, POP3 o
FTP se han definido mediante unos RFC. Uno de los RFC ms
famosos, pese a su difcil implementacin, es el RFC 1149
([Link] cuyo nombre es Standard for the
transmission of IP datagrams on avian carriers (Estndar para la
transmisin de datagramas IP en aves mensajeras), que define el
protocolo CPIP. Actualmente ya se dispone de una implementacin del
CPIP.
[Link]
Miguel ngel Abin, Julio 2004 - 19/313 -
Figura 1. Un router muy popular. Extrado de la publicidad de Cisco Systems, Inc.
Figura 2. Una tarjeta de red
Figura 3. Una extranet muy sencilla. Dibujo escaneado de Daryl's TCP/IP Primer
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 20/313 -
Figura 4. Una extranet ms compleja que la de la figura 3
Figura 5. Esquema muy simplificado de la estructura de Internet
Subred (regional,
nacional, etc.)
Red principal
Red
principal
Subred (regional,
nacional, etc.)
Redes locales: LANS
Miguel ngel Abin, Abril 2004
[Link]
Miguel ngel Abin, Julio 2004 - 21/313 -
Figura 6. Esquema de una trama Ethernet
Ethernet Addressing
Each interface looks at every frame and
inspects the destination address. If the
address does not match the hardware
address of the interface (or the
broadcast address), the frame is
discarded.
Some interfaces can also be
programmed to recognize multicast
addresses
Una
Una
trama
trama
Ethernet
Ethernet
8 bytes 8 bytes 66 66 22 0-1500 0-1500 4 4
Prembulo
Direccin
destino
Direccin
origen
Tipo CRC Datos Prembulo Prembulo
Direccin
destino
Direccin
destino
Direccin
origen
Direccin
origen
Tipo Tipo CRC CRC Datos Datos
Prembulo: 8 bytes, secuencia de ceros y unos usada para la
sincronizacin.
Direccin de destino: 6 bytes, direccin fsica del nodo de destino
(direccin MAC).
Direccin de origen: 6 bytes, direccin del nodo de origen.
Tipo: 2 bytes, especifica el protocolo de la capa superior usado.
Datos: entre 46 y 1500 bits, informacin de las capas superiores.
CRC: 4 bytes, Cyclic Redundancy Check, es una secuencia de
comprobacin de la trama.
Miguel ngel Abin, Abril 2004
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 22/313 -
2.2. Protocolos de comunicaciones
En An Internet Encyclopedia se define protocolo como una descripcin formal de
los formatos de mensaje y reglas que dos o ms mquinas deben seguir para
intercambiar esos mensajes. Los protocolos de comunicaciones establecen la manera
como se realizan las comunicaciones entre ordenadores. La meta ltima del uso de
protocolos es conseguir que ordenadores con distintos sistemas operativos y
arquitecturas de hardware puedan comunicarse si siguen al pie de la letra los
protocolos; dicho de otro modo, se persigue la independencia del proveedor. El espritu
que gua el diseo de protocolos para redes se resume en la frase Sea conservador en
lo que haga, sea liberal en lo que acepte de otros.
Los protocolos fundamentales de Internet son el TCP (Transmission Control
Protocol) y el IP (Internet Protocol). Para evitar confusiones, conviene aclarar que las
siglas TCP/IP se usan para designar conceptos ntimamente relacionados, pero no
idnticos:
1) Por un lado, un modelo de capas.
2) Por otro lado, un conjunto o familia de protocolos (TCP, IP, UDP,
Telnet, FTP, etc.) con un comportamiento comn, no la mera suma de
los protocolos TCP e IP. Algunos de estos protocolos se vern ms
adelante.
Un conjunto de capas y protocolos forma una arquitectura de comunicaciones.
Figura 7. Algunos protocolos de la familia TCP/IP. Dibujo escaneado de Data and
Computer Communications
[Link]
Miguel ngel Abin, Julio 2004 - 23/313 -
2.3. TCP/IP: Un modelo de capas
En general, entender cualquier proceso de comunicacin es tarea compleja.
Dentro de procesos como enviar correo electrnico, consultar pginas web o,
simplemente, llamar por telfono, se ocultan muchos subprocesos que se entrelazan de
forma no trivial.
Como es tendencia inherente al gnero humano el reducir la complejidad de los
problemas para intentar resolverlos, resulta natural que las comunicaciones tambin se
aborden desde una aproximacin simplificadora. La manera ms sencilla de simplificar
cualquier proceso consiste en dividirlo en pequeos problemas de ms sencilla
manipulacin: fragmentar facilita la comprensin. As, un proceso complejo de
comunicaciones se fragmenta en subproblemas de menor complejidad. Las capas (o
niveles) agrupan subproblemas relacionados entre s.
Las capas son objetos conceptuales que modelan situaciones. Para cada capa
puede definirse una forma de funcionamiento (o varias) que resuelve uno o ms
subproblemas asociados a la capa: estas formas de funcionamiento se denominan
protocolos. Con otras palabras: los protocolos en un modelo de capas son posibles
modos de funcionamiento de una capa, que la definen funcionalmente. Un protocolo
puede convertirse en un estndar, ya sea de jure o de facto; en ese caso, cualquier
fabricante de productos de hardware o de software puede disear y construir productos
que implementen ese estndar. As, el protocolo de rea local Ethernet
(correspondiente a la norma IEEE 802.3) es implementado por muchos fabricantes que
comercializan productos Ethernet compatibles entre s, pero distintos en cuanto a
circuitera.
Cada capa lleva a cabo un conjunto de funciones bien definidas y slo puede
comunicarse con otras mediante una interfaz, especificada por algn protocolo. El
trmino capa resulta muy apropiado, pues las comunicaciones se realizan mediante el
paso de los datos de una capa a la que est inmediatamente bajo ella, y as
sucesivamente. Entre dos mquinas, las comunicaciones desde la capa N de una de
ellas hasta la capa N correspondiente a la otra se comportan segn los protocolos
definidos para esa capa concreta.
A una capa le pueden corresponder varios protocolos; pero un protocolo no puede
corresponder a varias capas (se violara la definicin de capa). Las capas se
construyen de modo que la capa N de la mquina receptora recibe exactamente el
mismo objeto enviado por la correspondiente capa N de la mquina emisora.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 24/313 -
Figura 8. Un modelo de capas para un sistema de comunicaciones que todos
hemos utilizado
El sencillo modelo en capas de la figura 8 encapsula en capas los diversos
subproblemas que se plantean para que una carta llegue a su destino y muestra
algunas posibles soluciones. He aqu algunos de los problemas que se resuelven en
las capas:
- En qu lenguaje se debe escribir la carta para que la persona que la reciba la
entienda?
- Qu formato debe usarse para que el sistema de correos sepa cul es el
destino de la carta?
- Cmo se localiza el lugar geogrfico donde se encuentra la persona a quien se
enva la carta?
- Cmo se transporta la carta (es decir, la informacin) de un sitio a otro?
- Qu rutas son las ms adecuadas para llevar lo antes posible cada carta a su
destino?
Carta
Capas
Capas
de un
de un
servicio
servicio
de
de
correos
correos
Carta Destino
Sobre con
direccin
Barajas
Charles de
Gaulle
Espaol
Sobres y
sellos
Buzn Furgoneta
Almace-
namiento Transporte
Miguel ngel Abin, Abril 2004
[Link]
Miguel ngel Abin, Julio 2004 - 25/313 -
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:
[Link]
[Link] . Disfruten del Ctes dOr.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 26/313 -
El lector que conozca la terminologa de la orientacin a objetos reconocer que
las capas vienen a ser como clases bien encapsuladas, con interfaces pblicas e
implementaciones internas privadas. Si se cambia la implementacin interna de una
clase y se respeta la interfaz, no se necesita modificar el resto de las clases.
La relacin funcional entre capas se representa en la figura 9.
Figura 9. Comunicacin entre capas
Comunicacin en una arquitectura
de capas
Capa N
Funciones utilizadasde la capa N - 1
Funcionesofertadasa la capa N+1
Cada capa slo se
relaciona con las
inmediatamente
contiguas, lo que
simplifica el estudio de
las comunicaciones y los
protocos
Miguel ngel Abin, Marzo 2004
[Link]
Miguel ngel Abin, Julio 2004 - 27/313 -
La estructura en capas resulta muy habitual en telecomunicaciones.
Consideremos, por caso, una conversacin telefnica acerca de anzuelos entre un
informtico alemn y un pescador australiano, ambos hablantes de esperanto (cada
uno desconoce la lengua verncula del otro). Aunque las redes telefnicas a las que
estn conectados son completamente distintas, permiten que cada uno oiga al otro:
son capaces de interoperar. Por otra parte, cada hablante puede escuchar no slo
or las palabras que dice el otro porque usan un lenguaje comn (esperanto). Por
ltimo, si la conversacin tiene sentido para ambos (en otras palabras, si existe
comunicacin efectiva) es porque versa sobre asuntos o intereses que ambos
comparten (la pesca, en este caso). Estamos, pues, ante una arquitectura de dos
capas red telefnica y lengua, en la que existen tres protocolos el asociado a la
transmisin fsica de la voz, el esperanto y la pesca; como hoy da la palabra
arquitectura se usa con la ligereza del helio, espero que nadie se ofenda por la
imprecisin del trmino.
En este ejemplo, cada capa es lgicamente independiente de las otras (que se
pueda establecer comunicacin telefnica no implica que los interlocutores hablen el
mismo idioma o que tengan intereses comunes); pero todas son necesarias para la
comunicacin. La capa fsica corresponde a la red telefnica, pues sta permite la
comunicacin fsica (la transmisin de voz). Los dos usuarios no necesitan saber, al
igual que ocurre en Internet, nada de los detalles de la capa fsica; basta con que
sepan cmo llamar por telfono y conozcan los prefijos internacionales.
A este sencillo modelo de comunicaciones se le pueden aadir ms capas. Para
incorporar una nueva, podemos imaginar que ambos hablantes no hablan esperanto y
que cada uno se comunica mediante un intrprete que sabe esperanto y el idioma del
hablante con que est. Entonces, se habra aadido una nueva capa (intrprete) sin
modificar el nmero de protocolos. La escena descrita resulta enrevesada no lo
negar; pero situaciones mucho ms extraas se han visto en la apasionante historia
de las redes de comunicaciones.
Otro ejemplo de arquitectura de capas en procesos de telecomunicaciones nos lo
proporciona la propia historia: una situacin habitual en el Pars ocupado por los
alemanes en la II Guerra Mundial era la del espa sovitico que transmita a Mosc un
mensaje cifrado con un libro de claves (libro de una vez), mediante radiotransmisiones
de onda larga en cdigo Morse. Se sola usar la banda de treinta y nueve metros para
recibir, y la de cuarenta y nueve para emitir. En Mosc se descifraba el mensaje con el
libro de claves complementario del anterior y se diriga a quien correspondiera. Una vez
ledo, se enviaba un mensaje de respuesta al emisor, tambin cifrado con un libro de
claves. En la siguiente figura se muestra una versin simplificada de la arquitectura de
comunicaciones resultante (no considero ningn problema derivado del uso de distintas
lenguas).
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 28/313 -
Figura 10. Transmitiendo desde la Francia ocupada
El proceso mostrado en la figura 10 es simple: el espa parisiense redactaba su
informe; el tcnico en claves lo cifraba en una secuencia alfanumrica; y el telegrafista
converta el mensaje cifrado en rayas y puntos Morse y lo enviaba a Mosc mediante
telegrafa sin hilos. Si la capa Heaviside tena a bien no convertir el mensaje en ruido
esttico o en un manojo de interferencias incordiantes, un proceso similar pero inverso
se llevaba a cabo en Mosc: un telegrafista reciba el cdigo Morse y lo transcriba a un
documento; un tcnico en claves descifraba el documento, y un agente del espionaje
sovitico lo interpretaba. Para no faltar a la verdad, he de decir que los papeles de
espa, tcnico en claves y telegrafista solan recaer en una misma persona; aqu
considero que haba una persona distinta para desempear cada papel.
Al igual que el ejemplo anterior, ste nos manifiesta ya la encapsulacin de las
capas: el espa no tena por qu saber nada de cifrado ni de cdigo Morse; el
especialista en claves no necesitaba conocer nada sobre tcnicas de espionaje o
telegrafa sin hilos; y el telegrafista no tena por qu saber nada de claves ni de
espionaje. Por otro lado, el espa en Mosc tampoco necesitaba saber nada acerca de
cmo haba llegado el mensaje a sus manos: slo necesitaba evaluar su veracidad y
formular una respuesta. A todos los efectos, todo suceda como si se comunicaran
directamente el espa parisiense y el ruso. En todo modelo de capas, aunque la
comunicacin real se realiza verticalmente, todo sucede como si se realizara
horizontalmente.
Espa
Tcnico
en claves
Telegrafista
Espa
Tcnico
en claves
Una arquitectura de comunicaciones
Miguel ngel Abin, Marzo 2004
AXh782R3XVjY
Transmitiendo desde Pars
Secuencia Morse
Ruso
Libro de claves
Codificacin Morse
Telegrafista
Telgrafo
sin hilos
Telgrafo
sin hilos
Secuencia pulsos em
Oscilaciones campo
electromagntico
pulsos elctricos pulsos elctricos
pulsos em
[Link]
Miguel ngel Abin, Julio 2004 - 29/313 -
La arquitectura TCP/IP (en el sentido de conjunto de capas y protocolos) consta
de cuatro capas:
Capa de enlace. Suele incluir la tarjeta de red del ordenador, el
controlador de la tarjeta para el sistema operativo utilizado y el medio de
transmisin utilizado (cable, lser, fibra ptica, radio, etc.). Esta capa
describe las caractersticas fsicas del medio de transmisin, gestiona las
conexiones fsicas, proporciona la transmisin fsica de los datos
(cadenas de bits) a travs del medio usado y se encarga de manejar
todos los detalles del hardware que interacciona con el medio de
transporte de los datos. Asimismo, se encarga de especificar cmo han
de transportarse los paquetes de datos por el medio de transmisin.
Dicha especificacin incluye obligatoriamente el entramado (framing): la
manera como se especifica el comienzo y el fin de los paquetes. Por
ejemplo, una de las funciones de esta capa consiste en transformar una
secuencia de bits en una seal elctrica, en un modo de una fibra ptica,
en ondas electromagnticas, etc. Esta capa admite muchos protocolos
alternativos (ATM, Ethernet, Token ring, etc.).
Capa de red (tambin conocida como capa IP). Permite que se
transmitan datos entre mquinas de una red basada en TCP/IP,
independientemente de la naturaleza de las redes por las cuales pase la
informacin. Los datos se encaminan hacia su destino por medio de esta
capa. IP es su protocolo ms conocido.
Capa de transporte. Proporciona servicios de entrega de los datos
desde el origen al destino. Los dos protocolos dentro de TCP/IP que
suelen implementar esta capa son TCP (Transmission Control Protocol:
protocolo de control de la transmisin) y UDP (User Datagram Protocol:
protocolo de datagramas del usuario).
Capa de aplicacin. Proporciona toda la lgica correspondiente a las
aplicaciones para los usuarios. Los protocolos que implementan esta
capa se encargan de definir las condiciones exactas para solicitar y
recibir servicios, y de proporcionar interfaces para los usuarios. Los
protocolos ms conocidos de esta capa son HTTP (HyperText Transfer
Protocol: protocolo de transferencia de hipertexto), Telnet, FTP (File
Transfer Protocol: protocolo de transferencia de archivos), SMTP (Simple
Curiosidad: El mtodo de transmisin de informacin cifrada
descrito arriba no es tan arcaico como podra uno pensar.
Tambin fue usado por muchos espas de la extinta RDA en el
Berln de los aos sesenta y setenta, as como por agentes
occidentales infiltrados en pases tras el Teln de Acero.
En Espaa hay constancia de que existieron transmisiones de
ese tipo en los aos sesenta y setenta (se supone que
procedan de espas soviticos, pero nunca hubo comunicados
oficiales). Hace siete aos, pude ver en el INTA (Instituto
Nacional de Tcnica Aeroespacial) los coches con antenas
que se usaban en Madrid para localizar los focos de las
transmisiones.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 30/313 -
Mail Transfer Protocol: protocolo de transferencia de correo simple),
Kerberos, DNS (Domain Name System: sistema de nombres de dominio)
e ICMP (Internet Control Message Protocol: protocolo de mensajes de
control de Internet).
Figura 11. Las capas de la arquitectura TCP/IP
Algunos autores sostienen que la capa de enlace debera manejar slo los
detalles del hardware que interacciona con el medio fsico de transporte de los datos:
niveles de voltaje, sincronizacin de cambios de voltaje, distancia entre cables, etc.; no
los detalles del medio fsico. Si se acepta esta idea, debe incluirse una nueva capa en
el modelo: la capa fsica, encargada de transmitir los datos en un medio fsico. As, un
mdem o una tarjeta de red realizaran funciones en la capa de enlace y en la fsica,
pues transforman secuencias de bits en seales normalizadas que pueden transmitirse
mediante un medio fsico, y gestionan la activacin y desactivacin de la conexin
fsica.
Si se incorpora la capa fsica al modelo TCP/IP de cuatro capas, el reparto de
funciones entre la capa fsica y la de enlace queda as:
a) Capa fsica. Se encarga de convertir las secuencias de bits en seales
fsicas y de transmitirlas al medio fsico; para ello, define la
representacin de los bits en estados fsicos (medio de transmisin,
asignacin de voltaje a ceros y unos, definicin del tiempo asignado a
cada bit, definicin de establecimiento de conexin y de su fin, etc.).
b) Capa de enlace. Define las tramas (tamao, secuencia de bits para el
comienzo y el fin). En la mquina emisora, la capa de enlace
descompone los datos procedentes de capas ms altas en secuencias
de tramas y enva las tramas a la capa fsica en forma de secuencias de
bits. En la mquina receptora, recibe secuencia de bits de la capa fsica,
Capas de la arquitectura TCP/IP
Aplicaciones de software que trabajan sobre la red
Servicios de entrega de datos entre mquinas
Define los datagramas y controla su encaminamiento
Maneja el hardware necesario para estar en red
Miguel ngel Abin, Marzo 2004
Capa de aplicacin
Capa de transporte
Capa de red
Capa de enlace
[Link]
Miguel ngel Abin, Julio 2004 - 31/313 -
las traduce en tramas comprobando tambin si son tramas vlidas y
enva tramas de correcta recepcin a la mquina emisora.
TCP/IP funciona sobre el concepto de modelo cliente-servidor. Suele usarse el
tmino servidor para significar una aplicacin (o proceso) que se ejecuta en una
mquina en red (o en varias) y realiza dos funciones: a) acepta peticiones de procesos
que se ejecutan en otras mquinas en red; y b) contesta a dichas peticiones
proporcionndoles un servicio. Los procesos que realizan las peticiones se llaman
clientes. Por regla general, los clientes son activos (hacen solicitudes) y los servidores
pasivos (esperan solicitudes). Su tiempo de vida no coincide: los clientes dejan de
ejecutarse cuando se paran las aplicaciones de las cuales forman parte; los servidores
se ejecutan de forma continua. Una aplicacin cliente-servidor admite la divisin en
dos o ms procesos donde cada uno es cliente o servidor. Esta separacin es lgica,
no fsica: una aplicacin cliente-servidor puede ejecutarse en una mquina (con sendos
procesos para el cliente y el servidor) o en anfitriones separados por miles de
kilmetros. En una aplicacin en red, resulta habitual que a la separacin lgica le
corresponda una fsica.
La distincin entre clientes y servidores no siempre resulta tan clara como la
presento. Un servidor puede actuar como servidor para un proceso y como cliente para
otro. As, por ejemplo, un servidor que necesite consultar a otro para ofrecer su servicio
a los clientes ser cliente para el segundo. Para este tutorial, usar cliente y servidor
para designar los papeles mutuos desempeados en una sola comunicacin.
Las palabras cliente y servidor tambin suelen usarse para referirse a los
anfitriones o nodos en los que se ejecutan procesos de uno u otro tipo.
Una clasificacin muy extendida de los modelos cliente-servidor es sta:
- Modelos cliente-servidor de presentacin descentralizada. La
presentacin (gestin de la interaccin con el usuario, grficos, etc.)
corre a cuenta del cliente. El servidor gestiona la lgica de la
aplicacin (o reglas de negocio) y los datos. En un sistema bancario,
por ejemplo, una regla de negocio puede ser No se permite sacar
dinero de cuentas con saldos negativos.
- Modelos cliente-servidor de lgica distribuida. El cliente se
encarga de la presentacin y de parte de la lgica de la aplicacin; el
servidor se encarga del resto de la lgica de la aplicacin y de todos
los datos. Por ejemplo, en un sistema bancario de lgica distribuida,
los clientes pueden encargarse de avisar de la introduccin de valores
invlidos: cdigos de cuenta incompletos, cdigos fiscales errneos,
etc.
- Modelos cliente-servidor de lgico descentralizada. En el cliente
reside la presentacin y toda la lgica de la aplicacin. El servidor slo
se encarga de los datos; viene a ser un almacn de datos.
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.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 32/313 -
Figura 12a. Ejemplo de aplicacin cliente-servidor: la Web
Figura 12b. Otra vista de la figura 12a
Cliente
Navegador
web
Servidor
web
Lgica de la
aplicacin
Bases de
datos
Internet
EL MODELO CLIENTE-SERVIDOR EN LA WEB
Pginas
web
(HTML)
CGI
[Link]
Miguel ngel Abin, Julio 2004 - 33/313 -
2.4. TCP/IP: Un conjunto de protocolos
Tal como se dijo al principio del subapartado 2.2, las siglas TCP/IP se usan
tambin para designar un conjunto o familia de protocolos (IP, TCP, UDP, Telnet,
FTP, Telnet, etc.), correspondientes a las capas vistas en el subapartado 2.3.
Ya se adelant en 2.3 que los protocolos son posibles modos de funcionamiento
de una capa. En la capa de transporte, por ejemplo, existen dos protocolos (UDP y
TCP) que definen dos formas alternativas de funcionamiento (con conexin o sin ella).
Donde ms protocolos alternativos existen es en la capa de aplicacin; dependiendo
del tipo de servicio que precise el usuario, se usar uno u otro. La navegacin por
Internet se hace posible gracias al protocolo HTTP, que no forma parte del paquete
estndar de protocolos TCP/IP. Protocolos ms veteranos, como Telnet o FTP, s se
incluyen siempre en este conjunto de protocolos.
La unin de las capas vistas en 2.3 con los protocolos que se vern en este
apartado forma una completa arquitectura de comunicaciones, mostrada en la figura
13.
Figura 13. La arquitectura TCP/IP: un conjunto de capas y protocolos
FFDI Token
ring
Ethernet
IP
UDP TCP
Capa de
aplicacin
Capa de
transporte
Capa de
red
Capa de
enlace
DNS SMTP HTTP Kerberos
Telnet FTP
FFDI Token
ring
Ethernet
IP
UDP TCP
Capa de
aplicacin
Capa de
transporte
Capa de
red
Capa de
enlace
DNS SMTP HTTP Kerberos
Telnet FTP
DNS SMTP HTTP Kerberos
Telnet FTP
Protocolos
aaa
aaa
a
Capas
LA ARQUITECTURA TCP/IP COMPLETA (4 CAPAS)
Miguel ngel Abin, Abril 2004
ARP
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 34/313 -
En la figura 14 se muestra cmo encaja el protocolo de aplicaciones HTTP en la
arquitectura TCP/IP (supongo que la red fsica corresponde al tipo Ethernet):
Figura 14. El ejemplo de la figura 12 desde un punto de vista arquitectnico.
El protocolo IP es el protocolo de red utilizado para enviar datos entre los
ordenadores conectados a Internet o que forman parte de intranets o extranets. Es la
piedra angular sobre la cual se sostiene el catico edificio que es aparentemente
Internet; pues los paquetes de datos contienen paquetes IP o datagramas, es decir,
paquetes con la forma definida por este protocolo. Simplificando un poco, este
protocolo realiza tres funciones bsicas:
Define el datagrama, el paquete atmico de informacin en la capa de
red de cualquier arquitectura TCP/IP (Internet es la red TCP/IP ms
grande que existe).
Define el esquema de direcciones (IP) de las redes TCP/IP.
Se encarga de trasladar los datos entre la capa de enlace y la de
transporte.
Controla el proceso de fragmentacin y ensamblado de los
datagramas. Ninguna red puede transmitir tramas de tamao ilimitado:
todas tienen una unidad de transferencia mxima (Maximum transfer
unit o MTU) que define el tamao mximo de las tramas que pueden
ser enviadas a travs de una red fsica dada. Si un datagrama no cabe
Cliente
Web
TCP
IP
Driver
Ethernet
Servidor
web
TCP
IP
Driver
Ethernet
Flujo real de datos entre cliente y servidor
Ethernet (red fsica)
Cliente
Web
TCP
IP
Driver
Ethernet
Servidor
web
TCP
IP
Driver
Ethernet
Flujo real de datos entre cliente y servidor
Ethernet (red fsica)
Procesos
del sistema
operativo
Proceso
de
usuario
Protocolo HTTP
Protocolo TCP
Protocolo IP
Protocolo Ethernet
Acceso a una pgina web desde la perspectiva de la
arquitectura TCP/IP
Capa de
aplicacin
Capa de
transporte
Capa de red
Capa de enlace
Miguel ngel Abin, Marzo 2004
[Link]
Miguel ngel Abin, Julio 2004 - 35/313 -
dentro de una trama fsica, este protocolo especifica cmo ha de
dividirse y cmo los fragmentos han de ensamblarse en el destino.
Figura 15. Esquema de un datagrama, el tomo lgico de Internet
Los datagramas (a veces se llaman datagramas IP) son paquetes de datos,
definidos por el protocolo IP. Todo datagrama cuenta con un origen y un destino; pero
no existe conexin: no hay dos extremos en la comunicacin. Asimismo, es
independiente de los enviados antes o despus de l. En ocasiones, un datagrama
debe divididirse en otros de menor tamao; esta situacin resulta corriente cuando se
intentan pasar datagramas entre subredes fsicas muy distintas. Bsicamente, todo
datagrama consta de dos partes: datos y cabecera (donde figura la fuente, el destino y
el tipo de datos que contiene).
IP es un protocolo sin conexin y sin fiabilidad. Sin conexin, porque no
incorpora ningn mecanismo para intercambiar informacin de control antes de enviar
datos a una mquina receptora ni mantiene informacin de estado entre datagramas
sucesivos (cada uno se maneja independientemente de los otros, y pueden alcanzar su
destino en un orden distinto al de salida). Sin fiabilidad, porque no existe garanta de
que un datagrama llegue correctamente a su destino: no se encarga de reenviar los
paquetes perdidos o defectuosos (suele llamarse chernobylgram Chernobyl
datagram a aquel paquete tan defectuoso que causa la fundicin de la mquina
receptora es decir, que la deja fuera de funcionamiento; los creadores de protocolos
Esquema de un datagrama
IHL Tipo de servicio
Flags
Longitud total
Offset de fragmentacin
Versin
Datos 1
Relleno
Identificacin
Tiempo de vida
Direccin IP origen
Direccin IP destino
Opciones
Espacio donde comienzan los datos
N de protocolo Comprobacin de la cabecera
Datos 2
OAR - Universidad Nacional de Colombia - 1999 OAR - Universidad Nacional de Colombia - 1999
Cabecera
Miguel ngel Abin, Marzo 2004
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 36/313 -
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, [Link]).
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, [Link])
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
[Link]
Miguel ngel Abin, Julio 2004 - 37/313 -
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:
Mensajes, para la capa de aplicacin.
Segmentos (TCP o UDP), para la capa de transporte.
Datagramas, para la capa de red o IP.
Tramas, para la capa de enlace.
Tramas fsicas, para la capa fsica.
Ms adelante, usar todos estos trminos para mostrar el proceso completo de
transmisin de datos con el protocolo UDP.
Para ilustrar cmo se transmite fsicamente la informacin entre redes TCP/IP,
considerar un caso muy sencillo: la solicitud de una pgina web. No olvidemos que
Internet es una red compuesta por subredes sumamente heterogneas,
interconectadas unas con otras mediante encaminadores (routers). Cuando el
usuario hace su peticin mediante un navegador, su peticin se va encapsulando (el
proceso se muestra en la figura 16; se aade una cabecera por cada capa) hasta que
acaba en una trama (un datagrama encapsulado, listo para ser transmitido por un
medio fsico), la cual se enva a la subred local transformada en una seal fsica (una
onda elctrica portadora, un modo no evanescente de una fibra ptica, una onda
electromagntica, etc.), llamada trama fsica. La subred local dirige la trama fsica hacia
Internet mediante su encaminador.
Una vez cruzada el encaminador de la subred emisora, la trama fsica va de
encaminador en encaminador a travs de Internet hasta que pueda entregarse de
forma directa. Cada vez que la trama llega a un encaminador, suceden dos hechos
claramente diferenciados: a) el hardware convierte la trama fsica en una trama; b)
luego, el software IP extrae el datagrama encapsulado dentro de la trama, selecciona el
siguiente encaminador en algn camino hacia la mquina de destino, y lo enva a
travs de alguna subred a la que tenga acceso directo, transformndolo antes en una
trama fsica adaptada a la nueva subred subyacente.
Cuando se da el caso de que un encaminador tiene la mquina de destino en
alguna de sus subredes, ste enva la trama fsica a la mquina correspondiente. En
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 38/313 -
esta ltima se llevan a cabo dos procesos: a) la capa de enlace (hardware y
controladores) transforma la trama fsica en una trama; b) a continuacin, la trama pasa
por las tres capas superiores; c) finalmente, la capa de aplicacin se encarga de pasar
el mensaje contenido en el datagrama encapsulado a la aplicacin adecuada (servidor
web), que enviar el archivo HTML solicitado hacia la mquina que hizo la peticin. La
situacin se representa en la figura 17.
En todo lo dicho en el prrafo anterior se sobreentiende que la mquina a la que
se solicita la pgina no forma parte de la subred a la que pertenece la mquina cliente,
pues si as fuera no se necesitaran encaminadores: la entrega sera directa. De hecho,
ni siquiera sera necesario usar el protocolo IP, pues el direccionamiento fsico de los
nmeros de las tarjetas de red bastara para entregar correctamente la peticin.
Cmo sabe un encaminador si la trama va destinada a sus subredes? El
datagrama dentro de la trama tiene una cabecera en la que consta cul es su destino,
que es examinada por cada encaminador. Si la mquina de destino que figura en la
cabecera no pertenece a ninguna mquina de las subredes correspondientes al
encaminador, ste enva la trama de vuelta a Internet, hacia otros encaminadores. La
comprobacin de la cabecera no se hace en la capa de aplicacin sera como pagar
una carta contra reembolso sin comprobar que el mensaje es para uno, sino en la
capa de enlace.
Hilando fino, uno podra preguntarse cmo sabe un encaminador si la mquina de
destino pertenece a sus subredes. La respuesta reside en que todas las direcciones IP
de las mquinas dentro de una misma red incluyen un prefijo comn (una secuencia de
dgitos), tal como ya se dijo antes. En consecuencia, el encaminador slo tiene que
mirar la direccin IP del datagrama encapsulado y comparar el prefijo de sta con los
de sus subredes.
Nota: Cuando en una comunicacin han intervenido
encaminadores, la capa de red de la mquina receptora no recibe
exactamente el mismo objeto enviado por la correspondiente capa
de red de la mquina emisora. Lo usual es que se modifique
algn campo de la cabecera. Para la capa de transporte y la de
aplicacin se cumple a rajatabla la identidad entre lo emitido y lo
transmitido.
[Link]
Miguel ngel Abin, Julio 2004 - 39/313 -
Figura 16. Encapsulacin de datos en una sesin HTTP
Los encaminadores no se limitan a enviar paquetes de un lado para otro; tambin
se encargan de escoger las mejores rutas o caminos para ellos (entindase por "mejor
camino" el ms rpido). Para ello, cada encaminador mantiene actualizada una tabla de
encaminamiento (routing table) que registra las mejores rutas para ciertos destinos de
la red. Para saber que una ruta es mejor que otras se usan algoritmos que involucran
factores como el trfico de la red, el ancho de banda, la fiabilidad, etc. Como puede
suponerse, las tablas de encaminamiento se van actualizando regularmente (los
parmetros anteriores varan con el tiempo); de esto se encargan los protocolos de
enrutamiento: OSPF (Open Shortest Path First), BGP (Border Gateway Protocol), etc.
Cuando el encaminador (o parte de l) es un ordenador, no se necesita
obligatoriamente que sea un equipo con grandes prestaciones (memoria,
microprocesador, etc.). Un encaminador no guarda informacin sobre las mquinas
dentro de las redes a las que se haya conectado, slo sobre las subredes dentro de
estas redes. En consecuencia, la informacin que necesita guardar depende del
nmero de subredes dentro de cada red a la que est conectado, no del nmero de
ordenadores de las redes. Un encaminador no utiliza directamente el nodo de destino
cuando encamina una trama, slo la red de destino.
En media, cada vez que se enva un correo electrnico o se solicita una pgina
web, los datagramas asociados atraviesan entre diez y veinte redes. Un datagrama
suele tardar unos seiscientos milisegundos en cruzar veinte redes (es decir, veinte
Capa de enlacee
Capa de red
Capa de transporte
Capa de aplicacin
Capa de enlacee
Capa de red
Capa de transporte
Capa de aplicacin
Encapsulacin progresiva de los datos
transmitidos
Datos
Cabecera Datos
Datos Datos Cabecera
Datos Datos Datos Cabecera
Miguel ngel Abin, Marzo 2004
Frame
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 40/313 -
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.
Figura 17. Esquema de la transmisin fsica de datos en Internet
Cualquier usuario de un ordenador sabe que puede ejecutar varios procesos al
mismo tiempo. Por ejemplo, no es raro que se consulten a la vez distintas pginas web
y se use a la vez alguna aplicacin cliente de correo. Se puede, en consecuencia,
intercambiar informacin con ms de un anfitrin a la vez. La ejecucin simultnea de
distintos procesos en una misma mquina resulta posible gracias a los puertos, que
permiten distinguir entre distintos procesos que se ejecutan en la misma mquina. Un
puerto es una abstraccin lgica, pues no corresponde a ningn objeto del mundo real
(no tiene ninguna relacin con un puerto paralelo para impresoras, que s es algo
tangible). Igual que un anfitrin se identifica de forma nica por su direccin IP, un
Capa de aplicacin
Capa de transporte
Capa de red
Capa de enlace
Capa de aplicacin
Capa de transporte
Capa de red
Capa de enlace
Mquina origen
Mquina destino
Subred Subred
Router Router
INTERNET
INTERNET
Miguel ngel Abin, Marzo 2004
Transmisin de datos en Internet
[Link]
Miguel ngel Abin, Julio 2004 - 41/313 -
proceso se identifica de forma nica por la direccin IP de la mquina donde se ejecuta
y por el nmero de puerto que tiene asociado. Mediante el uso de puertos, los
protocolos TCP Y UDP usan una capa extra de abstraccin sobre la capa de red.
Al igual que el protocolo IP permite la comunicacin entre ordenadores de Internet
(o de una extranet o intranet), los puertos permiten la comunicacin entre programas o
aplicaciones especficas genricamente, entre procesos que se ejecutan en aquellos
ordenadores. Cuando un datagrama atraviesa Internet, lleva en su interior la direccin
IP del sistema que lo gener y el puerto del sistema local al que est ligado. Los
encaminadores que mueven datagramas entre redes no leen ni manipulan la
informacin relacionada con el puerto; la mquina de destino es la nica que emplea
esta informacin.
Cuando se considera una arquitectura cliente-servidor (por ejemplo, el ejemplo
anterior del servidor web y el navegador cliente), el programa servidor permanece a la
escucha de peticiones por parte de los clientes a travs de los puertos que tiene
activos. Las informaciones solicitadas se envan a los clientes mediante los puertos que
stos han utilizado para realizar las peticiones. En general, los servicios ms conocidos
de Internet tienen asignados puertos por defecto. Por ejemplo, el protocolo HTTP utiliza
el puerto estndar 80, y el protocolo FTP el puerto estndar 21. Por ello no es preciso
escribir en un navegador [Link] basta con escribir
[Link]
Es posible utilizar puertos distintos de los estndar para los servicios de Internet,
si bien no es habitual. Se podra perfectamente, por ejemplo, asignar el puerto 2378 al
protocolo HTTP y el puerto 3216 al protocolo FTP. Los clientes necesitaran, para
intercambiar datos con el servidor, conocer los nuevos puertos asociados a cada
servicio.
Figura 18. Un servidor proporciona distintos servicios mediante distintos puertos
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 42/313 -
Figura 19. Ejemplo de peticiones simultneas por distintos puertos
En la siguiente tabla aparecen los puertos asociados a los servicios ms
habituales de la capa de aplicacin en una arquitectura TCP/IP:
Servicio Nmero Puerto
Canal de datos FTP 20
Canal de control FTP 21
Telnet 23
Simple Mail Transfer 25
Gopher 70
Finger 79
Hipertexto (HTTP) 80
USENET 119
Figura 20. Ejemplo de algunos puertos y servicios populares
Existen dos protocolos de transporte (TCP y UDP) en la arquitectura TCP/IP que
se encargan de enviar datos de un puerto a otro para hacer posible la comunicacin
entre aplicaciones o programas.
Mediante la identificacin mediante IP y nmeros de puerto, el
servidor sabe quaplicacinde un cliente solicita un determinado
servicio.
TCP: 1335
TCP: 1336
TCP: 23
TCP: 80
Servicio
Telnet
Servicio
HTTP
Ejemplo de peticiones simultneas por distintos puertos
[Link]
Miguel ngel Abin, Julio 2004 - 43/313 -
El protocolo TCP (Transmission Control Protocol: protocolo de control de la
transmisin) ofrece tres caractersticas fundamentales:
Tolerancia a fallos (fiabilidad). Las transmisiones de datos mediante
TCP se dividen en segmentos; si se pierden o resultan daados, el
protocolo lo detecta y se encarga de volver a transmitir los segmentos
que faltan o que llegaron incompletos.
Manejo de corrientes continuas de datos. Una vez establecida una
conexin, el protocolo permite que los datos se transmitan de forma
continua.
Orientacin a la conexin. Siempre se transmite informacin de control
antes de comenzar la comunicacin; lo mismo ocurre antes de una
desconexin. Suele usarse la expresin circuito virtual para referirse a
las comunicaciones entre las dos mquinas finales.
TCP funciona as: cuando la capa de aplicacin enva un flujo (stream) de bytes
que corresponden a una peticin, el flujo se convierte en una sucesin segmentos,
cada uno con un tamao mximo de 64 K (muchas veces se usan 1.500 bytes). A cada
paquete se le aade una cabecera (que incluye un checksum, adems de una
secuencia numrica si la peticin consta de ms de un paquete). Luego, cada uno se
enva a la capa de red, junto con la direccin IP de destino y el nmero de puerto,
donde se transforma en un datagrama.
Cuando los datagramas lleguen a su destino, transmitidos dentro de tramas
fsicas, sern entregados a un proceso TCP, que reconstruir el flujo original de bytes
enviados por la mquina origen o fuente.
La transmisin de datos mediante este protocolo es asncrona: existe un retraso
voluntario en las transmisiones. Cada vez que se enva un paquete, se tarda un tiempo
en enviar el siguiente. Este tiempo basta para que el paquete de datos llegue a la
aplicacin TCP en el destino, para que sta enve un mensaje de aceptacin y para
que este mensaje llegue a la mquina origen. En el mensaje de aceptacin se
especifica cul es el prximo paquete esperado por la aplicacin TCP del destino. Si el
tiempo se acaba sin que se haya recibido ningn mensaje de aceptacin, la mquina
emisora reenva el paquete. Gracias a este mecanismo de espera, pueden
conseguirse comunicaciones fiables a partir de un protocolo base
intrnsecamente falto de fiabilidad (IP).
Vemos, pues, que la vida del mensajero de la pgina 37 es limitada: dispone de
un tiempo lmite para alcanzar su destino y entregar su mensaje; es como si viajara con
un cronmetro que ha comenzado su cuenta atrs. Si no puede entregarlo en dicho
tiempo, es sustituido por otro mensajero idntico a l, y as sucesivamente. La travesa
del primer viajero no tiene por qu coincidir con la del segundo o con la de cualquier
otro que lo sustituya. En el tiempo transcurrido entre el comienzo del viaje de uno y el
Nota: Un checksum es un nmero que se calcula usando un
algoritmo sobre los datos que enva una mquina. Cuando son
recibidos por la mquina destino, se vuelve a aplicar otra vez
el algoritmo. Si el nmero obtenido a partir de los datos
recibidos coincide con el inicial, se considera que los datos se
han recibido correctamente.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 44/313 -
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.
Por completitud, a continuacin detallo la secuencia exacta de pasos que realiza
cualquier proceso que utilice TCP (se omite cualquier detalle relativo a los pasos
intermedios de encaminamiento de los paquetes, ya vistos en la pgina 37):
1) La capa de aplicacin de la mquina emisora transforma la peticin del
proceso de usuario en un flujo de bytes (mensaje) que transfiere a la
capa de transporte.
2) La capa de tranporte trocea el flujo en segmentos TCP y aade una
cabecera a cada segmento TCP, la cual contiene el checksum del
segmento y un nmero de secuencia. Acto seguido, los segmentos TCP
se pasan a la capa de red.
3) La capa de red crea un datagrama a partir de cada segmento que recibe
de la capa de tranporte. El rea de datos del datagrama contiene los
datos del segmento; la cabecera lleva las direcciones IP de la mquina
de origen y de la mquina de destino, adems de un nuevo checksum.
Esta capa tambin determina la direccin fsica (direccin MAC o
Ethernet en una red Ethernet) de la mquina de destino o del
encaminador ms prximo. Luego pasa el datagrama a la capa de
enlace.
4) La capa de enlace transforma el datagrama en una trama, colocando los
datos del datagrama en el rea de datos de la trama y aadiendo una
nueva cabecera. En este paso, se reemplazan las direcciones IP por
direcciones fsicas de red. En las redes Ethernet y Token ring se usa
para ello el protocolo ARP (Address Resolution Protocol).
5) La capa fsica transforma la trama en una trama fsica y la enva a la red.
6) Cuando la trama fsica llega a la mquina de destino, la capa de enlace
extrae de ella la trama que contiene. A continuacin, descarta la
cabecera de la trama y transfiere los datos, en forma de datagrama, a la
capa de red.
7) La capa de red calcula el checksum del datagrama. Si no coincide con el
valor que figura en la cabecera, se descarta el datagrama (los datos se
han daado en el trayecto: el mensaje del recadero se ha estropeado);
en este caso, la mquina origen volver a enviarlo al poco tiempo.
8) Si el checksum coincide con el valor en la cabecera, la capa de red
elimina la cabecera IP y enva el segmento TCP resultante a la capa de
transporte.
9) La capa de transporte calcula el checksum del segmento. Si no coincide
con el valor que figura en la cabecera, se descarta el segmento. Si
coincide, se comprueba que el nmero de secuencia es correcto.
10) Si el nmero de secuencia y el checksum del segmento TCP son
correctos, la capa de transporte enva un mensaje de recepcin correcta
[Link]
Miguel ngel Abin, Julio 2004 - 45/313 -
a la mquina de destino y pasa los datos del segmento a la capa de
aplicacin.
11) La capa de aplicacin ensambla en el orden correcto los datos que le
vienen de la capa de transporte, simulando un flujo continuo de bytes.
Los pasos anteriores se reflejan, simplificados, en la figura siguiente. Se considera
una aplicacin cliente-servidor de tipo web que funciona en una red Ethernet, y se
emplea una representacin en cinco capas de la arquitectura TCP/IP.
Figura 21. Representacin de la solicitud de una pgina web a un servidor
Capa de
aplicacin
Capa de
transporte
Capa de
red
Capa de
enlace
Capa
fsica
HTTP
Peticin
TCP
IP
Ethernet
Cliente
Servidor
Peticin HTTP
TCP Peticin HTTP
IP TCP Peticin HTTP
HTTP
Peticin
TCP Peticin HTTP
IP TCP Peticin HTTP
IP TCP Peticin HTTP
Ethernet
Capa
fsica
Capa de
enlace
Capa de
red
Capa de
transporte
Capa de
aplicacin
Mensaje
Segmento
Datagrama
Trama
Trama
fsica
Miguel ngel Abin, Abril 2004
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 46/313 -
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.
Figura 22. Ejemplo tpico de una sesin TCP
El protocolo UDP (User Datagram Protocol), en cambio, ofrece estas otras tres
caractersticas principales:
Carencia de tolerancia a fallos. En este protocolo no hay mecanismos
que adviertan de los errores.
Orientacin a mensajes. Las aplicaciones que lo usan envan mensajes
unitarios (datagramas) de forma discontinua.
Carencia de conexin. Un paquete UDP se puede enviar en cualquier
momento a cualquier destino. Antes de transmitir datos, las aplicaciones
basadas en UDP no comprueban si la aplicacin destino se halla
preparada para recibir los datagramas.
Advertencia: Muchas veces se usan trminos como
conexiones UDP o sesiones UDP. Como no creo que su uso
sea correcto (salvo que se quiera expresar que las
aplicaciones finales simulan conexiones o sesiones), evitar
su uso.
[Link]
Miguel ngel Abin, Julio 2004 - 47/313 -
Desde luego, la comparacin entre TCP y UDP no favorece mucho al ltimo. La
nica ventaja de UDP sobre TCP es la velocidad: la ausencia de comprobaciones hace
que sea mucho ms rpido. Velocidad o seguridad? La respuesta al dilema depende
de las necesidades de cada aplicacin. UDP suele usarse para transmisiones de voz y
de vdeo.
UDP funciona as: cuando la capa de aplicacin enva un flujo (stream) de bytes
que corresponden a una peticin, el flujo se convierte en una sucesin de paquetes o
segmentos que no sobrepasan 64 K de tamao. A cada paquete se le aade una
cabecera, en la cual es optativo el checksum. Luego, cada uno se enva a la capa de
red, junto con la direccin IP de destino y el nmero de puerto, donde se transforma en
un datagrama.
Tanto el protocolo TCP como el UDP utilizan puertos, aunque son distintos para
cada uno; es decir, una aplicacin puede usar simultneamente el puerto nmero 1025
con TCP y otro puerto nmero 1025 con UDP. Una mquina tiene 65.536 puertos UDP
y 65.536 puertos TCP. Los puertos con nmeros inferiores a 1024 suelen reservarse
para procesos del sistema, y no es conveniente usarlos.
En la capa de aplicacin pueden usarse muchos protocolos distintos. Algunos
forman parte de TCP/IP, pues se han incluido en l desde el comienzo (por ejemplo,
Telnet o FTP). Otros son ms recientes, y no se incluyen todava en TCP/IP (as, HTTP
o HTTPS). El protocolo HTTP (HyperText Transfer Protocol: protocolo de transferencia
de hipertexto) proporciona un excelente ejemplo de protocolo popular que no forma
parte de TCP/IP. Para poder usarlo no basta con tener un ordenador donde se haya
configurado y parametrizado TCP/IP: tambin se necesita un navegador (la aplicacin
cliente). Lo cual implica instalar, como mnimo, los dos componentes que ste lleva:
El que implementa el protocolo HTTP.
El que se encarga de la presentacin de las pginas web y de atender los
eventos que genera el usuario (pulsaciones de ratn, pulsacin de teclas,
etc.).
Para cerrar este subapartado, se va a detallar con un ejemplo lo que ocurre,
cindose slo a los protocolos, cuando se accede a una pgina web (el protocolo
HTTP se ver en 2.8.5):
1) En un navegador se escribe esta URL (y se pulsa la tecla
correspondiente para enviar la peticin):
[Link]
2) El protocolo DNS convierte [Link] en la direccin IP
[Link].
3) El protocolo HTTP (recordemos el ht t p inicial), construye un mensaje
GET / ai di ma/ i ndex. ht m, que se enva al anfitrin con IP
[Link].
4) El protocolo TCP (el que usa HTTP) establece una conexin con el
anfitrin con IP [Link], por el puerto 80 (el estndar de HTTP), y
enva el mensaje GET / ai di ma/ i ndex. ht m.
5) El protocolo IP enva los paquetes TCP (en forma de datagramas) al
anfitrin con IP [Link], el cual ha enviado antes a la mquina del
cliente un mensaje de que est disponible para recibir peticiones.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 48/313 -
6) Un protocolo dependiente del medio fsico usado en la red (fibra ptica,
cable coaxial, etc.) codifica los paquetes IP/TCP/HTTP y los enva a la
red en forma de tramas fsicas. Para ello, hay un proceso de
substitucin de la direccin IP [Link] por la correspondiente
direccin fsica de red.
Los retrasos en atender las peticiones de pginas web pueden deberse a muchas
causas: saturacin de las redes, excesivo nmero de peticiones al servidor, ancho de
banda insuficiente, etc. Ahora bien, si uno quiere creer en explicaciones ms esotricas
y, para qu negarlo, ms divertidas le recomiendo la siguiente (extrada de Dave
Barry In Cyberspace), fcilmente extrapolable a muchos pases: Una pgina web
puede tardar un poco en aparecer en su pantalla. La razn para el retraso es que,
cuando escribe una direccin Web, su computadora la pasa a otra computadora, que a
su vez la pasa a otra computadora, y as sucesivamente a travs de cinco
computadores, hasta que finalmente alcanza la estacin de trabajo de un descontento
empleado del Servicio Postal de los Estados Unidos, que la arroja a la basura.
[Link]
Miguel ngel Abin, Julio 2004 - 49/313 -
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.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 50/313 -
El modelo OSI coloca ciertas funciones en la red, de manera que las
aplicaciones no tienen que gestionar ciertos aspectos. En TCP/IP, se
sigue el principio de extremo a extremo : las redes deben
encargarse del menor nmero posible de funciones; deben limitarse a
mover paquetes de un punto a otro, sin analizar su contenido ni
diferenciar entre unos paquetes y otros. En este ltimo modelo, son las
aplicaciones y los ordenadores de los extremos los que deben asumir la
mayor parte de las funciones exigibles (reordenacin de paquetes,
confirmacin de llegada correcta de los paquetes, reenvo de los
paquetes defectuosos, etc.)
El modelo OSI se basa en un concepto un tanto idealista de las redes,
que no corresponde a las redes reales. TCP/IP es totalmente emprico:
surgi de la experiencia sobre redes que ya existan.
El principio de extremo a extremo, que se ver con ms detalle en el siguiente
subapartado, fue una gua para los diseadores de las redes que acabaron dando lugar
a la Internet que hoy conocemos. El acierto de esta decisin de diseo queda fuera de
cualquier duda: la suma de miles de redes individuales, absolutamente heterogneas y
dispares, jams hubiera sido posible si las redes hubiesen tenido que encargarse de
casi todas las funciones necesarias para conseguir comunicaciones fiables. Si Internet
es tan flexible, se debe a este principio de diseo de las redes: los paquetes de datos
pueden enviarse para un conjunto de aplicaciones muy variadas (navegacin por
pginas web, transmisin de audio, de vdeo, realidad virtual, etc.).
Varias han sido la causa del fracaso del modelo OSI frente al TCP/IP. Incluyo aqu
algunas de ellas para que el lector perciba las dificultades inherentes a cualquier
normalizacin:
Complejidad. El modelo OSI es demasiado general. Su especificacin es larga y
densa (para mejorar la legibilidad de la documentacin, la parte que describe la capa
de enlace de datos y la de red tuvo que recurrir a dividirlas en muchas subcapas).
Cuando se aaden al modelo las normas ISO que especifican los protocolos de cada
capa, las cosas empeoran y la documentacin se convierte en algo que nadie querra
cargar sobre su espalda. Cuando le las especificaciones del modelo, hace seis aos,
me llamo la atencin la existencia de subcapas de pega, esto es, subcapas que han
sido incluidas en el modelo para salvar las diferencias entre las caractersticas de
cualquier tipo de red que pueda existir y las que el modelo puede describir. Me
recuerda a las teoras de supercuerdas, cuyo lema parece ser ste: si una teora fsica
no explica todos los fenmenos existentes y concebibles, aumente el nmero de
dimensiones (diez, luego trece) hasta que sea tan general que cubra cualquier
fenmeno que pudiera existir.
Mal momento de aparicin. El modelo OSI se cre cuando los protocolos de red
an se estaban desarrollando y perfeccionando. Como no se orient hacia ninguna
familia de protocolos, se qued en tierra de nadie. Por otro lado, cuando existieron
productos comerciales basado en el modelo OSI, tuvieron que competir con familias de
protocolos mucho ms especficas y que ya llevaban un tiempo en el mercado.
[Link]
Miguel ngel Abin, Julio 2004 - 51/313 -
Falta de adaptacin a la tecnologa de redes. El modelo OSI se centra en las
comunicaciones. Su especificacin dedica un espacio marginal a los problemas
inherentes al software de redes o al software en general. Algunas especificaciones son
perfectas para un mundo de cables, telfonos y transistores, pero resultan sumamente
difciles de implementar en software. Frases como Una entidad quiere responder a un
suceso o Ha llegado la respuesta a una peticin preliminar son demasiado abstractas
como para admitir una rpida implementacin en software.
Abundancia de fallos iniciales. Las primeras implementaciones del modelo OSI
y de los protocolos relacionados tuvieron muchos problemas: se colocaron protocolos
en capas donde no correspondan, se usaron slo protocolos con conexin (lo cual
contrastaba con los protocolos que usaban casi todas las LAN), la capa de enlace slo
era aplicable exactamente a redes de tipo punto a punto, etc. Todos estos problemas
no alentaron el espritu inversor de los clientes en una poca en que el mundo de las
telecomunicaciones andaba muy revuelto (ya saben, se tarda una vida en conseguir
un cliente, pero slo un minuto en perderlo).
Razones polticas y psicolgicas. La tradicional desconfianza estadounidense
hacia las organizaciones extranjeras hizo que el modelo OSI fuera visto como una
imposicin de la Comunidad Econmica Europea y, ms tarde, de la administracin
estadounidense. Si bien es cierto que las compaas telefnicas de varios pases
europeos influyeron en la elaboracin del modelo, tambin lo hicieron compaas
estadounidenses. En Estados Unidos, a finales de los ochenta, el gobierno quiso
imponer de forma obligatoria lo que se conoci como GOSIP (Goverment Open
Systems Interconnect Profile: perfil de interconexiones de sistemas abiertos del
gobierno), que dej de ser obligado en 1995. Como era de esperar, la imposicin por
parte del gobierno estadounidense de una cierta normalizacin se consider como un
recorte de las libertades individuales.
Retrocedamos un poco en el tiempo y situmonos mentalmente en 1985, en la
Universidad de Berkeley (California). Consideremos un investigador que trabaje con
UNIX y con los protocolos TCP/IP. Resulta probable que manifieste un cierto desprecio
hacia la Autoridad. Despus de todo, en los aos sesenta y setenta muchos alumnos y
profesores tomaban drogas psicodlicas; predicaban apasionadamente la revolucin
sexual y poltica, antes de convertirse en ejecutivos de ventas, empresarios o
profesores; y desconfiaban de un gobierno cuyo presidente tena serios problemas con
el alcohol, con los barbitricos y con la verdad (slo lo ltimo acab forzndole a
dimitir).
Cmo se sentira nuestro ficticio investigador ante la mera suposicin de que una
potencia extranjera o el Gobierno de los Estados Unidos est tratando de forzar a los
investigadores a que adopten un modelo forneo? No pensara que se trata de una
injerencia en el poder personal e intransferible de decisin de cada individuo? No
estara dispuesto a sabotear cualquier (supuesto) intento de coartar su derecho a
elegir? Como puede suponerse, el modelo OSI fue un estrepitoso fracaso en las
universidades norteamericanas, que marcaban la pauta en cuanto a investigacin en
redes, y slo ha tenido un tibio xito en algunas compaas telefnicas europeas y
japonesas.
Si el lector consulta algn libro publicado entre 1987 y 1991, puede ser que
encuentre que los autores hablan maravillas del OSI y que lo presentan como una
apuesta segura. Este optimismo se revel infundado: casi nadie lo usa fuera de las
aulas. El modelo OSI presenta ciertas ventajas pedaggicas sobre el modelo TCP/IP
de cuatro capas; pero las ventajas se desvanecen cuando se usa el modelo TCP/IP de
cinco capas (detallado al final de 2.3).
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 52/313 -
La arquitectura TCP/IP no es la Santa Perfeccin Cannica; pero tiene una
ventaja sobre el modelo OSI y sus protocolos asociados que se revel crucial para que
las redes TCP/IP dominen el mercado sin competidores de peso: se desarroll para
que en ella cupieran los protocolos TCP/IP. Por consiguiente, la arquitectura es como
un traje a medida para estos protocolos. Debido a su carcter especfico, no resulta til
para describir familias de protocolos arbitrarios; pero eso no es un problema en un
mundo donde casi todas las redes usan TCP/IP o son compatibles con l.
2.6. El principio de extremo a extremo
El principio de extremo a extremo o de conectividad de extremo a extremo,
mencionado en el subapartado anterior, merece una cierta atencin, pues cualquier
aplicacin basada en la arquitectura TCP/IP lo tiene en cuenta, ya sea de forma directa
o indirecta.
Este principio fue enunciado como tal en el artculo End-to-end arguments in
system design ([Link]
obra de Jerome H. Saltzer, David P. Reed y David D. Clark y publicado en noviembre
de 1984. Este principio establece que
La funcin en cuestin [de una aplicacin en red] puede implementarse
completa y correctamente solamente con el conocimiento y ayuda de las
aplicaciones que permanecen en los extremos del sistema de comunicacin. Por
lo tanto, proporcionar la funcin considerada como una caracterstica del propio
sistema de comunicacin no es posible.
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.
Este principio lleva a modelos de redes tontas y terminales listos, modelos
contrarios a los que predominaban antes de Internet. Seguirlo lleva aparejadas muchas
ventajas:
Los fallos en las redes intermedias no pueden destruir de forma
irrevocable las comunicaciones de extremo a extremo (slo los fallos en
los extremos pueden). En un modelo en que la red se encargue de
muchas funciones (como el reenvo de los paquetes defectuosos, por
ejemplo), un fallo en ella acabar con la comunicacin, pues se perdern
datos y no habr manera de recuperarlos.
Las infraestructuras de las redes son simples: deben ocuparse slo de
entregar los paquetes de la manera ms eficaz posible.
Los paquetes se transportan sin modificacin desde el origen hasta el
destino.
No hay terminales privilegiados: todos son nodos de una red. Tampoco
hay paquetes con privilegios; todos se tratan de la misma forma. El
principio de extremo a extremo implica un principio de no
discriminacin para los nodos y paquetes.
[Link]
Miguel ngel Abin, Julio 2004 - 53/313 -
La escritura de aplicaciones se torna homognea: el programador no
cambia su cdigo cada vez que se cambia de red.
Permite definir arquitecturas independientes de las redes usadas y que
admiten con facilidad nuevos servicios y protocolos.
El principio de extremo a extremo est siendo puesto a prueba durante los
ltimos aos. En la Internet actual hay subredes que lo vulneran. Un ejemplo
interesante de incumplimiento del principio nos lo da NAT.
En el RFC 3022 se describe la tcnica NAT (Network Address Translation:
traduccin de direcciones de red). NAT se propuso para paliar el progresivo
agotamiento de las direcciones IP; es un mecanismo que permite tener en las subredes
direcciones IP repetidas, esto es, direcciones que ya corresponden (o pueden
corresponder) a algn anfitrin de Internet. Mediante esta tcnica se pueden reescribir
las direcciones IP de los paquetes que pasan a travs de un encaminador o un
cortafuegos.
Una red con NAT se conecta mediante uno o ms traductores NAT de
direcciones; en ella, las direcciones IP de los nodos de la red son privadas y no
resultan accesibles directamente desde fuera de la red, por lo que pueden coincidir con
las de otros anfitriones en otras redes de Internet. Cuando un anfitrin de la red que
usa NAT desea acceder a un anfitrin de alguna otra red de Internet, el traductor NAT
manipula los paquetes salientes y convierte la direccin IP del anfitrin emisor (privada
y quizs duplicada) en una direccin IP vlida (nica en Internet). Cuando el anfitrin
de destino conteste la peticin, los paquetes llevarn como direccin de destino la
direccin IP vlida asignada por el traductor NAT. ste se encargar de convertir esa
direccin a la direccin IP privada del anfitrin que hizo la peticin.
Como vemos, NAT modifica el contenido de los paquetes entre el nodo emisor y el
destinatario. En consecuencia, cualquier protocolo TCP/IP que confe en el principio de
extremo a extremo no funcionar correctamente o har que NAT sea inservible. Por
ejemplo, el protocolo IPSEC (IP Security: seguridad IP) se basa en cifrar los bits de los
paquetes. Debido al cifrado, un traductor NAT no puede modificar correctamente los
bits donde se almacena la direccin IP, con lo cual se vuelve intil.
Muchos cortafuegos tambin chocan de frente con el principio de extremo a
extremo. El cifrado de los paquetes basndose en este principio entra en conflicto con
la necesidad que tienen muchos cortafuegos de inspeccionar las direcciones IP de los
paquetes entrantes, con el fin de impedir el paso de paquetes procedentes de
direcciones peligrosas o sospechosas (en realidad, son las personas las peligrosas
o las sospechosas, no las direcciones).
Las amenazas para el principio no acaban ah. En Internet, casi todas las
empresas propietarias de redes tienen acuerdos para permitir un cierto trfico de
paquetes forasteros, esto es, paquetes que no han sido generados en la red que
atraviesan ni tienen como destino ningn nodo de esa red. Pngase en el lugar de una
empresa que tenga redes propias y que ofrezca servicios de Internet mediante
suscripcin. Cmo podr atraer clientes? Pues ofreciendo servicios y contenidos de
calidad (grandes anchos de banda, buenas pelculas, servicios meteorolgicos
actualizados, precios baratos, etc.). Ahora bien, le interesar a esa empresa dar a los
paquetes forasteros el mismo ancho de banda o la misma calidad de servicio que
proporciona a sus suscriptores? No (salvo que cobre por ello). Es pura lgica
comercial: en qu se diferenciara esta empresa de sus competidores si diera a los
clientes de stos la misma calidad que a los suyos? Un ancho de banda grande es una
ventaja comercial slo cuando pocas empresas no lo ofrecen. Sucede como con el
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 54/313 -
dinero: qu privilegios o ventajas dara el dinero si todos lo tuvieran en abundancia?
Como es obvio, una empresa como la descrita carecer de inters en preservar el
principio de no discriminacin, pues tiene un acicate econmico para alterar el
funcionamiento transparente e igualitario de Internet.
Otra amenaza para el sufrido principio de extremo a extremo viene del
ofrecimiento de garantas en la calidad de los servicios de Internet. Garantizar un cierto
ancho de banda en Internet, por ejemplo, no resulta fcil, pues los caminos que siguen
los paquetes varan continuamente. En las aplicaciones crticas (bancarias, mdicas,
etc.) suele ser imprescindible un nivel garantizado de servicio y eficacia. Una manera
de conseguirlo consiste en crear subredes dentro de Internet donde pueda controlarse
y medirse la calidad del servicio, sujetas a la supervisin de terceros. Esta solucin,
pese a ser imprescindible a veces, es contraria al principio de extremo a extremo,
pues implica un trato preferente a ciertos paquetes y un control de los paquetes por
parte de las redes.
Las situaciones expuestas causan que, dentro de Internet, haya islas con
problemas para interoperar con el resto de la red de redes, que sigue el principio de
extremo a extremo. Dos son las principales soluciones para conciliar el devaluado
principio y las necesidades actuales de Internet:
Adoptar la versin nmero seis del protocolo IP (IPv6), la cual
permitir usar un nmero de direcciones IP (2
128
) mucho mayor que
el actual (2
32
).
Establecer protocolos que permitan asignar distintos niveles de
prioridad a distintos flujos de datos. El mayor obstculo a esta
solucin reside en los proveedores de servicios de Internet, poco
interesados en asignar de forma prioritaria recursos a flujos de datos
que no proceden de sus suscriptores.
[Link]
Miguel ngel Abin, Julio 2004 - 55/313 -
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-Write-
Close).
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,
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 56/313 -
write() transfiere datos de un proceso de usuario (emisor) a otro proceso de usuario
(receptor).
La API Socket, como toda API, es un conjunto de declaraciones de funciones o
mtodos, que admite mltiples implementaciones. En todas las distribuciones actuales
de UNIX que la usan se implementa como parte del ncleo del sistema operativo. Casi
todos los sistemas operativos actuales permiten usar sockets. Windows, por ejemplo,
usa la API WinSock (implementada como una biblioteca), mientras que UNIX System V
usa la API TLI (Transport Layer Interface: interfaz de la capa de transporte).
Curiosamente, este ltimo (que en sus primeras implementaciones no admita sockets)
gan la batalla comercial contra UNIX BSD, pero tuvo que adoptar el modelo de
sockets de UNIX BSD y, por ende, su forma de trabajar en red.
2.7.2. Sockets. Tipos de sockets
Los sockets definidos por la API Socket son abstracciones del sistema operativo
que existen mientras se ejecutan aplicaciones de red; pueden usarse para acceder a
distintos protocolos de transporte, no slo a TCP/IP. Por medio de los sockets, los
procesos envan o reciben mensajes. Un socket viene a ser una especie de pasadizo,
residente en el sistema que lo crea, que permite que los procesos de la capa de
aplicacin puedan enviar y recibir mensajes de otros procesos de aplicacin, se
ejecuten o no en la misma mquina. En la figura 23 se muestra dnde se ubicaran
conceptualmente los sockets.
Figura 23. Una abstraccin sobre abstracciones
TCP/IP
Drivers
Mdem / Adaptador de red
Socket
Socket
Socket
Socket
Telnet
FTP
HTTP
E-mail
Semiplano del sistema
operativo
Semiplano de las
aplicaciones para
usuarios
API SOCKET
Miguel ngel Abin, Marzo 2004
[Link]
Miguel ngel Abin, Julio 2004 - 57/313 -
En Thinking in Java 3rd Edition, Bruce Eckel describe as los sockets:
El socket es la abstraccin de software usada para representar los
terminales de una conexin entre dos mquinas. Para una conexin dada, hay
un socket en cada mquina, y puedes imaginar un cable hipottico corriendo
entre las dos mquinas con cada extremo del cable enchufado a un socket.
Desde luego, el hardware fsico y el cableado entre mquinas es completamente
desconocido. El punto fundamental de la abstraccin es que no necesitamos
conocer ms de lo necesario.
Un socket es al sistema de comunicaciones entre procesos lo que el buzn de la
figura 8 al sistema de comunicacin por correo: un punto de comunicacin entre dos
procesos que permiten intercambiar informacin (el envo y la recogida de las cartas,
en el caso del correo; el envo y la recepcin de datos binarios, en el caso de los
sockets).
Desde un punto de vista pragmtico, los sockets son herramientas que permiten
comunicar procesos a travs de Internet, de extranets, de intranets e incluso en
ordenadores aislados.
Figura 24. Ejemplo de conexin cliente-servidor
Hay dos tipos de sockets:
Activos, los cuales estn conectados mediante una conexin
abierta, que puede permitir la transmisin de datos.
Pasivos, los cuales no estn conectados. Por tanto, no pueden
usarse para transmitir datos. Se usan para permanecer a la
espera de peticiones de conexin; cuando reciben una, generan
sockets activos.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 58/313 -
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:
Figura 17. Ejemplo de conexin cliente-servidor
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
Accin Nombre en la API Socket Descripcin
SOCKET socket()
Creacin de un socket
BIND bind()
Asignacin de una
direccin IP a un socket
CLOSE close()
Cierre de la conexin
LISTEN listen()
Declaracin de
aceptacin de
conexiones entrantes
ACCEPT accept()
Espera hasta que llegue
alguna conexin
CONNECT connect()
Intento de establecer
conexin
SEND send()
Envo de datos por
medio de la conexin
RECEIVE recv()
Recepcin de datos por
medio de la conexin
[Link]
Miguel ngel Abin, Julio 2004 - 59/313 -
enviar la informacin (IP de la mquina y puerto al que est ligado) contenida en el
socket del cliente ni en el socket del servidor cada vez que se intercambian flujos de
datos. Dicho de otro modo: como un socket activo en el servidor est conectado a un
socket activo del cliente mientras dura la comunicacin, el primero siempre sabe
adnde enviar sus respuestas. Cuando se habla de conexiones TCP que atraviesan
Internet, un socket es globalmente nico; pues viene caracterizado por cinco datos: el
protocolo usado (FTP, HTTP, etc.), dos direcciones IP (la de la mquina local y la de la
mquina remota) y dos puertos (uno local y otro remoto). Si la comunicacin TCP se
realiza dentro de una red local, el socket es nico en esa red.
Los pasos que se siguen para establecer, mantener y cerrar una conexin TCP se
muestran aqu:
Se crean los sockets en el cliente y el servidor.
El servidor establece el puerto por el que proporcionar el
servicio.
El servidor permanece a la escucha de las peticiones de los
clientes.
Un cliente conecta con el servidor.
El servidor acepta la conexin.
Se realiza el intercambio de datos.
El cliente o el servidor, o ambos, cierran la conexin.
Figura 26. Esquema del uso de los sockets TCP
USO DE LOS SOCKETS TCP
CLIENTE
SERVIDOR
socket()
socket()
bind()
listen()
accept() connect()
Se abre conexin
close()
Peticin del cliente
send()/write()
Respuesta del servidor
close()
recv()/read()
send()/write() recv()/read()
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 60/313 -
Java proporciona clases para la implementacin de sockets, ya sean TCP o UDP.
La interfaz que ofrece Java para la programacin con sockets se basa completamente
en la API Socket de UNIX BSD; pero la ha simplificado ostensiblemente, amn de darle
una buena capa de orientacin a objetos. Por ejemplo, todas las funciones de la figura
25 se obtienen con las clases Socket y Ser ver Socket de [Link], paquete que
se ver en el apartado 8. La explicacin previa de los protocolos UDP y TCP har que
este paquete sea muy sencillo de explicar.
Programar sockets con Java es muy sencillo, mucho ms que usar C (vase el
siguiente subapartado). Internamente, Java usa la JNI (Java Native Interface: interfaz
nativa de Java) para llamar a las bibliotecas en C que implementan las funciones de los
sockets, pero el programador no debe preocuparse de ello.
Para ejemplificar el uso de sockets en Java, en la pgina siguiente se muestra el
cdigo correspondiente a un programa servidor multihilo que enva mediante TCP un
saludo a cada cliente que se le conecta. Si bien los mtodos de Socket y
Ser ver Socket se explicarn detenidamente en el apartado 8, prefiero que el lector
cuyas retinas estn deslumbradas o chamuscadas por la ausencia de cdigo Java en
las primeras cincuenta y nueva hojas pueda ver ya la estrecha relacin entre la API
Socket y algunas clases de [Link], as como la materializacin en este lenguaje de
los pasos arriba expuestos. Una vez ledo el apartado 8, el lector puede volver hacia
atrs y repasar este cdigo. Como puede suponerse, la clase Ser ver Socket
proporciona todo lo necesario para escribir programas servidores en Java: incorpora
mtodos que esperan conexiones por un determinado puerto y mtodos que devuelven
un objeto Socket cuando se recibe una conexin, as como mtodos para recibir y
enviar datos.
Si el programa se ejecuta en la mquina local, para verlo funcionar hay que
ejecutarlo y acceder despus a la direccin [Link] desde un navegador.
Si, en cambio, se ejecuta en una mquina remota ([Link], por ejemplo), se debe
llamar mediante la direccin correspondiente ([Link] siguiendo con el
ejemplo).
[Link]
Miguel ngel Abin, Julio 2004 - 61/313 -
import [Link].*;
import [Link].*;
public class ServidorSaludo {
public static void main(String args[]) throws IOException{
Socket socketCliente = null;
try {
ServerSocket socketServidor = new ServerSocket(9000);
while ( true ) {
socketCliente = [Link]();
Conexion con = new Conexion(socketCliente);
[Link]();
}
} catch (IOException e1) {
[Link]();
}
finally {
try {
[Link]();
} catch (IOException e2) { }
}
}
}
class Conexion extends Thread {
private Socket socketCliente;
private PrintWriter salida;
public Conexion(Socket socketCliente) {
[Link] = socketCliente;
}
public void run() {
try {
salida = new PrintWriter([Link](), true);
[Link]("Bienvenido al servidor");
[Link]();
}
catch (IOException e1) {
[Link]();
}
finally {
try {
[Link]();
} catch (IOException e2) { }
}
}
}
Paquete que permite trabajar
con sockets
Puerto por el que escucha
Socket
pasivo TCP
Espera peticiones
(ACCEPT)
Socket
activo
TCP
Se lanza conexin
Se enva mensaje al cliente (SEND)
Se cierra la conexin (CLOSE)
SOCKET, BIND
y LISTEN
Ejemplo 1: [Link]
Flujo de salida de los datos
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 62/313 -
En este sencillo ejemplo vemos que las clases Ser ver Socket y Socket ofrecen
al programador un I nput St r eamo un Out put St r eam, mediante mtodos como
get Out put St r eam( ) . Las clases I nput St r eam y Out put St r eam, as como
muchas de sus subclases, se explicarn en el apartado 3.
Figura 27. El ejemplo 1 en funcionamiento
Para el programador de Java, un socket TCP es la representacin de una
conexin para la transmisin de informacin entre dos ordenadores distintos o entre un
ordenador y l mismo. Esta abstraccin de alto nivel permite despreocuparse de los
detalles que yacen bajo ella (correspondientes a protocolos subyacentes). En resumen,
un socket TCP permite conectarse a un equipo a travs de un puerto, enviar o recibir
datos y cerrar la conexin establecida.
[Link]
Miguel ngel Abin, Julio 2004 - 63/313 -
Los sockets UDP (tambin conocidos como sockets de datagramas) ofrecen,
entre otras, las funciones que aparecen en la siguiente tabla:
Figura 28. Algunas funciones de los sockets UDP
En el modelo cliente-servidor, al cliente le corresponden las funciones socket(),
sendto()/recvfrom() y close(); al servidor, socket(), bind(), sendto()/recvfrom() y close().
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 UDP, los clientes y los servidores se comunican enviando
paquetes de datos entre los sockets de cada uno, sin que exista conexin. As pues, un
socket del servidor necesita enviar con cada paquete la IP de la mquina cliente y el
nmero de puerto asociado al socket del cliente; lo mismo sucede, mutatis mutandis,
con los sockets del cliente. En caso contrario, los paquetes acabaran en algn
Tringulo de las Bermudas de Internet.
Al no existir conexin, los sockets UDP no son globalmente nicos, a diferencia de
lo que sucede con los de tipo TCP, ya que no existe conexin: siempre se refieren a la
mquina local. Lgicamente, los sockets TCP ocupan ms memoria RAM que los UDP,
pues necesitan mantener ms informacin. Adems, los primeros necesitan reservar
memoria para dos buffers (uno para recibir y otro para transmitir; un buffer es una
memoria de almacenamiento temporal), mientras que los segundos slo necesitan un
buffer para recibir o transmitir.
Accin Nombre en la API Socket Descripcin
SOCKET socket()
Creacin de un socket
BIND bind()
Asignacin de una
direccin IP a un socket
CLOSE close()
Cierre del socket
SEND TO Sendto()
Envo de datos
RECEIVE FROM recvfrom()
Recepcin de datos
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 64/313 -
Figura 29. Esquema del uso de los sockets TCP
En la pgina siguiente aparece el cdigo para una aplicacin cliente-servidor que
devuelve un saludo a cada cliente mediante el protocolo UDP, indicando el puerto por
donde recibe la peticin y la fecha de sta. El comportamiento exacto de las clases
Dat agr amSocket y Dat agr amPacket se explicar en el apartado 8, pero el lector
puede usar lo aprendido sobre sockets y el esquema de la figura 29 para intuir cmo
funcionan. El cdigo del cliente se incluye porque un navegador web no valdra como
cliente UDP, pues el protocolo HTTP usa TCP, no UDP. Por no alargar en exceso el
cdigo, prescindo de usar hilos. Tal y como est escrito, se supone que el servidor y el
cliente se ejecutan en la mquina local. Si la aplicacin de servidor residiera en una
mquina remota, habra que modificar la lnea
I net Addr ess dest i no = I net Addr ess. get ByName( " l ocal host " ) ;
del ejemplo 2b indicando el nombre de la mquina donde se ejecuta el servidor.
socket()
bind()
close()
Peticin del cliente
sendto()
Respuesta del cliente
recvfrom()
socket()
bind()
close()
recvfrom()
sendto()
CLIENTE
USO DE LOS SOCKETS UDP
SERVIDOR
[Link]
Miguel ngel Abin, Julio 2004 - 65/313 -
import [Link].*;
import [Link].*;
public class ServidorSaludoUDP {
private static byte[] buffer;
private static byte[] datos;
public static void main(String args[]) {
try {
DatagramSocket socket = new DatagramSocket(9000);
buffer = new byte[1024];
while( true) {
DatagramPacket datagrama = new DatagramPacket(buffer, [Link]);
[Link](datagrama);
InetAddress hostDestino = [Link]();
int puertoDestino = [Link]();
datos = [Link]();
String cadena = new String(datos, 0, [Link]);
[Link]("Bienvenido al servidor. Envo por el puerto " +
puertoDestino + " el mensaje: " + cadena);
}
}
catch (IOException e) {
[Link]();
}
}
}
import [Link].*;
import [Link].*;
import [Link].*;
public class ClienteUDP {
private byte[] buffer;
private static String cadena = "Enviando datagrama en la fecha: " + new Date();
public static void main(String args[]) {
try {
byte[] buffer = [Link]();
InetAddress destino = [Link]("localhost");
DatagramPacket datagrama = new DatagramPacket(buffer, [Link],
destino, 9000);
DatagramSocket socket = new DatagramSocket();
Socket
activoUDP
SOCKET y BIND
RECEIVE FROM
Puerto por el que escucha
Ejemplo 2a: [Link]
Ejemplo 2b: [Link]
Socket activo
UDP
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 66/313 -
[Link](datagrama);
[Link]();
}
catch (IOException e) {
[Link]();
}
}
}
Figura 30. El cdigo del ejemplo 2 en funcionamiento
CLOSE
SEND TO
[Link]
Miguel ngel Abin, Julio 2004 - 67/313 -
2.7.3. Un ejemplo de sockets en C
Como curiosidad, incluyo aqu el cdigo C correspondiente a un programa servidor
que atiende a un cliente (slo a uno) y le enva un mensaje de bienvenida y otro de
despedida. Es la versin en C del ejemplo 1 (Ser vi dor Sal udo. j ava), pero sin hilos;
el cliente puede ser un simple navegador. Con l, slo pretendo que el lector intuya la
complejidad de la programacin de sockets en C y que pueda comparar ms adelante
con la sencillez y elegancia de Java para las comunicaciones en red.
Desde luego, esta sencillez y elegancia no es gratuita (lo nico que da gratis el
universo es hidrgeno, y algo de helio): Java slo puede trabajar con TCP/IP, mientras
que la API Socket de UNIX BSD y la API TLI pueden funcionar con casi cualquier
protocolo de red. En principio, ello no constituye un gran obstculo: los sockets de Java
funcionan en Internet, en extranets e intranets.
Como mis conocimientos de las bibliotecas en C para redes estn muy apolillados,
no puede garantizar que este cdigo sea todo lo eficaz que podra ser o que aproveche
las caractersticas de las bibliotecas ms recientes de C. Agradecer mucho cualquier
sugerencia de los lectores al respecto.
// Programa servidor TCP escrito en C
// Manda un saludo a cada cliente que se le conecta
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PUERTO 9000 // Puerto por el que se escuchan las peticiones
int main(void) {
// dasocket y nuevodasocket: descriptores de archivo de sockets
// longcliente: almacena el tamao de la direccin del cliente
int dasocket, nuevodasocket, longcliente;
// sockeaddr_in se define en <netinet/in.h>, se usa para representar dir de Internet
//dir_servidor y dir_cliente: direcciones de Internet del servidor y el cliente
struct sockaddr_in dir_servidor, dir_cliente;
// Buffer de 1 K para almacenar caracteres
char buffermensaje[1024];
// Almacena el estado de la conexin.
int estado;
// Se inicializa la estructura dir_servidor, llenando sus campos de ceros
bzero((char *) &dir_servidor, sizeof(dir_servidor));
// Se inicializa el buffer, llenando sus campos de ceros
bzero(buffer, 1024);
// Se crea un socket TCP
dasocket = socket(AF_INET, SOCK_STREAM, 0);
// Se comprueba que se pudo crear
if (dasocket < 0) {
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 68/313 -
perror("No se pudo abrir el socket.");
exit(1);
}
/* Se define la direccin del servidor mediante las lneas siguientes */
// Se establece el tipo de servidor
dir_servidor.sin_family = AF_INET;
// Se establece el orden de los bytes usado en la red
dir_servidor.sin_addr.s_addr = INADDR_ANY;
// Se establece la direccin IP de la mquina
dir_servidor.sin_port = htons(PUERTO);
/* Se asigna el estado del socket */
// bind liga un socket a una direccin. En este caso, la direccin del servidor.
// bind toma tres argumentos: el descriptor de archivo del socket, la direccin a la cual
// est ligada y su tamao.
estado = bind(dasocket, (struct dirsocket *) &dir_servidor, sizeof(dir_servidor))
/* Se comprueba el estado. Si no se ha podido ligar el socket al puerto, bind retorna 1 */
if (estado<0) {
perror("Error al intentar enlazar el socket al servidor.");
exit(1);
}
/* El servidor queda a la espera de sockets entrantes */
// listen toma dos argumentos: el descriptor de archivo del socket y el nmero mximo de
// conexiones que pueden estar en espera mientras el servidor maneja una conexin
// (suele usarse 5).
listen(sockfd,5);
longcliente = sizeof(dir_cliente);
/* El servidor acepta conexiones de los clientes */
// accept paraliza el servidor hasta que llegan conexiones de los clientes. Devuelve un
// nuevo descriptor de archivo, que se usara para intercambiar informacin con el cliente.
nuevodasocket = accept(dasocket, (struct dirsocket *) &dir_cliente, &longcliente);
/* Se comprueba que la conexin es correcta */
if (nuvodasocket < 0) {
perror("No pudo aceptarse la conexin del cliente.");
exit(1);
}
/*Se enva un mensaje de bienvenida al cliente usando write */
if ( write(nuevodasocket, "Bienvenido al servidor", 22) <0 ) {
perror("Problemas de comunicacin con el cliente.");
exit(1);
}
/* Se enva un mensaje de despedida al cliente usando send */
*buffermensaje = El servidor dice adis\n\r;
send(nuevodasocket, buffermensaje, strlen(buffermensaje), 0);
/* Se cierra el socket nuevo */
close(nuevodasocket);
return 0;
}
[Link]
Miguel ngel Abin, Julio 2004 - 69/313 -
2.7.4. Ventajas e inconvenientes de los sockets
Las principales ventajas que ofrecen los sockets se detallan aqu:
Las aplicaciones que los usan son muy rpidas y eficaces. Como los
sockets son entidades de bajo nivel, se comunican rpida y eficazmente
con el sistema operativo e introducen poca sobrecarga en las
aplicaciones.
Son el mecanismo ms difundido para las comunicaciones entre
procesos. Todos los sistemas operativos y lenguajes de programacin
actuales les dan cabida. Escasos son los protocolos de transporte que
no usan sockets.
La otra cara de la moneda nos la dan estos inconvenientes de los sockets:
Son abstracciones de bajo nivel. Por ello, la programacin intensiva con
sockets no resulta muy cmoda para el programador medio. Cuando
uno se ha acostumbrado a mensajes de error del estilo de Conversin
errnea de tipos, El tipo del argumento no corresponde a la definicin
del mtodo o Nmero errneo de argumentos, no entusiasma la idea
de encontrarse con errores como Conexin rechazada, No se
encontr el anfitrin, Puerto ocupado por otro proceso, etc.
El cdigo escrito con sockets depende de la plataforma. Debido al bajo
nivel de los sockets, estn muy ligados a la plataforma donde se
ejecutan.
No permiten el envo directo de argumentos. Es el programador quien
debe encargarse de abrir y cerrar los flujos de E/S y de introducir en
ellos los argumentos que se quieran pasar, as como de extraer los
resultados. Por ejemplo, si se necesita que el cliente enve un
argumento i nt y que el servidor devuelva un doubl e, el programador
debe encargarse de escribir en el cliente el cdigo que introducir el
i nt en un flujo de salida, el cdigo en el servidor que leer el flujo de
entrada y extraer un i nt y el cdigo en el cliente que leer un doubl e
del flujo de entrada enviado por el servidor.
El cdigo con sockets es difcil de reutilizar. Aparte de los problemas
derivados por el bajo nivel de stos, los clientes necesitan conocer la
direccin de la mquina donde se ejecuta el servidor y el nmero de
puerto para acceder a ste. Si el servidor cambia de ubicacin, hay que
recompilar los clientes o, al menos, reconfigurarlos.
No ofrecen metainformacin sobre los servicios de los servidores y sus
localizaciones. No hay mapas que digan El servidor A est en B y
ofrece estos servicios.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 70/313 -
2.8. Algunos servicios de la capa de aplicacin en la arquitectura TCP/IP
2.8.1. Introduccin
Los protocolos de la capa de aplicacin especifican
1) los tipos de mensaje intercambiados (peticiones y respuestas, por
ejemplo);
2) la sintaxis de los posibles mensajes: los campos de stos y sus
formatos;
3) el significado de los campos;
4) las reglas para responder a las peticiones o para enviarlas.
Ninguno de estos protocolos especifica o detalla ninguna implementacin, que
queda libre para los programadores.
En los siguientes subapartados veremos algunos servicios de la capa de
aplicacin, basados en protocolos que nos resultarn tiles cuando estudiemos el
paquete [Link].
2.8.2. El servicio de administracin de redes
En cualquier red, por sencilla que sea, el proceso de administracin resulta
imprescindible para controlar los recursos y compartirlos adecuadamente. El protocolo
SNMP (Simple Network Management Protocol: protocolo de administracin de redes
simples) se basa en UDP. Mediante SNMP, las aplicaciones pueden recopilar
informacin sobre el funcionamiento de los nodos de una red TCP/IP (eficacia,
existencia de problemas, desconexiones, etc.). SNMP simplifica la administracin de
redes mediante el envo de rdenes a travs de las redes, en lugar de mediante
cambios en las configuraciones fsicas de las mquinas.
Este protocolo se estructura en dos partes: el administrador SNMP y los agentes
SNMP. El administrador SNMP es una aplicacin que se ejecuta en la mquina
encargada de administrar la red y que se comunica con los agentes mediante la red.
Los agentes SNMP se ejecutan en los nodos de la red (mquinas, dispositivos
perifricos: impresoras, etc.), en pasarelas, en encaminadores, etc., y mantienen un
registro de su funcionamiento y de su estado actual. Al conjunto de todos los registros
se le llama MIB (Management Information Base: base de informacin de la
administracin). La MIB se divide en grupos que contienen informacin acerca de
distintos aspectos de la red: nombre del dispositivo, nombre de la red, interfaz de la
red, hardware y software de cada nodo, velocidad de trasmisin de los paquetes,
estadsticas de los paquetes enviados y no recibidos, de los datagramas UDP, de las
conexiones TCP en marcha, etc.
La comunicacin siempre se realiza entre el administrador y un agente, pues los
agentes no pueden intercambiar informacin entre ellos. stos emiten respuestas a las
rdenes enviadas por el administrador (lo normal es una respuesta de un agente por
cada orden enviada por el administrador). El protocolo SNMP define el formato de las
rdenes o mandatos, as como el de las respuestas de los agentes.
El uso de UDP es muy conveniente, pues las comunicaciones entre el
administrador y los agentes se basan en peticiones de datos y en respuestas con los
datos solicitados. La falta de fiabilidad de UDP no constituye problema alguno para ese
tipo de comunicaciones. Frente al TCP, UDP no exige el mantenimiento de una
[Link]
Miguel ngel Abin, Julio 2004 - 71/313 -
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.
2.8.3. El servicio de transferencia de archivos
El servicio de transferencia de archivos, basado en el protocolo de aplicacin FTP,
fue uno de los servicios ms populares de Internet. Por regla general, FTP se usa para
transferir archivos entre anfitriones de una red TCP/IP. No obstante, su funcin no
termina ah: permite navegar en los sistemas de archivos de las mquinas local y
remota, as como crear archivos y ficheros en ambas mquinas (si uno cuenta con los
permisos necesarios). En la especificacin del protocolo se destaca que est diseado
principalmente para usarlo dentro de programas; si bien los usuarios pueden utilizarlo
directamente, sin recurrir a programas que ejerzan de interfaz para el protocolo.
FTP define un conjunto de rdenes que se envan como texto US-ASCII. En el
subapartado 3.4 se comentar el estndar de codificacin US-ASCII, as como otros
muchos ms modernos y flexibles; asimismo, se comentarn varias cuestiones
concernientes a la internacionalizacin de las aplicaciones. Por ahora, podemos
aceptar que una codificacin da una tabla de equivalencia entre a) nmeros, letras y
smbolos y b) sus representaciones en bits. Por ejemplo, en US-ASCII, la letra A se
codifica como 01000001.
Cada orden FTP tiene hasta cuatro caracteres seguidos por cero o ms
argumentos. Una respuesta del cliente a una orden tiene un nmero de tres dgitos
seguido de una explicacin opcional en texto US-ASCII:
Nmero de 3 digitos Respuesta de texto
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 72/313 -
FTP se basa en el modelo cliente-servidor (descrito en el subapartado 2.3): el
cliente es cualquier proceso que inicia la transferencia de un archivo, ya sea hacia un
anfitrin remoto o desde l; el servidor es el proceso del anfitrin remoto que transfiere
el archivo. Casi todos los clientes FTP actuales permiten, adems de transferir
archivos, recorrer los sistemas de archivos del anfitrin remoto y del local, as como
crear y borrar archivos y directorios en dichas mquinas, siempre y cuando uno cuente
con los permisos necesarios.
La especificacin del FTP incluye la posibilidad de transmitir muchos tipos de
archivos; pero las implementaciones actuales del protocolo suelen admitir slo archivos
de textos y archivos binarios.
Los ficheros de texto que se transmiten son convertidos a formato US-ASCII
(texto plano). Antes de ser enviada, a cada lnea se le aade el cdigo US-ASCII de
retorno de carro. En el cliente FTP se realiza la conversin de los archivos de texto al
formato especfico de la plataforma donde se ejecuta el cliente.
Los archivos binarios se transfieren sin modificaciones. Se envan como flujos
continuos de bytes, mediante el protocolo TCP. Por la fiabilidad de ste, FTP no tiene
que encargarse de controlar los datos perdidos o descartados ni de volver a enviarlos.
Cualquier aplicacin que use el protocolo TCP mantiene dos conexiones TCP
durante la descarga de cualquier archivo. Una se usa para la transferencia de
informacin de control (emplea el puerto 21 por defecto), y la otra para la transferencia
de datos (usa por defecto el puerto 20). Con la primera se intercambian rdenes FTP y
respuestas del cliente; con la segunda, los datos de los archivos. Los recursos
gastados en mantener dos conexiones durante la transferencia de archivos se
compensan con las siguientes ventajas:
Se puede detener la transmisin de datos en cualquier
momento, mediante la orden ABOR (de abort, abortar). Si slo
se usara una conexin, no se podra cancelar la transferencia
de datos hasta que todos ellos se hubieran enviados. Para
evitar el inconveniente anterior, se podra implementar un
sistema de control que comprobara cada cierto tiempo que el
cliente no hubiera emitido ninguna orden de finalizacin; pero
sera muy ineficaz para transferencias de archivos voluminosos.
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.
[Link]
Miguel ngel Abin, Julio 2004 - 73/313 -
El servidor FTP mantiene en todo instante una suerte de
estado, esto es, la informacin sobre el directorio actual y
sobre la autenticacin hecha por el cliente al comienzo.
Figura 31. Esquema simplificado de una conexin FTP
Cuando se comienza una sesin FTP (el puerto por defecto es el 21), el servidor
FTP enva educadamente un mensaje de bienvenida (cdigo 220). A continuacin, el
cliente debe enviar un nombre de usuario (orden USER nombr eusuar i o). Si el
servidor contesta con el cdigo 331 (correspondiente a Need password for username:
se necesita contrasea para el nombre de usuario), el cliente solicita al usuario una
contrasea y la remite al servidor mediante la orden PASS cont r asenya. Si la
contrasea es vlida, el servidor enva al cliente la respuesta 230 (acceso autorizado).
Para ver los archivos y subdirectorios del directorio actual en el servidor, se usa la
orden DI R. Cuando el servidor recibe dicha orden, ejecuta otras dos. La primera, del
estilo PORT a, b, c, d, e1, e2, establece la direccin IP del cliente (a, b, c,
d) y un nmero de puerto del cliente (e2 + 256 x e1). La segundo (LI ST) hace que
el servidor abra una conexin TCP caracterizada por los argumentos de la primera
orden, que enve la lista de subdirectorios y archivos y que cierre la conexin.
Si se desea descargar un fichero desde un ordenador remoto, se usa primero una
orden PORT para declarar el puerto que se va a emplear para la conexin; luego, se
enva una orden RETR nombr ef i cher o que especifique el nombre del archivo que se
quiere descargar. Cuando el fichero ha sido transferido correctamente, el servidor FTP
cierra la conexin.
Interfaz de usuario
Interfaz del cliente FTP
Transferencia de datos
Interfaz del servidor FTP
Transferencia de datos
a
b
21
20
Conexin de
control
Conexin de
datos
Datos de archivos
rdenes o mandatos del
protocolo FTP
ESQUEMA DE UNA CONEXIN FTP
M
i
g
u
e
l
n
g
e
l
A
b
i
n
J
u
l
i
o
2
0
0
4
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 74/313 -
Figura 32. Los dos primeros pasos de una conexin FTP
Figura 33. Los dos siguientes pasos de una conexin FTP
FUNCIONAMIENTO DE UNA CONEXIN FTP (1)
Puerto nmero 355
Conexin de
control
Puerto nmero 356
Puerto nmero 21
Puerto nmero 20
PORT 192,168,1,20,1,100\r\n
Puerto nmero 355
Conexin de
control
Puerto nmero 356
Puerto nmero 21
Puerto nmero 20
ftp> [Link]
1
2
Comienzo
conexin de
datos
Cliente FTP
Cliente FTP
Servidor FTP
Servidor FTP
M
i
g
u
e
l
n
g
e
l
A
b
i
n
J
u
l
i
o
2
0
0
4
FUNCIONAMIENTO DE UNA CONEXIN FTP (2)
Puerto nmero 355
Conexin de
control
Puerto nmero 356
Puerto nmero 21
Puerto nmero 20
RETR [Link]\r\n
Puerto nmero 355
Conexin de
control
Puerto nmero 356
Puerto nmero 21
Puerto nmero 20
ftp> [Link]
3
4
Cliente FTP
Cliente FTP
Servidor FTP
Servidor FTP
Conexin de
datos
Bytes del archivo
[Link]
M
i
g
u
e
l
n
g
e
l
A
b
i
n
J
u
l
i
o
2
0
0
4
[Link]
Miguel ngel Abin, Julio 2004 - 75/313 -
Figura 34. Los dos siguientes pasos de una conexin FTP
Figura 35. ltimo paso de una conexin FTP
FUNCIONAMIENTO DE UNA CONEXIN FTP (3)
Puerto nmero 355
Conexin de
control
Puerto nmero 356
Puerto nmero 21
Puerto nmero 20
Puerto nmero 355
Conexin de
control
Puerto nmero 356
Puerto nmero 21
Puerto nmero 20
ftp> [Link]
5
6
Cliente FTP
Cliente FTP
Servidor FTP
Servidor FTP
Conexin de
datos
Fin del archivo
[Link]
Fin conexin de
datos
M
i
g
u
e
l
n
g
e
l
A
b
i
n
J
u
l
i
o
2
0
0
4
FUNCIONAMIENTO DE UNA CONEXIN FTP (4)
Puerto nmero 355
Puerto nmero 356
Puerto nmero 21
Puerto nmero 20
ftp> [Link]
7
Cliente FTP Servidor FTP
QUIT
Fin conexin de
control
M
i
g
u
e
l
n
g
e
l
A
b
i
n
J
u
l
i
o
2
0
0
4
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 76/313 -
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.
USER (User name). Los clientes que se conectan a un servidor FTP
envan primero este mandato una vez verificada la conexin. Con USER,
el usuario se identifica ante el servidor y se comprueba el nivel de
acceso que tiene a los archivos y directorios de anfitrin donde se
ejecuta el servidor. El nombre de usuario se pasa como argumento; por
ejemplo: USER j ml opez.
PASS (Password). Se enva despus de la orden USER. Como la
contrasea se pasa como argumento, el cliente FTP debe encargarse
de codificarla si no desea dejar la seguridad en manos del azar.
CWD (Change Working Directory). Permite que el usuario cambie a un
directorio distinto del actual, ya sea para almacenar archivos o para
recuperarlos (asumiendo que cuente con los permisos necesarios). El
directorio de trabajo donde se desea trabajar se pasa como argumento.
REIN (Reinitialise). Se encarga de terminar la conexin del usuario
cuando acaba la transferencia en curso, suponiendo que exista alguna.
QUIT. Cierra la conexin del usuario. Si hay alguna transferencia en
marcha, el servidor la cancela.
ABOR (Abort). Obliga a que el servidor cancele el ltimo mandato FTP y
a que anule cualquier transferencia de datos que pudiera estar en
marcha.
PORT. Permite especificar el puerto para las transferencias de datos.
Como argumento toma una direccin IP y un nmero de puerto.
TYPE. El argumento de esta orden especifica la representacin de los
datos que se transferirn. Dos argumentos frecuentes son A (de ASCII)
e I (de Image).
RETR (Retrieve). Hace que el servidor transfiera al cliente un copia del
archivo cuyo nombre figura como argumento (siempre que el usuario
disponga de los permisos apropiados).
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).
APPE (Append). Hace que el servidor acepte datos provenientes del
cliente y que los almacene en el fichero especificado como argumento,
aadindolos al final del archivo si ya existe.
RNFR (Rename From). Especifica el nuevo nombre para el fichero que
va a ser renombrado.
DELE (Delete). Hace que el fichero especificado en el argumento sea
borrado en el servidor, siempre que el usuario disponga de los permisos
apropiados.
[Link]
Miguel ngel Abin, Julio 2004 - 77/313 -
MKD (Make Directory). Hace que el directorio especificado como
argumento se borre, si el usuario dispone de los permisos de rigor.
PWD (Print Working Directory). Hace que se devuelva el nombre del
directorio actual.
HELP. Hace que el servidor enve informacin sobre su implementacin,
configuracin, etc.
LIST. Hace que el servidor enve al cliente una lista de todos los
archivos y subdirectorios dentro del directorio actual de trabajo.
NOOP (No Operation). Obliga al servidor a enviar una respuesta que
confirme que la conexin sigue activa.
2.8.4. El servicio de correo electrnico
El correo electrnico es uno de los servicios ms populares de Internet. A un
sistema de correo electrnico se le deben exigir estas funciones:
Composicin: correspondiente al proceso de creacin de los
mensajes (rellenado de los campos de un mensaje, existencia de una
lista de direcciones).
Transferencia: correspondiente al proceso de mover un mensaje del
emisor al destinatario. Es usual conseguir la transferencia mediante la
entrega del mensaje a alguna maquina intermedia, la cual se encarga de
reenviarlo hasta su destino final.
Generacin de informes: correspondiente a la generacin de
informacin que indique al emisor lo que ha ocurrido con su mensaje (si
ha sido recibido, si se perdi, si fue rechazado, etc.)
Presentacin de la informacin: correspondiente a la presentacin
de los mensajes al usuario. Si los mensajes slo tienen texto,
implementar esta funcin resulta sencillo; pero la situacin se complica
cuando contienen imgenes, vdeos, archivos de audio, etc. El sistema de
correo electrnico debe saber qu hacer con cada tipo de archivo dentro
del mensaje.
Disposicin: se refiere a la gestin de los mensajes (borrado,
reenvo, listas de correo, almacenamiento en buzones, etc.)
Los sistemas actuales de correo electrnico suelen constar de dos partes bien
diferenciadas, llamadas agente de usuario y agente de transferencia de mensajes.
La primera permite que se escriban y se lean mensajes; por ello, dispone de una serie
de rdenes para componer los mensajes, para recibirlos, mostrarlos y contestarlos. La
segunda se encarga de mover los mensajes hasta su destino final. Cualquier
aplicacin que permita a los usuarios leer correos o enviarlos constituye, total o
parcialmente, un agente de usuario.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 78/313 -
El servicio de correo electrnico se basa en el protocolo de aplicacin SMTP
(Simple Mail Transfer Protocol: protocolo de transferencia de correo sencillo), definido
en el RFC 821. El adjetivo sencillo procede de su limitacin a mensajes sencillos de
correo (sin archivos adjuntos ni caracteres no US-ASCII). Algunos textos traducen
equivocadamente SMTP como protocolo simple de transferencia de correo, cuando lo
simple es el correo, no el protocolo.
Este protocolo se dise a principios de los aos 80. Como ya existan sistemas
de correo electrnico anteriores a l, se construy para que pudiera implementarse
sobre cualquier sistema de comunicaciones capaz de manejar lneas de hasta 1.000
caracteres US-ASCII. As pues, con este protocolo se pueden enviar mensajes a travs
de redes que no usen TCP/IP; en las redes TCP/IP, TCP es el mecanismo de
transporte de los mensajes.
SMTP sigue el modelo cliente-servidor: los procesos que transmiten mensajes
operan como clientes; aquellos que los reciben, como servidores. Durante la vida de
una conexin SMTP, el cliente y el servidor establecen una conversacin: el cliente
enva peticiones al servidor, que las atiende.
El formato de los mensajes SMTP se define en el RFC 822:
Figura 36. Formato de un mensaje segn el RFC 822
Cada campo de la cabecera tiene una lnea de texto US-ASCII con el nombre del
campo, dos puntos y un valor (algunos campos admiten varios valores). Los campos
de la cabecera se muestran en la figura 37. Cuando un usuario usa para escribir correo
un agente de usuario, ste crea un mensaje con el formato anterior
Cabecera Significado
To: Direccin o direcciones de correo electrnico de los
destinatarios primarios.
Cc: Direccin o direcciones de correo electrnico de los
destinatarios secundarios.
Bcc: Direccin o direcciones con copia oculta
From: Persona que cre el correo
Sender: Direccin de correo del remitente
Received:
Lnea aadida por cada agente de transferencia a lo largo de la
ruta de destino
Return-Path: Especifica una ruta de retorno al remitente
Figura 37a. Campos obligatorios de la cabecera de un mensaje SMTP
Adems de los campos anteriores, una cabecera puede contener otros campos
optativos, detallados en la figura 37b.
Envoltura
Campos de la cabecera
Lnea en blanco
Cuerpo del mensaje
[Link]
Miguel ngel Abin, Julio 2004 - 79/313 -
Cabecera: Significado:
Date: Fecha y hora de envo del mensaje.
Reply-To: Direccin de correo a la que dirigir la contestacin
Message-Id: Nmero nico que sirve para referirse al mensaje
In-Reply-To: Identificador del mensaje al cual responde este
mensaje
References: Otros identificadores del mensaje
Keywords: Palabras clave elegidas por el usuario
Subject: Descripcin breve del mensaje
Figura 37b. Campos optativos de la cabecera de un mensaje SMTP
El RFC 822 permite que los usuarios y los programas de correo electrnico
inventen nuevas cabeceras. Para crearlas basta con empezarlas con X- (por ejemplo,
X- Pr i or i dad- Per sonal : 7).
SMTP estaba pensado originalmente para mensajes cuyo cuerpo estuviera escrito
usando la codificacin US-ASCII (volveremos a ella en el subapartado 3.4), la cual
resulta inapropiada para muchas lenguas, algunas alfabticas (espaol, francs,
alemn, ruso, griego, etc.) y otras no alfabticas (japons, chino, etc.). Si se intenta
usar dicha codificacin para una lengua latina como la nuestra, los resultados suelen
ser de este tipo:
Desde que a principios de a=F1o cambi=E9 de programa de
correo electr=F3nico, algunos reciben caracteres extra=F1os en
mis mensajes =BFQu=E9 est=E1 sucede?
Un mensaje escrito en chino:
puede acabar convertido en
TRGihA7MRtOGfu#4kLcwvL#
En cuanto el correo electrnico se fue popularizando en los pases no
angloparlantes, se hizo evidente que el protocolo SMTP deba dar cabida a muchsimas
lenguas que usaban caracteres no US-ASCII. Como la necesidad de usar US-ASCII
aparece en el RFC 821, hubo que definir unos RFC que permitieran usar en el cuerpo
caracteres no US-ASCII: el RFC 1521 y el 1522, en los cuales se define la
especificacin MIME (Multipurpose Internet Mail Extensions: extensiones multipropsito
de correo de Internet). MIME permite la inclusin de caracteres no ingleses y de
informacin binaria en el cuerpo del mensaje. Cualquier texto no US-ASCII o cualquier
archivo (de vdeo, de audio, etc.) se codifica como US-ASCII, para as poder enviarlo
mediante el protocolo SMTP.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 80/313 -
MIME define cinco nuevas cabeceras de mensaje (se describen en el RFC 2045):
Cabecera MIME Significado
MIME-Version: Identifica la versin MIME
Content-Type: Tipo del mensaje
Content-Description: Cadena legible que describe el contenido del mensaje.
Content-Id: Identificador nico
Content-Transfer-
Encoding:
Especifica cmo se codifica el cuerpo del mensaje
Figura 38. Cabeceras de un mensaje MIME
He aqu un ejemplo de mensaje MIME:
MI ME- Ver si on: 1. 0
Cont ent - Type: t ext / pl ai n; char set =us- asci i
Cont ent - Tr ansf er - Encodi ng: 7bi t
Cont ent - Descr i pt i on: mensaj e muy si mpl e MI ME
Cont ent - I D: <par t 00909@j l opez. empl e>
Est e es el cuer po del mensaj e.
La cabecera MI ME- Ver si on indica la versin de la especificacin MIME seguida
por el mensaje.
La cabecera Cont ent - Type declara el formato original del cuerpo del mensaje.
Dentro del primer valor (t ext / pl ai n), t ext corresponde al tipo del cuerpo; pl ai n, al
subtipo del cuerpo. El tipo es una clasificacin genrica del contenido (por ejemplo,
t ext ); y el subtipo es una clasificacin ms concreta (por ejemplo, pl ai n, ht ml o
xml ). El tipo del cuerpo admite estos valores: t ext , i mage, audi o, vi deo,
appl i cat i on y message.
El campo Cont ent - Tr ansf er - Encodi ng indica cmo se codifican los
caracteres en bits. Se puede usar la codificacin US-ASCII (us- asci i ), ISO Latin 1
(i so- 8859- 1), etc. Un mismo mensaje puede enviarse con distintas codificaciones.
Cuando se envan mensajes binarios con el cuerpo (un documento PDF o un
ejecutable, por ejemplo), suelen codificarse mediante la codificacin de base 64. sta
divide cada grupo de veinticuatro bits en grupos de seis bits, y codifica cada grupo
como un carcter ASCII mostrable (no de control). El sistema de codificacin es A
para el cero, B para el uno, y as sucesivamente. Cuando se acaban las maysculas
(Z corresponde al veinticinco), se contina con las minsculas, luego con los
caracteres del 0 al 9 (el 0 corresponde al cincuenta y dos; el 9 al sesenta y uno)
y, luego, con + (sesenta y dos) y - (sesenta y tres). Los caracteres = y == se usan
para indicar que el ltimo grupo del archivo contiene slo ocho o diecisis bits,
respectivamente.
[Link]
Miguel ngel Abin, Julio 2004 - 81/313 -
Figura 39. Tabla de la codificacin de base 64: valor y cdigo
Un ejemplo valdr ms que mil palabras: imaginemos que tenemos un archivo
binario cuyos primeros veinticuatros bits son:
000100010000010001000011
El segmento se dividir en grupos de seis bits:
000100 010000 010001 000011
que equivalen en decimal a 4, 16, 17 y 3.
Cada grupo se codificar como una letra, de acuerdo con el esquema expuesto:
EQRD
Por ejemplo, en la codificacin de base 64, el siguiente galimatas:
SVNBKj AwKi AgI CAgI CAgI CAqMDAqI CAgI CAgI CAgI CowMSo5ODc2NTQzMj EgI CAg
I CAqMTI qODAwNTU1MTI zNCAgI CAgKj kxMDYwNyowMTExKl UqMDAyMDAqMTEwMDAw
Nzc3Kj AqVCo+CkdTKl BPKj k4NzY1NDMyMSo4MDA1NTUxMj M0Kj kyMDUwMSoyMDMy
Kj c3Mj EqWCowMDI wMDMKU1QqODUwKj AwMDAwMDAwMQpCRUcqMDAqTkUqTVMxMTEy
Ki o5Mj A1MDEqKkNPTl RSQUNUI wpSRUYqSVQqODEyODgyNzc2MwpOMSpTVCpNQVZF
Ukl DSyBTWVNURU1TCk4zKj MzMTI gTkVXI EhBTVBTSEl SRSBTVFJ FRVQKTj QqU0FO
I EpPU0UqQ0EqOTQ4MTEKUE8xKj EqMj UqRUEqKi pWQypUUDhNTSpDQi pUQVBFOE1N
Cl BPMSoyKj MwKkVBKi oqVkMqVFAxLzQqQ0I qVEFQRTEvNEl OQ0gKUE8xKj MqMTI 1
KkVBKi oqVkMqRFNLMzEvMi pDQi pESVNLMzUKQ1RUKj MKU0UqMTEqMDAwMDAwMDAx
CkdFKj EqNzcyMQpJ RUEqMSoxMTAwMDA3NzcK
equivale a
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w
15 P 32 g 49 x
16 Q 33 h 50 y
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 82/313 -
I SA*00* *00* *01*987654321 *12*8005551234 *910=
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*I T*8128827763
N1*ST*MAVERI CK SYSTEMS
N3*3312 NEWHAMPSHI RE STREET
N4*SAN J OSE*CA*94811
PO1*1*25*EA***VC*TP8MM*CB*TAPE8MM
PO1*2*30*EA***VC*TP1/ 4*CB*TAPE1/ 4I NCH
PO1*3*125*EA***VC*DSK31/ 2*CB*DI SK35
CTT*3
SE*11*000000001
GE*1 *7721
I EA*1*110000777
Este ejemplo corresponde a una peticin de comercio electrnico con una
empresa de Estados Unidos.
En la siguiente tabla se exponen algunos valores que puede tomar la cabecera
Cont ent - Type, definidos en el RFC 1521:
Tipo Subtipo Descripcin
plain Texto sin formato
text
richtext Texto que incluye rdenes simples de
formato
gif Imagen en formato GIF
image
jpeg Imagen en formato JPEG
audio basic Archivo de audio
video mpeg Archivo en MPEG
octet-stream Secuencia de bytes sin interpretacin
application
postscript Documento imprimible en Postscript
rfc822 Mensaje MIME RFC 822
partial Mensaje dividido para la transmisin
message
external-
body
El mensaje mismo debe obtenerse de la red
Figura 40. Valores posibles de la cabecera Content-Type
Por ejemplo, cuando en un mensaje aparece el campo Cont ent - Type:
i mage/ j peg, el cliente ya sabe que debe tratarlo como una imagen.
[Link]
Miguel ngel Abin, Julio 2004 - 83/313 -
En principio, una implementacin del SMTP proporciona todo lo necesario para
enviar y recibir correos electrnicos. Una comunicacin SMTP comienza cuando la
mquina de origen abre una conexin TCP con la mquina de destino mediante el
puerto nmero 25 (asociado por defecto al SMTP). El servidor SMTP enva un mensaje
de reconocimiento al cliente, del tipo 220 Ser ver Ready. El formato de las respuestas
SMTP es muy similar al que vimos para las respuestas FTP: primero, un cdigo de tres
dgitos; a continuacin, un mensaje de texto. Un servidor SMTP puede rechazar
conexiones mediante la respuesta 421 Ser vi ce not avai l abl e. Si la conexin se
acepta, el cliente enva la orden HELO nombr eanf i t r i on (por ejemplo, HELO
j mgar ci a. uv. es). Una vez que el cliente recibe una respuesta 250 OK, puede
empezar el envo del mensaje.
El envo del mensaje comienza cuando el cliente indica de quin es el mensaje, a
quin se enva, y luego despacha el contenido del mensaje. De quin procede el
mensaje se especifica con la orden MAI L FROM <di r ecci on>, que avisa al
destinatario de que va a recibir un nuevo mensaje. La direccin entre < y > es el
camino de retorno para el mensaje, esto es, la direccin a la cual se enviar cualquier
mensaje de error. Si se usa MAI L FROM: <>, no se enviarn mensajes de error. A
quin se enva el mensaje se especifica con la orden RCPT TO: <di r ecci on>(si hay
varios destinatarios, se precisa un RCPT para cada uno).
Cada destinatario que reciba el mensaje contestar con una respuesta 250 OK; si
el servidor rechaza el mensaje, se enviar una respuesta 550 (siempre que el servidor
no reconozca el mandato del cliente, responder con un cdigo 500 502). Una vez
enviada la informacin concerniente al remitente y a los destinatarios, el contenido del
mensaje se enva mediante la orden DATA. En primer lugar se enva una orden DATA y
se espera a recibir una respuesta del tipo 354 St ar t mai l i nput ; end wi t h
<CRLF>) (el texto puede variar de unos servidores a otros; por ejemplo, en otros
servidores la respuesta ser 354 Ent er mai l , end wi t h . on a l i ne by
i t sel f ). Cuando le llega, el cliente enva el mensaje como una sucesin de lneas de
texto US-ASCII (slo se permiten caracteres mostrables). Finalmente, se indica con
<CRLF>que el mensaje ha terminado (en el otro ejemplo, se indicara con .). Si la
transferencia ha sido correcta, el servidor responde con un mensaje 250 OK. Como no
se enva para cada lnea ningn mensaje de recepcin correcta, cualquier error obliga a
reenviar todos los datos del mensaje.
Las direcciones que se indican en la cabecera del correo no se emplean en la
entrega del mensaje, slo se usan los argumentos de los mandatos RCPT TO: .
Nota: Si ha trabajado con sistemas UNIX y peina alguna que
otra cana, seguramente le sonarn los programas Uuencode y
Uudecode. Su comportamiento es similar al de MIME. Con el
primero, un archivo binario se convierte en un archivo de texto
US-ASCII mediante una codificacin no mucho ms compleja
que la descrita hace tres pginas. Uudecode descodifica el
archivo de texto US-ASCII y lo devuelve a su formato original
(binario). Con el uso generalizado de MIME, dichos programas
apenas se utilizan.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 84/313 -
El conjunto de rdenes que puede usar un cliente SMTP se detalla en esta tabla:
Orden Significado
HELO nombre_anfitrion Identifica el origen de la conexin
MAIL FROM: <direccion_anfitrion> Identifica al remitente
RCPT TO: <direccion_destino> Identifica al destinatario
DATA Seala el comienzo de la introduccin de datos
RSET Aborta la conexin con el servidor SMTP
QUIT Cierra la conexin con el servidor SMTP
HELP Muestra ayuda sobre las rdenes aceptadas
EXPN <direccion_correo> Expande una lista de correo
VRFY <direccion_correo> Comprueba la existencia de una direccin de
correo.
Figura 41. rdenes a disposicin de un cliente SMTP
A continuacin expongo un ejemplo de transferencia SMTP (disculpe que me use
como ejemplo por partida doble, pero es difcil inventar esta clase de ejemplos):
220 ai di ma. es Sendmai l SMI - 8. 6/ SVR4 r eady at Fr i , 9 J ul 2004
16: 34: 25 GMT
HELO [Link]
250 ai di ma. es OK mabi an. ai di ma. es [ 192. 168. 1. 20] , pl eased t o
meet you
MAIL FROM: <mabian@[Link]>
250 <mabi an@ai di ma. es>Sender ok
RCPT TO <mabian2@[Link]>
250 <mabi an2@ai di ma. es>Reci pi ent ok
DATA
354 Ent er mai l , end wi t h . On a l i ne by i t sel f
Hol a, l ect or es y l ect or as de j avaHi spano:
Est e es un ej empl o del pr ot ocol o SMTP.
Sal udos.
.
250 TAA11108 Message accept ed f or del i ver y
QUIT
221 mabi an@ai di ma. es cl osi ng connect i on
El carcter de fin
de mensaje es
indicado por el
servidor
Advertencia: El RFC 821 especifica que las rdenes se
interpretan sin tener en cuenta si se escriben con maysculas
o minsculas (o con una combinacin de ambas). As, dara
igual escribir DATA que DaTa o dat a. Sin embargo, algunos
servidores SMTP se han implementado de manera que slo
entienden mandatos escritos en maysculas. En este tutorial
sigo el criterio de escribirlos siempre con maysculas.
Cualquier argumento de una orden debe ser de tipo US-ASCII.
As, no estn permitidos argumentos como nez@[Link],
kurtnabenger@[Link] o snchez@[Link].
[Link]
Miguel ngel Abin, Julio 2004 - 85/313 -
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.
El protocolo SMTP se encarga de establecer una conexin TCP entre la mquina
de destino (cliente) y la receptora (servidor) y de enviar directamente el mensaje a
travs de ella. En consecuencia, basta este protocolo para entregar mensajes
directamente a los usuarios. Ahora bien, pocas veces interesa la entrega directa de los
mensajes a los destinatarios. Veamos algunos problemas que plantea el uso directo de
SMTP:
a) Si SMTP no consigue enviar un mensaje a su destino, lo reintenta a
intervalos cada vez ms largos, durante varios das, antes de enviar
un mensaje de error a la direccin de camino de retorno. Como las
mquinas receptoras actan como servidores, si no estn encendidas
y conectadas a Internet las veinticuatro horas del da puede suceder
que el servidor est apagado, desconectado, o ambas cosas, cada
vez que el cliente intenta enviarle el mensaje.
b) Muchas veces, el uso de conexiones TCP est restringido por motivos
de seguridad. A los cortafuegos les desagradan las conexiones a
puertos aleatorios.
c) Cuando el destinatario usa un protocolo de correo y el remitente otro,
la comunicacin directa se torna imposible. Las incompatibilidades
entre dos protocolos de correo electrnico pueden ser legin: uno
puede admitir campos de cabecera que el otro no tiene, pueden
haberse construidos sobre familias de protocolos incompatibles,
pueden existir diferencias semnticas entre los campos de la cabecera
(aun cuando tengan el mismo nombre), los formatos de los
argumentos de los mandatos pueden ser distintos o tener diferentes
representaciones binarias... Aunque los problemas expuestos no son
triviales, palidecen ante los derivados de la falta de compatibilidad
entre los campos del cuerpo. Imagine que enva un mensaje en cuyo
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 86/313 -
cuerpo hay una referencia a un archivo disponible mediante FTP (por
ejemplo, [Link] Cmo podr
interpretarlo un cliente de correo que trabaje con un protocolo del
modelo OSI, donde no existe FTP? No podr hacerlo directamente.
Es ms: posiblemente tampoco podr hacerlo indirectamente
(mediante traductores o pasarelas, que funcionan bien para
mensajes de texto US-ASCII), pues las diferencias de implementacin
entre los protocolos TCP/IP y los OSI son casi insalvables.
Estos problemas suelen evitarse servidores de correo electrnico, que se
encargan de almacenar, recibir y transmitir correos electrnicos. El propsito bsico de
un servidor de correo electrnico es actuar como un almacn de correos al cual pueden
acceder los destinatarios. En un servidor de correo electrnico, cada usuario autorizado
dispone de uno o varios buzones, donde se van almacenando los mensajes que recibe,
que luego pueden descargarse en una mquina local para su posterior lectura.
Un protocolo de aplicacin sencillo y eficaz para recuperar mensajes de un buzn
de un servidor de correo es el POP3 (Post Office Protocol Version 3: versin 3 del
protocolo de oficina de correos), definido en el RFC 1225. Este protocolo tiene rdenes
para que un usuario establezca una sesin, obtenga sus mensajes, los borre y cierre la
sesin. Con ellas, el usuario puede obtener los mensajes de sus buzones remotos
(ubicados en servidores de correo) y almacenarlos en su mquina local para leerlos
cuando desee.
POP3 usa el protocolo TCP y, por defecto, el puerto TCP estndar 110. Tambin
se basa en el modelo cliente-servidor: los clientes reclaman sus correos, y el servidor
se los enva. Cuando un cliente se conecta a un servidor POP3 para leer su correo,
obtiene la respuesta +OK POP3 ser ver r eady. POP3 emplea +OK y ERR para
comunicar al cliente su aceptacin o rechazo de la ltima orden recibida. Basta con que
el cliente lea el primer carcter de una respuesta (- o +) para que sepa si se ha
producido un error o no. El siguiente paso por parte del cliente consiste en enviar al
servidor el mandato USER nombr eusuar i o. Si el servidor devuelve una respuesta
+OK, el cliente debe enviar un mandato PASS cont r asenya. Si la contrasea es
vlida, el cliente recibir un mensaje del estilo +OK nombr eusuar i o has x
message( s) ( y oct et s) , donde x es el nmero de mensajes sin leer e y los bytes
que ocupan. Durante el proceso de identificacin, si el cliente introduce una contrasea
incorrecta o irreconocible por el servidor recibir un mensaje del estilo ERR.
El mandato STAT devuelve el nmero de mensajes que no han sido ledos
(num_mensaj es) y su tamao total en bytes (num_byt es), con una respuesta del tipo
+OK num_mensaj es num_byt es. El mandato LI ST sirve para averiguar el tamao
de cada mensaje. RETR se usa para retirar mensajes del buzn: el servidor enva una
respuesta +OK y enva el mensaje completo al ordenador local del usuario. La orden
Advertencia: En este tutorial uso los trminos byte y octeto de
forma intercambiable. Si se consultan otros textos, conviene
tener presente que no siempre un byte equivale a 8 bits
(octeto): hay sistemas operativos antiguos, pero que an se
usan, que trabajan con bytes de 7 bits. Raro sera que el lector
se encontrara con alguno, pero ms vale estar prevenido.
[Link]
Miguel ngel Abin, Julio 2004 - 87/313 -
TOP num_mensaj e num_l i neas lista la cabecera del mensaje con nmero
num_mensaj e, ms num_l i neas del cuerpo del mensaje.
En la tabla siguiente se muestran las rdenes ms habituales de los clientes
POP3:
Orden Significado
USER usuario Identifica al usuario
PASS contrasenya Identifica la contrasea del usuario
STAT Devuelve el nmero de mensajes y sus tamaos
en bytes
LIST Lista los mensajes en el buzn y sus tamaos
RETR num_mensaje Lee un mensaje
DELE num_mensaje Marca un mensaje para borrarlo al cerrar la
sesin
QUIT Acaba la sesin. Cuando se ejecuta, se borran
todos los mensajes marcados.
TOP num_mens num_lineas Lista la cabecera del mensaje ms las lneas del
cuerpo que se marcan
Figura 42. rdenes a disposicin de un cliente POP3
He aqu un ejemplo de una sesin POP3:
+OK POP3 ser ver r eady <ai di ma. es>
USER mabian
+OK Passwor d r equi r ed f or mabi an.
PASS 34XsdSak9512
+OK mabi an has 7 messages.
STAT
+OK 7 1345
LIST
+OK 7 messages ( 1345 oct et s)
RETR 1
+OK 546 oct et s
DELE 1
+OK message 1 del et ed
LIST
+OK 1 messages ( 799 oct et s)
TOP 1 20
- ERR message 1 has been del et ed
TOP 2 4
+OK 799 oct et s
Recei ved: f r om ai di ma. es by ai di ma. es i d LAA01134; Fr i , 9 J ul
2004 18: 12: 01 GMT
Message I D: <003f 01c412a$13a2b510$900000@ai di ma. es>
Fr om: J ose Lui s Gr aci a j l gr aci a@ai di ma. es
To: <mabi an@ai di ma. es>
Subj ect : Convenci n sobr e i nt er oper abi l i dad en Ri ga
Dat e: Fr i , 9 J ul 2004 20: 11: 37 +0100
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 88/313 -
MI ME- ver si on: 1. 0
Cont ent - Rype: t ext / pl ai n; Char set =i so- 8859- 1
Cont ent - Tr ansf er - Encodi ng: 7 bi t
Hol a, Mi guel ngel :
Ti enes ya al go pr epar ado par a l a convenci n en Ri ga? An f al t a,
per o ms val e t ener l o en cuent a.
Di me al go.
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 quiere eliminar un mensaje defectuoso que bloquea al cliente
de correo cada vez que lo intenta descargar a la mquina local.
Cuando se quieren eliminar mensajes sin haberlos descargado (por su
tamao o su peligrosidad, por ejemplo).
Cuando se quiere comprobar el contenido de los mensajes antes de
bajarlos, viendo los campos de la cabecera o las primeras lneas del
cuerpo, pongamos por caso.
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.
En la figura 43 se muestra un sencillo esquema del proceso de envo y entrega de
correos electrnicos.
[Link]
Miguel ngel Abin, Julio 2004 - 89/313 -
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.
Agente de
usuario
Agente de
usuario
SMTP
SMTP
POP3
Servidor de correo
del remitente
Servidor de correo
del destinatario
USO HABITUAL DE LOS PROTOCOLOS SMTP Y POP3
Para acceder a los correos, se pueden
usar otros protocolos: IMAP o
DMSP, por ejemplo.
Miguel ngel Abin Julio 2004
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 90/313 -
2.8.5. La World Wide Web
La World Wide Web (tambin conocida como WWW o Web) es, para muchos
usuarios, Internet. Desde luego, es con diferencia el servicio ms popular de la capa de
aplicacin. Dentro de la arquitectura TCP/IP, la Web introduce protocolos de aplicacin
y servicios nuevos. Los navegadores web, los servidores web y el protocolo HTTP se
ubican en la cima de la familia de protocolos TCP/IP. La Web no es un sistema cerrado
ni esttico; segn se van necesitando, se le aaden nuevos protocolos y aplicaciones.
Dependiendo de quien use el trmino Web, suele emplearse una definicin u otra.
A continuacin doy seis que son bastante comunes (no ser preciso que le diga cules
son oficiales, enseguida lo notar):
El universo de la informacin accesible de la red, la encarnacin del
conocimiento humano.
Un sistema distribuido de hipertexto, de tipo cliente-servidor y que
funciona en Internet, que proporciona una nica interfaz de usuario
para acceder a un gran conjunto de informacin almacenada como
informes, notas, bases de datos, documentacin de ordenadores.
Un servicio de informacin multimedia, distribuido, basado en
hipertexto y que funciona en Internet: es interactivo, dinmico,
distribuido y multiplataforma.
Un conjunto de servicios (correo electrnico, foros, transferencia de
archivos, HTTP, etc.) a los cuales se puede acceder mediante un
navegador web.
Un conjunto de archivos de hipertexto, de imgenes, vdeos y sonidos
ubicados en los servidores web.
Un conjunto de protocolos que permiten la consulta y la transmisin de
pginas web en Internet, en las intranets y en las extranets.
Figura 44. La WWW dentro de la arquitectura TCP/IP
Capa de enlace
Capa de red
Capa de transporte
Capa de aplicacin: SMTP, FTP, POP3...
Capa de aplicacin: HTTP
HTML
Aplicaciones de la World Wide Web
Miguel ngel Abin Julio 2004
[Link]
Miguel ngel Abin, Julio 2004 - 91/313 -
La caracterstica ms relevante de la Web es su estructura hipertextual: la WWW
contiene un gran conjunto de documentos de hipertexto (llamados pginas web).
Cualquier documento de hipertexto contiene enlaces que conectan con otros
documentos; un enlace puede ser una palabra, una frase o un grfico. A travs de los
enlaces, se puede acceder a otros documentos, imgenes, vdeos, sonidos, etc. E
general, se dice que la red permite acceder a recursos. Un recurso es una pgina web
o algn tipo de contenido susceptible de ser almacenado en un archivo, binario o no, y
presentado al usuario de una forma inteligible. Un recurso puede ser una imagen, un
directorio, un vdeo, un documento Word, PDF, PostScript, etc. Tambin puede ser una
referencia a una consulta a una base de datos o a un motor de bsqueda (como
Google).
Como los enlaces de una pgina a otros recursos pueden no seguir caminos
lgicos o directos, la Web es un entramado de documentos, vdeos, imgenes,
animaciones y sonidos. De ah lo apropiado del nombre (web significa telaraa o
malla). Los documentos de la Web no tienen porque ser necesariamente estticos:
pueden generarse de forma dinmica, como respuesta a las acciones o peticiones de
los usuarios. Por ejemplo, cuando se hace una compra electrnica, la pgina web que
nos muestra los detalles de la transaccin no exista antes de la compra.
Como supongo que si est leyendo esto sabe ya muy bien qu aspecto presenta
la Web y cmo se navega por ella, obviar explicarlo y me dedicar a explorar sus
entraas.
El servicio de la World Wide Web se basa, como tantos otros, en el modelo
cliente-servidor: el cliente solicita acceder a pginas web, y el servidor se las
suministra. Tres son los componentes fundamentales de este servicio:
Una arquitectura cliente-servidor que usa el protocolo de aplicacin HTTP
(HyperText Transfer Protocol: protocolo de transferencia de hipertexto) y
se basa en TCP/IP (tanto en la acepcin de familia de protocolos como en
la de modelo de capas). Por debajo del HTTP quedan los protocolos de
las capas de red, de transporte y de enlace. A diferencia de FTP o Telnet,
HTTP no se considera como parte estndar de la familia de protocolos
TCP/IP, aunque es casi imposible encontrar algn producto comercial que
no lo implemente. HTTP viene a ser el protocolo vernculo de la Web.
Los URL (Uniform Resource Locator: localizador uniforme de recursos).
Un lenguaje de etiquetado de hipertexto (HTML o HyperText Markup
Language: lenguaje de etiquetado de hipertexto). Este lenguaje, basado
en etiquetas, es el que permite escribir pginas web y establecer enlaces
entre ellas.
En este apartado considerar slo los dos primeros componentes de la Web. En
ella se pueden encontrar muchsimos manuales de HTML, gratuitos y de buena calidad.
Ntese la naturaleza metalingstica de este hecho: el HTML se usa para describirse a
s mismo.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 92/313 -
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:
El protocolo que debe usarse para acceder al recurso.
El nombre de la mquina donde est el recurso.
El nmero de puerto por el cual la mquina permite solicitar el recurso.
La ubicacin del recurso dentro de la mquina.
Un URL tiene la forma
esquema: l ocal i zaci n- segn- el - esquema
La primera parte (esquema) especifica el protocolo de aplicacin que se usar
para acceder al recurso. Un URL como [Link] identifica un
archivo que puede conseguirse mediante el protocolo FTP (visto en 2.8.3). Los URL de
HTTP son los ms comunes para localizar recursos a los que se puede acceder
mediante el protocolo HTTP. El lector puede encontrar ms informacin de los tipos de
URL y de sus formatos en
[Link]
En este mismo ejemplo, ht t p nos indica el protocolo necesario para acceder al
recurso. La cadena ar chi ve. ncsa. ui uc. edu nos indica que el recurso est ubicado
en un anfitrin cuyo nombre DNS es ar chi ve. ncsa. ui uc. edu. La cadena
/ SDG/ Sof t war e/ Mosai c/ Demo/ nos indica el camino dentro del anfitrin
ar chi ve. ncsa. ui uc. es donde se encuentra el recurso. Por ltimo, ur l -
pr i mer . ht ml nos indica el nombre del recurso.
En un URL se puede especificar un nmero de puerto. Tal como ya se coment, si
ste no se especifica, se sobreentiende que se usa el puerto por defecto
correspondiente al protocolo usado. En el caso de HTTP, el puerto por defecto es el 80.
Podramos, por tanto, haber escrito
[Link]
Los URL siempre han tenido un defecto inherente a su formato: todo URL hace
referencia a un anfitrin concreto; no permite apuntar a un recurso sin especificar
dnde se encuentra. Para los recursos muy solicitados, sera interesante disponer de
copias del recurso, ubicadas en distintos anfitriones. As se podran distribuir las
peticiones entre varios anfitriones distantes y se repartira el trfico de datos entre
redes alejadas geogrficamente. Sin embargo, los URL no permiten solicitar recursos
independientemente de los anfitriones donde se encuentran o se generan estos
recursos.
Una solucin a este problema la dan los URN (Uniform Resource Name: nombre
uniforme de recursos). Vienen a ser unos punteros independientes de la localizacin.
Gracias a ellos, un recurso puede ser copiado en muchos lugares distintos. Si una
copia no se encuentra disponible en un sitio dado, el recurso puede ser encontrado en
[Link]
Miguel ngel Abin, Julio 2004 - 93/313 -
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 Ht t pd (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.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 94/313 -
El protocolo HTTP, que usa la codificacin US-ASCII, es el protocolo de facto para
la transferencia de archivos web y el acceso a los recursos de la Web,. La versin 1.1
de este protocolo se documenta en el RFC 2616 (la versin 1.0, ahora obsoleta, se
documenta en el RFC 1945).
El RFC 2068 afirma que el protocolo HTTP funciona por lo general sobre una
conexin TCP, pero que no depende de una capa de transporte especfica. Tal y como
se define, HTTP es un protocolo abierto, extensible, sin conexin y sin estado. Es
abierto y extensible porque, cuando transmite informacin a un cliente, incluye una
cabecera MIME que informa a ste de la clase de datos que siguen a la cabecera. Con
ese conocimiento, los clientes saben qu aplicaciones necesitan para interpretar el
recurso (reproductores de vdeo, de audio, etc.). Si se crean recursos nuevos, HTTP
puede incorporarlos sin grandes problemas. Su carencia de conexin y estado se debe
a que, una vez contestada la peticin de un cliente y pasado un tiempo, la conexin
entre servidor y cliente se desecha y no se registra. Para el servidor, cada peticin es
nueva, pues no la asocia a peticiones anteriores o a clientes concretos. Si fuera
humano, HTTP sera amnsico.
Toda comunicacin HTTP consiste en tres partes:
Una lnea inicial, que puede corresponder a una respuesta o a
una peticin.
Una cabecera (optativo).
Un cuerpo (optativo).
En el lado del cliente, una conexin HTTP sigue estos pasos:
1) El cliente (un navegador) abre un socket TCP y se conecta al servidor
HTTP por medio de un puerto (por defecto, el 80). Mediante el socket
enva su peticin. La lnea inicial de una peticin consiste en el mtodo
de peticin (en este protocolo, las rdenes se llaman mtodos), la
direccin del recurso solicitado y la versin del protocolo HTTP con que
se trabaja. Por ejemplo: GET / ai di ma/ i ndex. ht ml HTTP/ 1. 1. Esta
lnea indica una peticin con el mtodo GET del recurso i ndex. ht ml
(un archivo HTML), as como la versin del HTTP usado: la 1.1.
2) De manera optativa, el cliente puede enviar una cabecera con
informacin acerca de su configuracin y de sus preferencias a la hora
de mostrar documentos. He aqu un ejemplo:
User - Agent : Mozi l l a/ 4. 76 ( Wi nNT; I )
Accept : i mage/ gi f , i mage/ x- xbi t map, i mage/ j peg,
i mage/ pj peg, */ *
Accept - Encodi ng: gzi p
Accept - Char set : i so- 8859- 1, *, *ut f - 8
[ l nea en bl anco par a i ndi car f i n de l a cabecer a]
3) Tras el envo de la peticin y la cabecera, el cliente puede enviar un
cuerpo, que contendr datos enviados por el cliente mediante el mtodo
POST. Lo normal es que esos datos se usan en programas de tipo CGI
(vase el final de este subapartado).
[Link]
Miguel ngel Abin, Julio 2004 - 95/313 -
El servidor HTTP contesta a la peticin de la siguiente forma:
1) Enva al cliente una lnea con tres campos: la versin del HTTP usada por
el servidor, el cdigo de control y la descripcin de este cdigo. Por
ejemplo, HTTP/ 1. 1 200 OK indica que el servidor usa la versin 1.1 del
protocolo y que devuelve el cdigo 200, cuya descripcin es OK. Dicho
cdigo significa que la peticin del cliente se juzga correcta y que se
enviar la informacin solicitada tras la cabecera.
2) Tras la lnea anterior, el servidor enva al cliente una cabecera con
informacin sobre s mismo y sobre el documento solicitado. Veamos un
ejemplo:
Dat e: Sat , 10 J ul 2004 09: 34: 12 GMT
Ser ver : Apache/ 1. 3. 12 ( Uni x) mod_per l / 1. 21
MI ME Ver si on 1. 0
Last - modi f i ed: Sat , 10 J ul 2004 08: 57: 56 GMT
Cont ent - Type: t ext / pl ai n; char set =I SO- 8859- 1
Cont ent - l engt h: 1239
[ l nea en bl anco par a i ndi car f i n de l a cabecer a]
3) A continuacin se envan los datos solicitados. En nuestro caso,
corresponden a un documento HTML (i ndex. ht ml ) con un tamao de
1239 bytes. Pueden tener una forma de este estilo:
<HEAD><TI TLE>Bi enveni do a AI DI MA</ HEAD></ TI TLE>
<BODY>
<H1> I nst i t ut o t ecnol gi co del muebl e y af i nes </ H1>
. . .
Como vemos en los pasos 2 y 3, el documento que solicitamos est encapsulado
mediante MIME (vase 2.8.4). La lnea Ver si on 1. 0 indica al cliente el cuerpo que
vendr luego est codificado con MIME. La lnea Cont ent - t ype: t ext / ht ml es la
manera con que MIME especifica el tipo de documento o recurso solicitado. Si el cliente
no es capaz de trabajar con el tipo de documentos especificado en la cabecera
Cont ent - t ype, no ser capaz de mostrarlos. Como ya vimos, los archivos binarios y
el texto no US-ASCII se pueden codificar en mensajes MIME, de modo que puedan ser
enviados por servidores que slo admitan US-ASCII. Por ejemplo, si el cliente recibe
del servidor una cabecera
Cont ent - Type: t ext / pl ai n; char set =I SO- 8859- 1
Cont ent - t r ansf er - encodi ng: base64
sabr que va a recibir, en el cuerpo del mensaje del servidor, un mensaje codificado a
partir de la codificacin de base 64 y que el mensaje original estaba codificado con
ISO-8859-1 (ISO Latin 1).
Veamos otro ejemplo, correspondiente a un archivo PDF:
Cont ent - t ype: appl i cat i on/ oct et - st r eam; name=Bor r ador . pdf
Cont ent - t r ansf er - encodi ng: base64
CCEhj pVgV5EggkkwRSgXWI YQu0AOi RxI 0Bnf SQDAxR382/ MQP/ PP8OWXh+AZF
Vb5wo6UYM2kaPr / XqE4Cz38DUEsBAj I LFAAAAAgAr owxI 0Bnf SQDwgAAAAI EA
AoAAAAAAAAAAAAAUEsDBBQAAAAI AK6MMSNAZ30kW9kMy0xLnBwdOx9
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 96/313 -
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 Significado
GET Permite acceder a recursos del servidor.
HEAD 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.
POST 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)
Figura 45. Mtodos ms frecuentes del protocolo HTTP
Figura 46. Algunos cdigos de control del protocolo HTTP
CDIGOS DE CONTROL DE HTTP
200 OK
201 Created
202 Accepted
204 No Content
301 Moved Permanently
302 Moved Temporarily
304 Not Modified
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
500 I nternal Server Error
501 Not I mplemented
502 Bad Gateway
503 Service Unavailable
[Link]
Miguel ngel Abin, Julio 2004 - 97/313 -
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 (Ht t pd) suelen requerir que los programas
CGI residan en un directorio / cgi - bi n.
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_STRI NG.
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 ACTI ON 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_STRI NG, 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.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 98/313 -
Figura 47a. Esquema de una comunicacin HTTP sin CGI
[Link]
Miguel ngel Abin, Julio 2004 - 99/313 -
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
Al lector interesado en aprender ms sobre redes y protocolos le recomiendo
estos textos: Computer Networking: A Top-Down Approach Featuring the Internet (2nd
Edition) [J. F. Kurose y K. W. Ross, 2002], Designing TCP/IP Internetworks [Geoff
Bennett, 1995], Data and Computer Communications (4th Edition) [William Stallings,
2000], Internetworking with TCP/IP Vol.1: Principles, Protocols, and Architecture (4th
Edition) [Douglas E. Comer, 2000], Internetworking with TCP/IP Vol. II: ANSI C
Version: Design, Implementation, and Internals (3rd Edition) [Douglas E. Comer y
David L. Stevens, 2000] e Internetworking with TCP/IP, Vol. III: Client-Server
Programming and Applications--BSD Socket Version (2nd Edition) [Douglas E. Comer
y David L. Stevens, 1996].
En el libro Dark Fiber: Tracking Critical Internet Culture (Electronic Culture: History,
Theory, and Practice) [Geert Lovink, 2002] se puede encontrar una interesante visin
de la cultura de Internet.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 100/313 -
3. El paquete [Link] de Java
No es propsito de este apartado proporcionar un estudio minucioso o exhaustivo
sobre el paquete [Link] (no se tratan, por ejemplo, los pipes ni los ficheros de
acceso aleatorio), sino dar una visin general de las clases de Java necesarias para
manejar comunicaciones en red. Al lector interesado en un estudio completo de este
paquete le remito a la documentacin oficial de Sun.
Hasta la aparicin del paquete [Link] en JDK 1.4, la entrada y salida en java
se realizaba exclusivamente mediante [Link]. Su jerarqua de clases se detalla en el
siguiente esquema.
Figura 48. El paquete [Link]
[Link]
Miguel ngel Abin, Julio 2004 - 101/313 -
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 [Link] y [Link] (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.
3.1. La clase [Link]
Una instancia de la clase File, pese a su nombre, es una representacin
abstracta de una ruta de acceso para un archivo o un directorio. Que exista un objeto
de esta clase no implica que exista el archivo (o directorio) correspondiente en el
sistema de archivos.
Sus constructores son
Fi l e ( St r i ng cami no)
Fi l e ( St r i ng padr e, St r i ng hi j o)
Fi l e ( Fi l e padr e, St r i ng hi j o)
Fi l e ( URI ur i )
Ninguno de los cuatro constructores lanzan excepciones: el objeto se crea, exista
o no en el sistema de archivos el archivo o el directorio. Veamos algunos ejemplos de
uso:
/ / Ej empl o del pr i mer const r uct or
/ / La r ut a de acceso es r el at i va
Fi l e ar chi vo = new Fi l e( " t mp. t xt " ) ;
/ / Ej empl o del pr i mer const r uct or
/ / La r ut a de acceso t ambi n es r el at i va
Fi l e ar chi vo = new Fi l e( " / t empor al / t mp. t xt " ) ;
/ / Ej empl o del segundo const r uct or
/ / La r ut a de acceso t ambi n es r el at i va
Fi l e ar chi vo = new Fi l e( " / t empor al " , " t mp. t xt " ) ;
/ / Ej empl o del t er cer const r uct or
/ / La r ut a de acceso t ambi n es r el at i va
Fi l e ar chi vo1 = new Fi l e ( " / t empor al " ) ;
Fi l e ar chi vo2 = new Fi l e ( ar chi vo1, " t mp. t xt " ) ;
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 102/313 -
/ / Ej empl o del pr i mer const r uct or en Wi ndows
/ / La r ut a de acceso es absol ut a
Fi l e ar chi vo = new Fi l e( " C: / t empor al / t emp. t xt " ) ;
Los cuatro primeros ejemplos usan rutas de acceso relativas. Son relativas
porque no bastan por s solas para determinar dnde se encuentran los archivos a los
cuales se refieren. Si en una aplicacin aparece una ruta de acceso relativa, la MVJ
usar el directorio actual del usuario (es decir, el directorio desde donde ejecuta dicha
aplicacin) para formar una ruta de acceso absoluta.
Por ejemplo, si el archivo que contiene el segundo ejemplo se encuentra uso un
sistema Windows en C: / j ava/ j dk15, el constructor se referir a un archivo
t mp. t xt en C: / j ava/ j dk15/ t empor al . En un sistema UNIX, si el archivo se
encuentra en / usr / l ocal / bi n/ j ava/ j dk15, el constructor se referir a un archivo
t mp. t xt en / usr / l ocal / bi n/ j ava/ j dk15/ t empor al .
Para conocer el directorio actual se puede usar este cdigo:
Syst em. get Pr oper t y( " user . di r " ) ) ;
Si se desea conocer la ruta absoluta de un objeto Fi l e ar chi vo, puede usarse
ste:
Syst em. out . pr i nt l n( ar chi vo. get Absol ut ePat h( ) ) ;
En Windows, un resultado tpico de la lnea anterior sera as:
C: \ Document s and Set t i ngs\ mi guel angel \ Mi s
document os\ J avaHi spano\ per sona2. t xt .
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
Fi l e. separ at or Char en lugar de "/" o "\"; Fi l e. separ at or Char es una variable
esttica que devuelve un valor St r i ng que corresponde al separador de archivos en el
sistema utilizado.
El mtodo publ i c bool ean exi st s( ) t hr ows Secur i t yExcept i on
permite saber si el archivo o directorio representado por un objeto Fi l e existe. Como
un objeto Fi l e puede referirse a un archivo o a un directorio, se proporcionan mtodos
Advertencia: Java interpreta "\" dentro de un St r i ng como un carcter de escape.
Por ello, si se quiere indicar la ruta de un archivo Windows situado en
C: / t empor al / t emp. t xt , ser necesario usar un St r i ng
"C: \ \ t empor al \ \ t emp. t xt ". Tambin podran usarse las siguientes opciones:
Fi l e ar chi vo = new Fi l e( " C: / t empor al / t emp. t xt " ) ;
Fi l e ar chi vo = new Fi l e( " C: " + Fi l e. separ at or Char + " t empor al " +
Fi l e. Separ at or Char + " t emp. t xt " ) ;
[Link]
Miguel ngel Abin, Julio 2004 - 103/313 -
para saber si corresponde a un archivo (publ i c bool ean i sFi l e( ) ) o a un
directorio (publ i c bool ean i sDi r ect or y( ) ). Cuando est enlazado a un
directorio, puede obtenerse la lista de los archivos en el directorio con los mtodos
publ i c St r i ng[ ] l i st ( ) t hr ows Secur i t yExcept i on o publ i c Fi l e[ ]
l i st Fi l es( ) t hr ows Secur i t yExcept i on. Veamos un ejemplo:
Fi l e di r ect or i o = new Fi l e( " TEMP" ) ;
St r i ng nombr esAr chi vos[ ] = di r ect or i o. l i st ( ) ;
Fi l e ar chi vos[ ] = di r ect or i o. l i st Fi l es( ) ;
Si el directorio TEMP, relativo respecto al directorio donde se encuentra el archivo
que llam a la MVJ, existe, el array nombr esAr chi vos contendr los nombres de
todos los archivos del directorio, y el array ar chi vos contendr todos los objetos Fi l e
correspondientes a aqul.
El siguiente programa admite como argumento el nombre de un directorio y
muestra, si existe, los nombres de todos sus archivos y subdirectorios (no se tratan las
posibles excepciones):
import [Link].*;
public class ListadoDirectorio {
public static void main(String args[]) throws IOException {
File directorio = new File(args[0]);
if ( ([Link]()) && ([Link]()) ) {
String[] lista = [Link]();
for (int i = 0; i < [Link]; i++ )
[Link](lista[i]);
} else {
[Link]("El directorio no existe");
}
}
}
El siguiente programa admite como argumento en la compilacin el nombre de un
archivo y muestra, si existe, todas sus caractersticas (no se tratan las posibles
excepciones):
import [Link].*;
import [Link].*;
public class InformacionArchivo {
public static void main(String args[]) throws IOException {
Ejemplo 3: [Link]
Ejemplo 4: [Link]
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 104/313 -
File archivo = new File(args[0]);
if ( (archivo. exists()) && ([Link]()) ) {
[Link]("Nombre: " + [Link]());
[Link]("Ruta absoluta " + [Link]());
[Link]("Ruta: " + [Link]());
[Link]("Padre: " + [Link]());
[Link]("Admite lectura? " + [Link]());
[Link]("Admite escritura? " + [Link]());
[Link]("Tamao en bytes: " + [Link]());
[Link]("Fecha de la ltima modificacin: " +
new Date([Link]()));
} else
[Link]("No existe ningn archivo con esa ruta");
}
}
En un ejercicio de metaprogramacin, cuando pido al programa que me diga
cules son sus caractersticas (en mi sistema, con j avac
C: / I nf or maci onAr chi vo. j ava) obtengo esto:
Nombr e: I nf or maci onAr chi vo. j ava
Rut a absol ut a c: \ I nf or maci onAr chi vo. j ava
Rut a: c: \ I nf or maci onAr chi vo. j ava
Padr e: c: \
Admi t e l ect ur a? t r ue
Admi t e escr i t ur a? t r ue
Tamao en byt es: 1187
Fecha de l a l t i ma modi f i caci n: Sun Apr 18 12: 42: 16 CEST 2004
Exi t code: 0
La clase Fi l e no slo es una representacin abstracta de un archivo o de un
directorio: permite crear y eliminar tanto archivos como directorios (siempre que se
cuenten con los permisos necesarios). El mtodo publ i c bool ean
cr eat eNewFi l e( ) t hr ows I OExcept i on, Secur i t yExcept i on permite crear
un nuevo archivo vaco (slo si no exista antes). Si el mtodo devuelve el valor t r ue
es que el archivo fue creado. Este mtodo apenas suele usarse; en su lugar, se
prefiere usar clases como Fi l eOut put St r eamo Fi l eWr i t er , que se vern ms
adelante. El mtodo publ i c bool ean mkdi r ( ) t hr ows Secur i t yExcept i on
permite crear el directorio representado por un objeto Fi l e; devuelve t r ue si pudo
crearse. Por ltimo, el mtodo publ i c bool ean del et e( ) t hr ows
Secur i t yExcept i on puede usarse para borrar un archivo o un directorio; si es un
directorio, debe estar vaco para que la operacin resulte exitosa.
Veamos ahora un ejemplo en el que se crea un archivo en un directorio
especificado; si el directorio no existe, se crea. El camino del directorio y del archivo se
pasan como argumentos en la compilacin; si no hay argumentos, se toman DI R y
ARCHI VO como caminos por defecto.
[Link]
Miguel ngel Abin, Julio 2004 - 105/313 -
import [Link].*;
public class CrearDirectorioYArchivo {
private static String DIR = "c:/temporal"; // directorio en formato Windows
private static String ARCHIVO = "[Link]";
private static void crearArchivoYDirectorio (String dir, String archivo) {
boolean dirCreado = false;
File temp = new File(dir);
if ( ([Link]()) && ([Link]()) ) {
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) {
[Link]("Directorio creado.");
return true;
} else {
[Link]("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) {
[Link]("No pudo crearse el archivo.");
}
if (archCreado) {
[Link]("Archivo creado.");
} else {
[Link]("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
Ejemplo 5: [Link]
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 106/313 -
if (([Link] == 2) && ( (args[0] != "") && (args[1] != "") ) ) {
crearArchivoYDirectorio(args[0], args[1]);
} else {
crearArchivoYDirectorio(DIR, ARCHIVO);
}
}
}
Fi l e tambin nos ofrece el mtodo publ i c URL t oURL( ) t hr ows
I OExcept i on, que convierte el camino representado por el objeto Fi l e en un objeto
[Link] (el paquete [Link] se ver en apartado 8). Podemos usar el
archivo creado antes para ver su URL:
Syst em. out . pr i nt l n( ar chi vo. t oURL( ) . t oSt r i ng( ) ) ;
En mi sistema, el resultado es la cadena f i l e: / C: / t empor al / t mp. t xt .
3.2. La jerarqua de clases [Link]
La superclase raz [Link] proporciona los mtodos bsicos
para leer bytes de un flujo de entrada basado en bytes:
publ i c abst r act i nt r ead( ) t hr ows I OExcept i on
publ i c i nt r ead( byt e[ ] dat os) t hr ows I OExcept i on
publ i c i nt r ead( byt e[ ] dat os, i nt of f set , i nt l ongi t ud)
t hr ows I OExcept i on
El primer mtodo lee un byte sin signo del flujo de entrada y devuelve el valor i nt
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 dat os y devuelve el nmero de bytes ledos. Si encuentra el final del flujo,
devuelve 1.
El tercero lee hasta l ongi t ud bytes del flujo de entrada y los almacena en el
array dat os, comenzando en la posicin indicada por el entero of f set . 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 [Link].
El mtodo publ i c voi d cl ose( ) t hr ows I OExcept i on se encarga de
cerrar el flujo de entrada y de liberar los recursos del sistema usados por el flujo. Esta
clase proporciona un mtodo publ i c i nt avai l abl e( ) t hr ows I OExcept i on
que devuelve el nmero de bytes que pueden leerse sin bloqueo del flujo de entrada.
[Link]
Miguel ngel Abin, Julio 2004 - 107/313 -
Veamos un ejemplo muy sencillo del funcionamiento de la clase I nput St r eam
(se ha omitido el tratamiento de las excepciones):
import [Link].*;
public class Entrada {
public static void main (String args[]) throws IOException {
int byteLeido;
InputStream entrada = ([Link]); // [Link] es una referencia a un
// objeto InputStream definido por el sistema
while (true) {
byteLeido = [Link]();
if (byteLeido == -1) {
[Link]("Se ley todo el flujo. FIN DEL PROGRAMA.");
[Link](0);
}
char caracter = (char) byteLeido;
[Link](caracter);
[Link](" ");
}
}
}
El programa lee los datos de la entrada, y usa los valores i nt devueltos para
obtener los caracteres de la entrada, que se presentan separados por espacios en
blanco. Java ofrece un objeto I nput St r eam(cuya referencia es Syst em. i n) 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 publ i c i nt r ead( byt e[ ] dat os) , lo que permitira
leer de golpe un nmero mximo de bytes igual al tamao del array dat os; pero
[Link] ofrece mejores soluciones, tal como veremos enseguida.
Nota: Cuando se dice que una clase o un mtodo utiliza
objetos I nput St r eam(que es una clase abstracta), no quiere
decirse que use una instancia de la clase (por definicin, una
clase abstracta no es instanciable); sino que usa instancias de
las subclases no abstractas de I nput St r eam. Un mtodo que
tenga como argumento un I nput St r eamaceptar cualquier
objeto que sea instancia de una subclase no abstracta de
I nput St r eam. Una clase como I nput St r eam (u
Out put St r eam) proporciona una interfaz comn para todas
sus subclases.
Ejemplo 6: [Link]
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 108/313 -
Antes de continuar con la clase I nput St r eam, me adelanto a una objecin que
se me puede hacer, resumible en dos preguntas: qu tienen que ver clases como
sta con las comunicaciones en red?, por qu se explican aqu? Se me puede
decir, con toda razn, que al fin y al cabo son las clases de E/S de toda la vida (al
menos, de la vida del lenguaje Java). S, as es: no hay ms cera que la que arde; pero
Java no necesita ms cera para alumbrar las tenebrosas catacumbas de las
comunicaciones en red. Tal como escrib ya en la introduccin, se cumple que el
proceso de transferir informacin a travs de redes es tan sencillo o tan difcil como
leer ficheros o escribir en ellos. Recibir datos a travs de una red (sea Internet, una
extranet o una intranet) apenas difiere de leerlos de un archivo sito en la mquina local;
lo mismo vale para enviarlos. As pues, no me parece mala idea hacer un rpido repaso
de las clases ms usadas de la E/S estndar de Java.
Como prueba fidedigna de lo dicho, reproduzco a rengln seguido la versin en
red, cliente-servidor, de la clase Ent r ada. La clase Out put St r eam se ver en el
siguiente subapartado; pero por su nombre se puede intuir que es la complementaria
de I nput St r eam; Ser ver Socket y Socket se vern en el apartado 8.
import [Link].*;
import [Link].*;
public class EntradaRed {
//Versin para red de la clase Entrada
public static void main (String args[]) throws IOException {
int byteLeido;
InputStream entrada = ([Link]);
Socket socket = new Socket("localhost", 9000);
OutputStream salida = [Link]();
while (true) {
byteLeido = [Link]();
Advertencia: Pensando en el rendimiento, podra pensarse que se puede usar el
mtodo aval ai bl e( ) en combinacin con el uso de un array de bytes, de un
modo similar a ste:
/ / ent r ada es un obj et o del t i po I nput St r eam
i nt capaci dad = ent r ada. aval ai bl e( ) ;
i f ( capaci dad > 0) {
byt e dat os[ ] = new byt e( capaci dad) ;
ent r ada. r ead( dat os) ;
}
Aunque la documentacin de Sun para esta clase no lo explica, usar cdigo similar
al anterior no es conveniente. Para algunas MVJ y algunos flujos de E/S,
aval ai bl e( ) siempre devuelve cero. Uno puede llevarse la desagradable
sorpresa de comprobar que el cdigo de E/S que funciona bien en una plataforma
falla estrepitosamente en otra.
Ejemplo 7a: [Link]
[Link]
Miguel ngel Abin, Julio 2004 - 109/313 -
if (byteLeido == -1) {
[Link]("Se ley todo el flujo. FIN DEL PROGRAMA.");
[Link](0);
}
[Link](byteLeido);
}
}
}
import [Link].*;
import [Link].*;
public class ServidorRed {
//Servidor para la aplicacin EntradaRed
public static void main(String args[]) throws IOException {
int byteLeido;
ServerSocket socketServidor = new ServerSocket(9000);
Socket socketCliente = [Link]();
InputStream entrada = [Link]();
while (true) {
byteLeido = [Link]();
if (byteLeido == -1) {
[Link]("Se ley todo el flujo. FIN DEL PROGRAMA.");
[Link](0);
}
char caracter = (char) byteLeido;
[Link](caracter);
[Link](" ");
}
}
}
En esta aplicacin, el texto escrito por el cliente se manda al servidor, que lo
muestra por pantalla. Si se desea ejecutar el cliente en una mquina distinta de aquella
donde se ejecuta el servidor, habr que modificar la lnea
Socket socket = new Socket ( " l ocal host " , 9000) ;
y escribir, en lugar de l ocal host , el nombre de la mquina donde se ejecute la
aplicacin de servidor. Exceptuando el uso de sockets, el cdigo de E/S es idntico al
que apareca en la clase Ent r ada. Por regla general, las clases del paquete
[Link] ofrecen al programador un I nput St r eamo un Out put St r eampara poder
enviar o recibir datos. En aplicaciones ms sofisticadas que la anterior no se utilizan
directamente las clases I nput St r eamy Out put St r eam, pues se limitan a permitir la
lectura y escritura de bytes. Como veremos en este apartado, hay muchas ms clases
en [Link] que permiten envolver a I nput St r eamo a Out put St r eamy ofrecer
ms posibilidades al programador.
Ejemplo 7b: [Link]
Tngase muy en cuenta la
advertencia de la pgina 111
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 110/313 -
Figura 49. El cliente del ejemplo 7
Figura 50. El servidor del ejemplo 7
Texto enviado por el
cliente
Texto mostrado por
el servidor
[Link]
Miguel ngel Abin, Julio 2004 - 111/313 -
Figura 51. La jerarqua de clases InputStream
En la jerarqua de clases de la figura aparecen varias clases (faltan algunas). Las
ms importantes son [Link], [Link]
y [Link]. La primera permite leer bytes a partir del flujo de
entrada obtenido de un archivo; la segunda permite deserializar datos de tipos
primitivos y objetos serializados antes usando [Link].
[Link] es una clase mucho ms misteriosa que las otras: es
un decorador. Para no interrumpir la exposicin de las clases elementales de E/S, el
patrn observador se explicar ms adelante. Por ahora, es suficiente con saber que
las subclases de Fi l t er I nput St r eamproporcionan nuevas funciones a las clases a
las cuales "decoran" o "envuelven".
Las instancias de las subclases de Fi l t er I nput St r eam(en la figura faltan
[Link] y [Link])
permiten la lectura de un flujo y la escritura en otro, alterando los datos en el paso de
Advertencia: El cdigo de la parte a) del ejemplo 7 slo debe
tenerse en cuenta como ejemplo. Ninguna aplicacin que vaya
a funcionar en el mundo real debera considerar el envo de
caracteres (o de bytes) individuales. Enviar un solo carcter
cada vez comporta mandar un datagrama completo a travs
de la red para cada carcter, lo cual es tremendamente
ineficaz. En estas ocasiones, el uso de buffers se hace
imprescindible.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 112/313 -
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.
Figura 52. Lectura de un archivo mediante la clase FileInputStream
Un Buf f er edI nput St r eamusa un array interno de almacenamiento temporal
(buffer) para el flujo de entrada. Cuando se crea un Buf f er edI nput St r eam, se crea
tambin un array interno de almacenamiento de bytes. Cada vez que se llama a un
mtodo r ead( ) , los bytes se leen del array de almacenamiento; segn se van leyendo
bytes, el array se vuelve a rellenar con bytes del flujo de entrada, ledos de golpe. As
se evita tener que leer y almacenar byte a byte (y llamar cada vez a los metodos
nativos del sistema operativo sobre el cual trabaja la mquina virtual Java), lo cual
mejora mucho el rendimiento de la E/S. Siempre que se pueda, interesa manejar clases
de E/S que trabajen con buffers. Analizemos, como ejemplo, el siguiente cdigo:
Buf f er edI nput St r eambi s = new
Buf f er edI nput St r eam( obj et oI nput St r eam, 1024)
bi s. r ead( )
Con el constructor, se ha creado un buffer de 1024 bytes de tamao. Al llamar por
primera vez a r ead( ) , se intentar llenar por completo el buffer a partir del flujo de
entrada. En las siguientes llamadas, se leer directamente del buf f er , que se ir
rellenando, cuando convenga, con los bytes del flujo de entrada.
Bytes
FileInputStream( Stringfile )
read( byte[] );
close();
Bytes
FileInputStream( Stringfile )
read( byte[] );
close();
FileInputStream(Stringfile)
read(byte[]);
close();
Manera ms simple de
leer losbytesde un
archivo con la clase
Fi l eI nput St r eam
Archivo
LECTURA DE LOS BYTES DE UN ARCHIVO
[Link]
Miguel ngel Abin, Julio 2004 - 113/313 -
public class [Link] {
// Constructor
public DataInputStream( InputStream is );
public final int read( byte b[] );
public final boolean readBoolean();
public final byte readByte();
public final char readChar();
public final short readShort();
public final long readLong();
public final int readInt();
public final float readFloat();
public final double readDouble();
public final String readLine();
public final String readUTF();
public final int skipBytes( int n );
}
Dat aI nput St r eamincorpora mtodos para leer bytes y arrays de bytes, al igual
que I nput St r eam; pero adems incluye mtodos para leer caracteres, St r i ngs,
nmeros (enteros, de punto flotante...), etc. Todos los mtodos empiezan con read:
r eadBool ean( ) , r eadByt e( ) , r eadChar ( ) ..., excepto ski pByt es( ) .
Figura 53. La interfaz de la clase DataInputStream
Un objeto Fi l eI nput St r eam(que representa un flujo de entrada que proviene
de un archivo) puede ser decorado por otro Buf f er edI nput St r eam para
proporcionar la capacidad de admitir buffers (memorias de almacenamiento temporal) y
aadir dos nuevos mtodos (publ i c voi d mar k( i nt l i mi t el ect ur a) y
publ i c voi d r eset ( ) ). Al crear un objeto de esta clase, la mquina virtual Java
(MVJ) intenta abrir el archivo; en el caso de que no exista, se lanza una excepcin
Fi l eNot FoundExcept i on. Si no se puede acceder al archivo por motivos de
seguridad, se arroja una excepcin Secur i t yExcept i on.
En el subapartado dedicado a la clase Out put St r eamse pondrn ejemplos del
uso de los objetos Obj ect I nput St r eam.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 114/313 -
A continuacin se expone un programa de ejemplo del uso combinado de
Buf f er edI nput St r eamy Fi l eI nput St r eam, el cual permite leer un archivo de
texto (situado en el directorio donde se ejecuta la clase) y mostrar su contenido en
pantalla:
import [Link].*;
public class LeerCaracter {
public static void main(String[] args) {
Advertencia: Cuando se cierra mediante el mtodo cl ose( ) un objeto que
envuelve a otros, se producen dos acciones:
- El primer objeto enva al objeto que envuelve la informacin que pudiera tener
almacenada.
- Se llama al mtodo cl ose( ) del objeto envuelto.
A su vez, si el segundo objeto envuelve a otros, se contina el proceso arriba
descrito hasta que se llega al ltimo.
Veamos qu sucede cuando se ejecuta el siguiente cdigo:
Fi l e ar chi vo = new Fi l e( " t empor al . t xt " ) ;
Fi l eOut put St r eamf os = new Fi l eOut put St r eam( ar chi vo) ;
Buf f er edOut put St r eambos = new Buf f er edOut put St r eam( f i s) ;
/ / Oper aci ones de escr i t ur a
bos. cl ose( ) ;
Al llegar a la ltima lnea, se produce la siguiente secuencia de acciones:
Cualquier dato que an est en el objeto bos se enva a f os.
Se llama al mtodo cl ose( ) de f os.
Cualquier dato que an permanezca en f os se enva a ar chi vo, donde
se escribir.
Se cierra f os.
Se cierra bos.
Si en lugar de llamar primero al mtodo cl ose( ) de bos se llamara al cl ose( ) de
ar chi vo, los datos que todava quedaran en f os o bos (por el uso de buffers
internos) no podran escribirse ya en el archivo, pues el objeto que hace referencia a
l se habra cerrado antes.
Por lo tanto, es recomendable cerrar siempre slo el objeto ms decorado (el
ltimo o ms externo).
Ejemplo 8: [Link]
[Link]
Miguel ngel Abin, Julio 2004 - 115/313 -
BufferedInputStream entrada = null;
try {
// Si el archivo de texto [Link] no existe hay que crearlo
// previamente o cambiar el camino para que se refiera a un archivo
// existente.
File archivo = new File("[Link]");
entrada = new BufferedInputStream(new FileInputStream(archivo));
while (true) {
int temp = [Link]();
if (temp == -1) {
[Link]("");
[Link]("Se ley todo el archivo.");
break;
}
char caracter = (char) temp;
[Link](caracter);
}
}
catch(IOException e1) {
[Link]();
}
finally {
try {
[Link]();
}
catch (Exception e2) {
[Link]("No pudo cerrarse el flujo.");
}
}
}
}
Si el lector prescinde del decorador Buf f er edOut put St r eamy decide usar
directamente el mtodo wr i t e( ) de la clase Fi l eOut put St r eam, notar cuando
use valores elevados de N la diferencia de rendimiento ocasionada por no usar
buffers.
Es necesaria una excepcin
distinta a IOException, pues
se podra arrojar una
excepcin del tipo
NullPointerException
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 116/313 -
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:
t r y {
/ / Rest o cdi go
ent r ada = new Buf f er edI nput St r eam(
new Fi l eI nput St r eam( ar chi vo) ) ;
/ / Cdi go t r at ami ent o de l a E/ S
ent r ada. cl ose( ) ;
}
cat ch ( I OExcept i on e) {
/ / Tr at ami ent o del er r or
}
aparecera el problema de que podra lanzarse una excepcin antes del
ent r ada. cl ose( ) , con lo que no se liberaran los recursos destinados al flujo. Con los
ejemplos de este apartado no es importante el consumo de recursos; pero es algo que
debe tenerse muy en cuenta cuando se programan aplicaciones que hacen un uso
intensivo de la E/S.
Para hacer un tratamiento exhaustivo de cualquier posible excepcin debera usarse
cdigo similar a ste (por motivos de espacio, coloco en la misma lnea el corchete de
cierre de t r y y la sentencia cat ch asociada):
t r y {
Fi l e ar chi vo = new Fi l e( ) ;
} cat ch ( I OExcept i on e1) {
/ / Se t r at an l as excepci ones der i vadas de Fi l e
}
t r y {
Fi l eI nput St r eamf i s = new Fi l eI nput St r eam( ar chi vo) ;
} cat ch ( I OExcept i on e2) {
/ / Se t r at an l as excepci ones der i vadas de Fi l eI nput St r eam
}
t r y {
Buf f er edI nput St r eament r ada = new Buf f er edI nput St r eam( f i s) ;
} cat ch ( I OExcept i on e3) {
/ / Se t r at an l as excepci ones der i vadas de Buf f er edI nput St r eam
}
t r y {
/ / Cdi go de mani pul aci n del obj et o ent r ada
} cat ch ( I OExcept i on e4) {
/ / Se t r at an l as excepci ones del cdi go que mani pul a a ent r ada
}
f i nal l y {
ent r ada. cl ose( ) ;
} cat ch ( Except i on e4) {
/ / Se t r at an l as excepci ones al i nt ent ar cer r ar ent r ada
}
As nos aseguraramos que ningn recurso se quedara en el aire, sucediera lo que
sucediera. De la manera que aparece el tratamiento de las excepciones en el listado de la
pgina anterior, algn recurso (un objeto Fi l e) podra quedase sin limpiar si no se pudiera
crear un objeto Buf f er edReader (por falta de memoria, por ejemplo). Recomiendo esta
prctica para cualquier aplicacin que abuse de la E/S; pero no la sigo aqu porque
alargara en exceso el cdigo de los ejemplos, sin facilitar su comprensin.
[Link]
Miguel ngel Abin, Julio 2004 - 117/313 -
3.3. La jerarqua de clases [Link]
La superclase raz [Link] proporciona los mtodos bsicos
para escribir bytes en un flujo de salida basado en bytes (todos ellos son bloqueantes):
publ i c abst r act voi d wr i t e( i nt byt e) t hr ows I OExcept i on
publ i c voi d wr i t e( byt e[ ] dat os) t hr ows I OExcept i on
publ i c voi d wr i t e( byt e[ ] dat os, i nt of f set , i nt l ongi t ud)
t hr ows I OExcept i on
El primer mtodo escribe un nico byte en un flujo de salida. El segundo escribe
un array de bytes, y el tercero escribe l ongi t ud bytes del array dat os, comenzando
por la posicin indicada por el entero of f set .
Los sistemas operativos utilizan buffers internos para evitar tener que escribir los
bytes de uno en uno. As pueden escribir decenas o cientos de bytes de golpe, lo cual
redunda en un mejor rendimiento del sistema. Esta clase dispone de un mtodo
(publ i c voi d f l ush( ) t hr ows I OExcept i on) que obliga a escribir todos los
bytes que haya en el buffer, est lleno o no. El tamao exacto de cada buffer depende
del sistema operativo usado y de la implementacin de la mquina virtual Java.
Out put St r eam tambin dispone de un mtodo publ i c voi d cl ose( )
t hr ows I OExcept i on, que se encarga de cerrar el flujo de salida y de liberar los
recursos del sistema usados por el flujo.
Syst em. out (el flujo de entrada estndar) y Syst em. er r (el flujo de salida
estndar de los errores) son objetos Out put St r eam. Ms especficamente, son
objetos Pr i nt St r eam.
Figura 54. La jerarqua de clases OutputStream
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 118/313 -
public class [Link] {
// Constructor
public DataOutputStream( OutputStream os );
public void flush();
public void write( byte b[], int off, int len);
public final void writeBoolean( bollean v );
public final void writeByte( int v );
public final void writeBytes( String s );
public final void writeChar( int v );
public final void writeChars( String s );
public final void writeShort( int v );
public final void writeLong( long v );
public final void writeInt( int v );
public final void writeFloat( float v );
public final void writeDouble( double v );
public final void writeUTF( String str );
}
En la jerarqua de clases derivadas de la superclase base Out put St sr eamque
aparece en la figura aparecen varias clases (faltan algunas). Las ms importantes son
[Link], [Link] y
[Link]. La primera permite escribir bytes en el flujo de
salida asociado a un archivo; la segunda permite serializar datos de tipos primitivos y
objetos. Como era de esperar, Fi l t er Out put St r eames un decorador. Las instancias
de las subclases de Fi l t er Out put St r eam (en la figura faltan
[Link] y [Link])
permiten decorar los objetos a los que envuelven.
Dat aOut put St r eamincorpora mtodos para escribir bytes y arrays de bytes, al
igual que Out put St r eam; pero adems incluye mtodos para escribir caracteres,
St r i ngs, nmeros (enteros, de punto flotante...), etc. Todos los mtodos empiezan
con write: wr i t eBool ean( ) , wr i t eByt e( ) , wr i t eChar ( ) ...,excepto f l ush( ) .
Figura 55. La interfaz de la clase DataInputStream
Fi l eOut put St r eam complementa a Fi l eI nput St r eam. Con respecto a esta
ltima, presenta una diferencia: sus constructores, a diferencia de los de
Fi l eI nput St r eam, no arrojan excepciones del tipo Fi l eNot FoundExcept i on; si el
archivo no existe, Fi l eOut put St r eamlo crea. En caso de que el archivo s exista y
se utilice el constructor que aparece en la siguiente lnea de cdigo:
Fi l eOut put St r eamf os = new Fi l eOut put St r eam( f i cher o) ;
[Link]
Miguel ngel Abin, Julio 2004 - 119/313 -
hay que tener en cuenta que, con la primera llamada a wr i t e( ) , 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:
Fi l eOut put St r eamf os = new Fi l eOut put St r eam( f i cher o, t r ue) ;
La clase Pr i nt St r eamincluye varios mtodos publ i c voi d pr i nt ( ) y
publ i c voi d pr i nt l n( ) para imprimir (en el sentido de mostrar al usuario por la
salida estndar) cualquier valor de un objeto o un tipo primitivo.
Los mtodos pr i nt ( ) convierten el argumento en un St r i ng 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 wr i t e( ) .
Los mtodos pr i nt l n( ) hacen exactamente lo mismo que los pr i nt ( ) , pero
incluyen un carcter de nueva lnea ("\n", "r" o "r\n"; depende de la plataforma).
Los objetos Pr i nt St r eam 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, [Link] (el flujo de entrada
estndar) y [Link] (el flujo de salida estndar de los errores) son objetos
Pr i nt St r eam. Sera bastante incmodo para un programador tener que escribir
cdigo para manejar las excepciones cada vez que escriba lneas inofensivas como
Syst em. out . pr i nt l n( " J AVA" ) . 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 publ i c bool ean
checkEr r or ( ) .
Un objeto Buf f er edOut put St r eam puede decorar a un Out put St r eam,
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 f l ush( ) , que fuerza a escribir, est o no
lleno). Su funcionamiento no difiere mucho del correspondiente a la clase
Buf f er edI nput St r eam, vista en el subapartado anterior: las llamadas a wr i t e( )
van almacenando los datos en el buffer, que slo se escribir cuando est lleno (o se
llame a f l ush( ) ). A continuacin, se muestra un ejemplo del uso combinado de las
clases Buf f er edOut put St r eamy Fi l eOut put St r eam, el cual escribe N veces las
letras A y B en un archivo.
import [Link].*;
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;
Ejemplo 9: [Link]
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 120/313 -
try { // Si el archivo no existe, lo crea (si puede).
File archivo = new File("[Link]");
salida = new BufferedOutputStream(new FileOutputStream(archivo));
for (int i=0; i<N; i++) {
[Link]( (int) 'A'); // Escribe el byte correspondiente al carcter 'A'
}
[Link](); // Se fuerza a vaciar el buffer
[Link](); // Se cierra el flujo de salida
// Ahora se aade N veces la letra B; usando el constructor con true se
// se consigue que se aada despus de las letras A, sin eliminarlas
salida = new BufferedOutputStream(new FileOutputStream(archivo, true));
[Link] ( (int) '\t'); //Se aade un tabulador
for (int i=0; i<N; i++) {
[Link]( (int) 'B'); // Escribe el byte correspondiente al carcter 'B'
}
[Link]();
}
catch(IOException e1) {
[Link]();
}
finally {
try {
[Link]();
}
catch (Exception e2) {
[Link]("No se pudo cerrar el flujo");
}
} // fin del bloque try-catch-finally
}
}
La clase Obj ect Out put St r eam es una clase muy importante para las
comunicaciones en red: permite serializar objetos (Obj ect I nput St r eampermite
deserializarlos). Serializar es la accin de codificar un objeto en un flujo de bytes;
deserializar es la accin de decodificar un flujo de bytes para reconstruir una copia del
objeto original. Esencialmente, serializar un objeto equivale a guardar (y luego poder
cargar) el estado de un objeto. La serializacin es un mecanismo de implementacin de
la persistencia de objetos. Uso persistencia (de un objeto) en el sentido de capacidad
de un objeto para persistir en el tiempo y en el espacio, independientemente de la
MVJ que lo cre. El flujo de bytes que produce la serializacin de un objeto se puede
enviar a mquinas remotas mediante sockets o se puede guardar en un archivo. Para
poder reconstruir correctamente un objeto, el proceso de serializacin tambin
almacena en el flujo de bytes la descripcin de la clase a la que pertenece el objeto.
Bruce Eckel explica as la serializacin en Java (Thinking in Java 3rd Edition):
La serializacin de objetos en Java le permite tomar cualquier objeto
que implemente la interfaz Ser i al i zabl e y convertirlo en una secuencia
de bytes que puede restaurarse completamente ms tarde para regenerar el
objeto original. Esto es cierto incluso a travs de una red, lo que significa que
el mecanismo de la serializacin compensa automticamente las diferencias
entre sistemas operativos. Esto es, puede crear un objeto en una mquina
Windows, serializarlo y enviarlo a travs de la red a una mquina Unix donde
[Link]
Miguel ngel Abin, Julio 2004 - 121/313 -
ser reconstruido correctamente. No tiene que preocuparse sobre las
representaciones de los datos en las diferentes mquinas, el orden de los
bytes o cualquier otro detalle.
Por s misma, la serializacin de objetos es interesante porque le
permite implementar persistencia ligera. Recuerde que la persistencia
significa que el tiempo de vida de un objeto no est determinado por si un
programa se est ejecutando; el objeto vive entre las invocaciones del
programa. Tomando un objeto serializable y escribindolo en el disco, y
entonces restaurando ese objeto cuando el programa es reinvocado, puede
producir el efecto de persistencia. El motivo por el que se llama ligera es
que no puede simplemente definir un objeto y usar alguna clase de palabra
reservada persistent y dejar que el sistema se preocupe de los detalles
(aunque esto podra ocurrir en el futuro). En lugar de eso, debe
explcitamente serializar y deserializar los objetos en su programa.
Una caracterstica sumamente interesante de la serializacin estriba en su
capacidad de congelar objetos vinculados y de hacer que retornen a su estado original,
aunque la mquina de destino est a miles de kilmetros de la maquina donde se
crearon originalmente los objetos. Cuando se serializa un objeto, se serializan tambin
todos los objetos a los que tenga referencias (los cuales deben, por tanto, implementar
tambin la interfaz Ser i al i zabl e); como es lgico, al deserializarlo se reconstruyen
tambin los objetos vinculados. Esta propiedad abre posibilidades muy interesantes
para los programadores: mareas enteras de objetos interconectados de muchas
maneras pueden almacenarse y recuperarse cuando se necesiten. Si se intentar
simular la serializacin de un objeto mediante la clase Dat aOut put St r eam, se
precisara guardar cada dato de tipos simples (i nt , doubl e, f l oat ...) contenido en el
objeto, as como los datos de tipos simples que contuvieran los objetos a los cuales
contiene referencias. Se puede trabajar as, pero sera tarea muy tediosa y propensa a
errores.
Cuando se deserializa un flujo de bytes, se llama al mtodo pr ot ect ed Cl ass
r esol veCl ass( Obj ect St r eamCl ass descr i pci on) t hr ows I OExcept i on,
Cl assNot FoundExcept i on de la clase Obj ect I nput St r eam para que cargue
dinmicamente los bytecodes de las clases cuyas descripciones encuentra en el flujo
(suponiendo que no los hubiera cargado antes). Este mtodo llama al cargador de
clases de Java, el cual es el verdadero encargado de buscar los archivos . cl ass
necesarios y de cargar dinmicamente sus bytecodes. El cargador de clases busca, en
primer lugar, en el directorio actual (aquel desde el cual se ejecut la aplicacin), y si
no los encuentra sigue buscando en los directorios indicados en el CLASSPATH. Si
finalmente no encuentra los . cl ass que se necesitan, lanza una excepcin
[Link]. Siempre interesa configurar el CLASSPATH
local para que incluya todos los directorios donde estn los archivos . cl ass de las
clases que se necesitarn durante el proceso de deserializacin, pues no es habitual
que estn todos en el directorio desde el cual se lanza la aplicacin.
La relacin entre la serializacin de objetos y la RMI (Remote Method Invocation:
ejecucin remota de mtodos) se detallar en el apartado 5.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 122/313 -
La mejor manera de ver cmo funciona la serializacin es mediante un ejemplo
completo. En l veremos cmo se graban objetos Per sona en un archivo llamado
per sonas. t xt (si no existe, se crea), ubicado en el directorio donde se ejecuta
Escr i bi r Per sona.
import [Link].*;
public class EscribirPersona {
public static void main(String args[]) {
FileOutputStream archivo = null;
ObjectOutputStream salida = null;
Persona p1= new Persona("Louis Ferdinand Cline", 67);
Persona p2= new Persona("Andr Breton", 69);
Persona p3= new Persona("Andr Malraux", 71);
try {
archivo = new FileOutputStream("[Link]");
salida = new ObjectOutputStream(archivo);
[Link](p1);
[Link](p2);
[Link](p3);
[Link]();
}
catch (IOException e1) {
[Link]("Imposible crear el archivo o escribir en l.");
[Link]();
}
finally {
try {
[Link]();
}
catch (Exception e2) {
[Link]("No pudo cerrarse el flujo.");
}
} // fin del bloque try-catch-finally
}
}
class Persona implements Serializable {
private String nombre;
private int edad;
public Persona (String nombre, int edad) {
[Link] = nombre;
[Link] = edad;
}
Ejemplo 10a: [Link]
[Link]
Miguel ngel Abin, Julio 2004 - 123/313 -
public String toString() {
return ("Nombre: " + nombre +"; Edad: " + edad);
}
}
Per sona implementa la interfaz Ser i al i zabl e porque, tal como se dijo,
cualquier objeto que pueda ser serializado (y deserializado) debe implementarla.
import [Link].*;
public class LeerPersona {
public static void main(String args[]) {
FileInputStream archivo = null;
ObjectInputStream entrada = null;
try {
archivo = new FileInputStream("[Link]");
entrada = new ObjectInputStream(archivo);
Object tmp = [Link]();
while (tmp != null) {
Persona persona = (Persona) tmp;
[Link] ([Link]());
tmp = [Link]();
}
}
catch (EOFException e1) {
[Link]("Archivo ledo");
}
catch (Exception e2) {
[Link]("Imposible abrir el archivo o leer de l.");
[Link]();
}
finally {
try {
[Link]();
}
catch (Exception e3) {
[Link]("No pudo cerrarse el flujo");
}
} //fin del bloque try-catch-finally
}
}
Para que el cdigo funcione correctamente, se necesita ejecutar Leer Per sona
desde el mismo directorio donde se ejecuta Escr i bi r Per sona o configurar el
CLASSPATH para que Leer Per sona tenga acceso al archivo Per sona. cl ass
(generado al compilar la clase Escr i bi r Per sona), y despus de ejecutar esta ltima
al menos una vez. Hecho esto, veremos que los escritores han resucitado.
Ejemplo 10b: [Link]
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 124/313 -
Figura 56. El ejemplo 10 en funcionamiento
No hay ningn obstculo para serializar a travs de redes. A continuacin incluy
el cdigo de la versin de red correspondiente al ejemplo anterior para que el lector vea
su forma. En el apartado 8 se explicarn los mtodos correspondientes a clases del
paquete [Link].
Tal y como est escrito, se considera que el cliente y el servidor se ejecutan en la
misma mquina. Si se desea ejecutar Escr i bi r Per sonaRed en una mquina distinta
de aquella donde se ejecuta Leer Per sonaRed, habr que modificar la lnea
Socket socket = new Socket ( " l ocal host " , 9000) ;
y escribir, en lugar de l ocal host , el nombre de la mquina donde se vaya a ejecutar
Leer Per sonaRed. Adems, ser necesario colocar el archivo Per sona. cl ass en
esta ltima mquina de manera que Leer Per sonaRed pueda acceder a ella cuando
se ejecute.
[Link]
Miguel ngel Abin, Julio 2004 - 125/313 -
import [Link].*;
import [Link].*;
public class EscribirPersonaRed {
// Versin en red de la clase EscribirPersona.
// Los mtodos de ServerSocket y Socket se explicarn ms adelante.
public static void main(String args[]) {
OutputStream salida = null;
ObjectOutputStream salidaObjeto = null;
Socket socket = null;
Persona p1= new Persona("Louis Ferdinand Cline", 67);
Persona p2= new Persona("Andr Breton", 69);
Persona p3= new Persona("Andr Malraux", 71);
try {
socket = new Socket("localhost", 9000);
salida = [Link]();
}
catch (IOException e1) {
[Link]("No fue posible establecer la conexin con el servidor." +
"Error fatal.");
[Link](-1);
}
try {
salidaObjeto = new ObjectOutputStream(salida);
[Link](p1);
[Link](p2);
[Link](p3);
[Link]();
}
catch (IOException e2) {
[Link]("Imposible escribir los objetos en el servidor.");
[Link]();
}
finally {
try {
[Link]();
[Link]();
}
catch (Exception e3) {
[Link]("No pudo cerrarse el flujo o el socket, o ninguno.");
}
} // fin del bloque try-catch-finally
}
}
Ejemplo 11a: [Link]
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 126/313 -
import [Link].*;
class Persona implements Serializable {
// Esta clase tiene que estar en el mismo directorio que EscribirPersonaRed y
// LeerPersonaRed o debe configurarse el CLASSPATH para incluirla.
private String nombre;
private int edad;
public Persona (String nombre, int edad) {
[Link] = nombre;
[Link] = edad;
}
public String toString() {
return ("Nombre: " + nombre +"; Edad: " + edad);
}
}
import [Link].*;
import [Link].*;
public class LeerPersonaRed {
// Versin en red de la clase LeerPersona. Debe ejecutarse antes que EscribirPersonaRed.
// Es un mero ejemplo, pues slo permite que se conecte un cliente (no usa hilos).
// Los mtodos de ServerSocket y Socket se explicarn ms adelante.
public static void main(String args[]) {
InputStream entrada = null;
ObjectInputStream entradaObjeto = null;
ServerSocket socketServidor = null;
Socket socketCliente = null;
try {
socketServidor = new ServerSocket(9000);
socketCliente = [Link]();
entrada = [Link]();
[Link]("Entrada desde la direccin " + [Link]());
}
catch (IOException e1) {
[Link]("No fue posible arrancar el servidor. Error fatal.");
[Link](-1);
}
try {
entradaObjeto = new ObjectInputStream(entrada);
Object tmp = [Link]();
while (tmp != null) {
Ejemplo 11c: [Link]
Ejemplo 11b: [Link]
[Link]
Miguel ngel Abin, Julio 2004 - 127/313 -
Persona persona = (Persona) tmp;
[Link] ([Link]());
tmp = [Link]();
}
}
catch (EOFException e2) {
[Link]("Se han ledo correctamente todos los datos.");
}
catch (Exception e3) {
[Link]("Imposible leer del cliente.");
[Link]();
}
finally {
try {
[Link]();
[Link]();
[Link]();
}
catch (Exception e4) {
[Link]("No pudo cerrarse el flujo o el socket, o ninguno.");
}
} //fin del bloque try-catch-finally
}
}
Figura 57. El ejemplo 11 en funcionamiento
Direccin IP de
la mquina local
(localhost)
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 128/313 -
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.
import [Link].*;
import [Link].*;
public class SerializarHashMap {
private static Map hashmap = null;
private static FileOutputStream archivo = null;
private static ObjectOutputStream salida = null;
// Objetos con los que se rellena la lista
private static Persona p1 = null;
private static Persona p2 = null;
private static Persona p3 = null;
private static String s1 = null;
private static String s2 = null;
private static Integer i1 = null;
private static Double d1 = null;
public static void inicializarElementos() {
p1= new Persona("Louis Ferdinand Cline", 67);
p2= new Persona("Andr Breton", 69);
p3= new Persona("Andr Malraux", 71);
s1 = "Yo no soy escritor";
s2 = "Se acab este conjunto tan hetergeneo";
i1 = new Integer(100);
d1 = new Double (3456.3879563);
}
public static void cargarElementos() {
hashmap = new HashMap();
[Link]("uno", p1);
[Link]("dos", p2);
[Link]("tres", p3);
[Link]("cuatro", s1);
[Link]("cinco", i1);
[Link]("seis", d1);
[Link]("siete", s2);
}
public static void serializar() {
try {
archivo = new FileOutputStream("[Link]");
Ejemplo 12a: [Link]
[Link]
Miguel ngel Abin, Julio 2004 - 129/313 -
salida = new ObjectOutputStream(archivo);
[Link](hashmap);
[Link]();
}
catch (IOException e1) {
[Link]("Imposible crear el archivo o escribir en l.");
[Link]();
}
finally {
try {
[Link]();
}
catch (Exception e2) {
[Link]("No pudo cerrarse el flujo.");
}
} // fin del bloque try-catch-finally
}
public static void main(String args[]) {
inicializarElementos();
cargarElementos();
serializar();
}
}
class Persona implements Serializable {
private String nombre;
private int edad;
public Persona (String nombre, int edad) {
[Link] = nombre;
[Link] = edad;
}
public String toString() {
return ("Nombre: " + nombre +"; Edad: " + edad);
}
}
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 130/313 -
import [Link].*;
import [Link].*;
public class DeserializarHashMap {
// Esta clase debe estar en el mismo directorio que [Link]
// y debe ejecutarse despus de ella.
private static Map hashmap = null;
private static FileInputStream fis = null;
private static ObjectInputStream entrada = null;
public static void deserializar() {
try {
fis = new FileInputStream("[Link]");
entrada = new ObjectInputStream(fis);
hashmap = (HashMap) [Link]();
[Link]([Link]());
}
catch (IOException e1) {
[Link]("Imposible abrir el archivo o leer de l.");
[Link]();
}
catch (ClassNotFoundException e2) {
[Link]("Imposible convertir a un HashMap.");
[Link]();
}
finally {
try {
[Link]();
}
catch (Exception e3) {
[Link]("No pudo cerrarse el flujo.");
}
} // fin del bloque try-catch-finally
}
public static void main(String args[]) {
deserializar();
}
}
Ejemplo 12b: [Link]
[Link]
Miguel ngel Abin, Julio 2004 - 131/313 -
3.4. Cuando un byte no basta: comunicaciones en un mundo plurilinge.
Las dos superclases raz vistas hasta ahora y sus subclases trabajan directamente
con bytes. A menudo se precisa utilizar caracteres en lugar de bytes. Cuando un
carcter corresponde a un byte, es decir, cuando se almacena un carcter en un solo
byte, leer bytes corresponde a leer caracteres. Eso ocurre, por ejemplo en las
codificaciones US-ASCII e ISO Latin-1. Sin embargo, cuando un carcter requiere ms
de un byte para ser almacenado (como sucede con los caracteres asiticos, por
ejemplo), las clases anteriores son intiles: desconocen cmo codificar o decodificar
caracteres que ocupen ms de un byte. Todos los mtodos de las clases anteriores
que manipulan texto a partir de flujos de bytes asumen una codificacin ISO Latin 1
(US-ASCII es un subconjunto suyo).
Las subclases de las clases abstractas [Link] y [Link]
permiten trabajar directamente con flujos de caracteres Unicode, esto es, con flujos de
datos basados en caracteres Unicode.
Figura 58. La jerarqua de clases Writer. Extrada de la documentacin
oficial de Sun
Figura 59. La jerarqua de clases Reader. Extrada de la documentacin
oficial de Sun
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 132/313 -
La primera codificacin oficial de caracteres para ordenadores fue la codificacin
US-ASCII. Es una codificacin de 7 bits, aunque se use un byte u octeto para
representar cada carcter. De los ocho bits que forman un octeto, se usa uno como
dgito de control (por ejemplo, para comprobar posibles errores en las comunicaciones).
Esta codificacin permite slo 128 caracteres (de 0 a 127), suficientes para el ingls;
pero insuficientes para el espaol o el alemn, y completamente insuficientes para
idiomas como chino, coreano o japons. Incluso codificaciones que usan un byte
completo para cada carcter (como la ISO 8859-1 o ISO Latin 1) son incapaces de
representar alfabetos asiticos, hebreos o cirlicos.
Nota: El lector que no est familizarizado con los mtodos para
internacionalizar aplicaciones deber tener en cuenta el sentido en que uso
estos trminos en el tutorial:
- Carcter: Es la unidad mnima atmica de texto. Todo texto esta
compuesto por una cadena de caracteres.
- Conjunto, juego o repertorio de caracteres: Conjunto de caracteres.
- Conjunto de caracteres codificados: Es un conjunto ordenado de
caracteres en el que se asigna a cada carcter un nmero entero no
negativo. Los enteros no negativos se conocen como puntos de cdigo.
- Codificacin de caracteres: Es el sistema por el cual los caracteres de
un repertorio de caracteres se representan de forma binaria en un
archivo o en memoria.
- Charset: Conjunto de caracteres que se ha codificado mediante una
codificacin de caracteres.
Conviene tener en cuenta que un carcter no es una cadena de ceros y
unos: es un concepto terico. Cualquier persona considera que la letra Z de la
fuente Times New Roman y la letra Z de la fuente Comic Sans MS
corresponden al carcter zeta, si bien sus representaciones en bytes son
completamente diferentes y sus representaciones grficas no coinciden
exactamente.
Un carcter tampoco corresponde necesariamente a una letra: existen
caracteres sin correspondencia con letras (los caracteres LF y ESC en US-
ASCII, por ejemplo), pues existen caracteres de control, que se reservan para
tareas de control (marcar el fin de una lnea, del proceso, etc.). Incluso puede
suceder que distintos caracteres correspondan a una misma letra.
Nota: Las clases Reader y Writer, as como sus subclases, se introdujeron en
el JDK 1.1 (no en el 1.2). Algunas de las clases de Java que se introdujeron en
la versin 1.0 se han quedado obsoletas (oficialmente, depredated, perdn,
deprecated). As, la clase LineNumberReader. Qu sentido tiene una clase
que asocia un nmero de lnea a cada lnea de texto cuando se dispone de
clases que manejan directamente lneas de caracteres? Algo similar ocurre con
las clases PrintStream y StringBufferInputStream.
[Link]
Miguel ngel Abin, Julio 2004 - 133/313 -
Figura 60. Juego de caracteres ISO 8859-1 (ingls, alemn, francs, italiano...)
I SO 8859-1
8
9
-
NBS
P
A
B
C
D
E
F
O N M L K J I H G F E D C B A @ 4
_ ^
] \ [ Z Y X W V U T S R Q P 5
o n m l k j i h g f e d c b a ` 6
DE
L
~ } | { z y x w v y t s r q p 7
? > = < ; : 9 8 7 6 5 4 3 2 1 0 3
/ . - , + * ) ( & % $ # ! sp 2
1
0
F E D C B A 9 8 7 6 5 4 3 2 1 0
8
9
-
NBS
P
A
B
C
D
E
F
O N M L K J I H G F E D C B A @ 4
_ ^
] \ [ Z Y X W V U T S R Q P 5
o n m l k j i h g f e d c b a ` 6
DE
L
~ } | { z y x w v y t s r q p 7
? > = < ; : 9 8 7 6 5 4 3 2 1 0 3
/ . - , + * ) ( & % $ # ! sp 2
1
0
F E D C B A 9 8 7 6 5 4 3 2 1 0
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 134/313 -
Figura 61. Juegos de caracteres ISO 8859-1
El estndar Unicode (la ltima versin es la 4.0) aadi ms variedad lingstica a
las comunicaciones mediante ordenadores. El tutorial de Java de Sun afirma
errneamente que "Unicode es una codificacin de 16 bits que incluye los lenguajes
ms extendidos del mundo". Por bien que suene, est francamente equivocado. Hoy
da, Unicode es un estndar cuya meta es asignar un nmero entero no negativo
(punto de cdigo) a cada carcter de cada lenguaje humano escrito que exista o haya
existido. Por consiguiente, no constituye una codificacin (en el sentido definido hace
dos pginas) ni un charset. Asimismo, no especifica obligatoriamente ninguna
representacin binaria de los caracteres ni asigna dos bytes a cada carcter, aunque s
define algunas codificaciones posibles (y optativas) para los caracteres Unicode.
Este estndar slo recopila los caracteres existentes en casi todas las lenguas
usadas por los bpedos implumes del tercer planeta de un pequeo sistema solar y
asigna a cada caracter un nmero entero nico; adems, reserva un cierto nmero de
puntos de cdigo para futuros nuevos caracteres. Por ahora, Unicode reserva 1114112
(2
20
+ 2
16
) enteros no negativos o puntos de cdigo; de ellos, slo unos 96.000 tienen
asignados caracteres: el resto permanece vaco, a la espera de la introduccin de
nuevos caracteres.
Desde luego, Unicode no obliga a ninguna representacin computacional de los
caracteres o de los nmeros que los representan. Tomemos como ejemplo la cadena
Hello. En Unicode, esta cadena se representa as:
Los juegosde caracteresISO 8859
Lenguas de Europa oriental (substituto de Latin-2) Latin-10 ISO 8859-16
Lenguas de Europa occidental (substituto de Latin-1) Latin-9 ISO 8859-15
Lenguas clticas Latin-8 ISO 8859-14
Lenguajes blticos (substituto de Latin-4) Latin-7 ISO 8859-13
Tailands Tailands ISO 8859-11
Lenguas del norte de Europa (unifica Latin-1 y Latin-4) Latin-6 ISO 8859-10
Turco (Substituto de Latin-3) Latin-5 ISO 8859-9
Hebreo Hebreo ISO 8859-8
Griego Griego ISO 8859-7
rabe rabe ISO 8859-6
Ruso, ucraniano, blgaro, serbio, etc. Cirlico ISO 8859-5
Lenguajes del norte de europa (lituano, etc.) Latin-4 ISO 8859-4
Lenguajes del sur de Europa (turco y malts) Latin-3 ISO 8859-3
Lenguas de Europa oriental (polaco, checo, hngaro, etc.) Latin-2 ISO 8859-2
Lenguas de Europa occidental (espaol, italiano, francs,
italiano, etc.)
Latin-1 ISO 8859-1
Lenguas de Europa oriental (substituto de Latin-2) Latin-10 ISO 8859-16
Lenguas de Europa occidental (substituto de Latin-1) Latin-9 ISO 8859-15
Lenguas clticas Latin-8 ISO 8859-14
Lenguajes blticos (substituto de Latin-4) Latin-7 ISO 8859-13
Tailands Tailands ISO 8859-11
Lenguas del norte de Europa (unifica Latin-1 y Latin-4) Latin-6 ISO 8859-10
Turco (Substituto de Latin-3) Latin-5 ISO 8859-9
Hebreo Hebreo ISO 8859-8
Griego Griego ISO 8859-7
rabe rabe ISO 8859-6
Ruso, ucraniano, blgaro, serbio, etc. Cirlico ISO 8859-5
Lenguajes del norte de europa (lituano, etc.) Latin-4 ISO 8859-4
Lenguajes del sur de Europa (turco y malts) Latin-3 ISO 8859-3
Lenguas de Europa oriental (polaco, checo, hngaro, etc.) Latin-2 ISO 8859-2
Lenguas de Europa occidental (espaol, italiano, francs,
italiano, etc.)
Latin-1 ISO 8859-1
[Link]
Miguel ngel Abin, Julio 2004 - 135/313 -
U+0048 U+0065 U+006C U+006C U+006F
Cada carcter se ha representado con un nmero entero no negativo (que aqu
aparece en hexadecimal); pero no hay ningn tipo de representacin asociada a un
ordenador. Lo nico que hace Unicode es asociar un entero no negativo a cada
carcter.
Unicode fue diseado de manera que sus 256 primeros puntos de cdigo
coinciden exactamente con los de ISO 8859-1 o ISO Latin 1 (es decir, un punto de
cdigo X en Unicode tiene asociado el mismo carcter que el punto de cdigo X en ISO
Latin 1). Como los 128 primeros puntos de cdigo de ISO Latin 1 coinciden con los de
US-ASCII, los 128 puntos de cdigo de Unicode tambin coinciden con los de US-
ASCII.
Java usa una codificacin de tipo UTF-16 (Universal character set Transformation
Format). Las codificaciones ms comunes de Unicode son UTF-8, UTF-16 y UTF-32
(las tres se definen en el estndar Unicode). Echemos un rpido vistazo a sus
caractersticas:
UTF-8: Es la codificacin Unicode ms usada. En ella, cada carcter se
almacena en uno, dos, tres o cuatro bytes. Los caracteres US-ASCII, por
ejemplo, comunes en las lenguas de Europa occidental, se almacenan en un
solo byte (los caracteres en las posiciones 0-127 se corresponden en el
mismo orden con los caracteres US-ASCII). Los datos en archivos suelen
almacenarse segn esta codificacin.
UTF-16: Almacena la mayor parte de los caracteres en dos bytes, si bien se
usan cuatro bytes para algunos caracteres muy poco comunes (como
algunos caracteres chinos tradicionales, por ejemplo)
UTF-32: Usa cuatro bytes para almacenar cada carcter. Esta manera es la
ms simple posible de almacenar caracteres Unicode. El principal
inconveniente radica en el espacio: un carcter representable mediante un
byte con US-ASCII o ISO Latin-1 ocupar siempre cuatro bytes en esta
codificacin.
Las dos primeras codificaciones pueden usar de uno a cuatro bytes por carcter,
dependiendo del carcter; la ltima siempre usa cuatro bytes, sea cual sea el carcter
codificado.
La codificacin que usa Java para representar internamente los caracteres
Unicode (presentes en datos del tipo char y St r i ng) se llama UCS2. Es una variante
de UTF-16, en la que se han eliminado algunos caracteres (los que precisan ms de
dos bytes) para que los restantes se puedan almacenar en dos bytes.
Aunque la internacionalizacin es una materia muy interesante, no me propongo
perderme en ella. Con lo expuesto es suficiente para entender el porqu de las clases
[Link] y [Link]. Como ya se mencion, las subclases
derivadas de [Link] y [Link] asumen que un
carcter puede almacenarse en un byte u octeto. Este occidental planteamiento slo
resulta correcto para el juego de caracteres ISO Latin 1 (estndar ISO 8859-1), que
incluye los caracteres correspondientes a muchas lenguas europeas (espaol, francs,
alemn, etc., pero no para caracteres asiticos, arbes, cirlicos, hebreos o griegos.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 136/313 -
En resumen, las clases Reader y Wr i t er proporcionan mtodos similares a los
de I nput St r eamy Out put St r eam; pero orientados a caracteres, en lugar de a bytes.
Especificando la codificacin deseada, estas clases saben en qu caracteres deben
convertir los bytes, y viceversa.
Para concretar ideas, supongamos que se quiere leer un archivo grabado usando
la codificacin ISO 8859-5 (que incluye el alfabeto cirlico) y que se desea grabarlo,
mediante Internet, en un sistema ruso que trabaja con UTF-8. El cdigo necesario se
muestra aqu:
/ / Se l ee del ar chi vo de ent r ada
I nput St r eamReader ent r adaAr chi vo = new I nput St r eamReader ( new
Fi l eI nput St r eam( " ar chi vo. t xt " ) , " I SO- 8859- 5" ) ;
Buf f er edReader ent r ada = new Buf f er edReader ( ent r adaAr chi vo) ;
St r i ng l i nea = ent r ada. r eadLi ne( ) ; / / Se l ee l a pr i mer a l nea
/ / del ar chi vo de ent r ada
. . . / / Se pr ocesa l a ent r ada.
. . . / / Se escr i be en el ar chi vo de sal i da
Out put St r eamWr i t er sal i daAr chi vo = new Out put St r eamWr i t er (
new Fi l eOut put St r eam( " r uso. t xt " ) , " UTF- 8" ) ;
Buf f er edWr i t er sal i da = new Buf f er edWr i t er ( sal i daAr chi vo) ;
/ / Se escr i be l a pr i mer a l i nea en el ar chi vo de sal i da
sal i da. wr i t e( l i nea) ;
. . .
Lo que hace exactamente las clases no resulta relevante para el ejemplo (se
explicarn ms adelante); pero s la estructura del cdigo:
Lectura y decodificacin
Codificacin y escritura
Si el sistema que lee el archivo estuviera configurado como ASCII o ISO Latin 1 y
no se especificara la codificacin que debe usarse para la lectura, todos los caracteres
que no correspondieran a caracteres ASCII o ISO Latin 1 apareceran equivocados. En
consecuencia, los datos que se grabaran en el archivo del sistema ruso careceran de
sentido.
El resultado de leer, usando la configuracin por defecto de mi sistema (ISO Latin
1), un archivo con caracteres cirlicos codificado con ISO 8859-5 y de transformarlo en
un archivo UTF-8 se muestra a continuacin. La primera captura de pantalla
corresponde al archivo original; la segunda, al transformado.
Se decodifica
la entrada
Se codifica la
salida
[Link]
Miguel ngel Abin, Julio 2004 - 137/313 -
Figura 62. Archivo escrito en ruso (texto sacado de una pgina rusa sobre
Unicode)
Figura 63. El archivo anterior, transformado en un galimatas.
Como puede verse, los nicos caracteres que se han conservado correctamente
han sido los US-ASCII (los nmeros y la palabra Unicode en algunas lneas). Desde
luego, los angloparlantes siempre parten con ventaja: cualquier codificacin respeta los
caracteres US-ASCII, que permiten representar cualquier texto escrito en ingls. Dicho
de otra manera: los 128 primeros caracteres de todas las codificaciones actuales
siempre coinciden con los caracteres US-ASCII, en el mismo orden que tienen en el
estndar norteamericano (de estos 128 caracteres, slo aquellos con posiciones entre
la 32 y la 127, ambas inclusive, corresponden a caracteres mostrables). Toda persona
que trabaje siempre con informacin en ingls no deber preocuparse de la
configuracin de su sistema: un texto en ingls siempre puede leerse correctamente,
sea cual sea la codificacin usada para guardarlo o para leerlo (US-ASCII, ISO Latin 1,
UTF-8, UTF-16, etc.); lo nico que vara en cada codificacin es el espacio necesario
para almacenarlo.
Las moralejas resultan claras:
Para enviar datos a travs de una red o almacenarlos en un archivo
hay que manejar una codificacin que el receptor sepa interpretar.
De nada sirve Internet si los receptores reciben garabatos. Usar siempre
la codificacin por defecto del sistema es incorrecto: las aplicaciones as
escritas se comportarn de distinto modo en distintos sistemas.
Para conseguir que un lenguaje sea respetado por todos los
estndares hay que hacer los primeros basndose en ese lenguaje.
En esto de los estndares, como en tantas cosas de la vida, gana quien
llega primero.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 138/313 -
Advertencia: La codificacin por defecto de un programa
Java, es decir, la codificacin en la que leer y escribir
caracteres Unicode, depende de varios factores. A saber: la
MVJ, el sistema operativo bajo la MVJ y los parmetros de
configuracin del sistema operativo.
El lector que trabaje con versiones de Java anteriores a la 1.4
debe tener en cuenta que Sun us en ellas nombres no
oficiales para casi todos las codificaciones. Es posible que
para que funcionen los ejemplos sea necesario cambiar "ISO-
8859-5" por "ISO8859_5", etc.
Recomiendo consultar la documentacin de Java para saber
cmo referirse a cada codificacin.
[Link]
Miguel ngel Abin, Julio 2004 - 139/313 -
3.5. La clase [Link]
Esta subclase de Reader modela un flujo de entrada basado en bytes como un
flujo de caracteres, tambin de entrada. Los bytes se leen de un I nput St r eamy se
convierten en caracteres, de acuerdo con la codificacin especificada en el constructor.
Proporciona mtodos de lectura (publ i c i nt r ead( ) , publ i c i nt r ead( char [ ]
ar r ay, i nt of f set , i nt l ongi t ud) ) que permiten leer bytes y convertirlos en
caracteres, segn la codificacin usada (si no se especifica ninguna, se toma por
defecto la que corresponde al sistema operativo). Cada vez que se llama a uno de los
dos mtodos de lectura, se lee uno o ms octetos del flujo de bytes sobre el cual se ha
construido.
Los dos constructores ms usados de esta clase son
publ i c I nput St r eamReader ( I nput St r eament r ada)
publ i c I nput St r eamReader ( I nput St r eam ent r ada, St r i ng
codi f i caci on) t hr ows Unsuppor t edEncodi ngExcept i on
Para leer caracteres se usan dos mtodos r ead( ) :
publ i c i nt r ead( ) t hr ows I OExcept i on
publ i c i nt r ead( char [ ] buf f er , i nt of f set , i nt l ongi t ud)
t hr ows I OExcept i on
La siguiente lnea lee la entrada estndar y la convierte en caracteres Unicode:
I nput St r eamReader ent r adaCar act er es = new I nput St r eamReader (
Syst em. i n) ;
Al haberse usado el primer constructor, se toma como codificacin la usada en la
mquina. En un ordenador europeo o estadounidense, lo normal es que sea Cp1252 o
ISO 8859-1 (ISO Latin 1). En una mquina ubicada en China, por ejemplo, lo lgico es
que se use MS936, GB18030, EUC_CN o GBK. En una mquina china cabe esperar
que se manipulen archivos con datos escritos en chino mandarn y que se use un
sistema operativo que permita trabajar con caracteres chinos; si se intentara usar una
codificacin ISO Latin 1, los bytes de los archivos (codificados para representar
caracteres chinos) se intentaran convertir en caracteres europeos. Resultado: el
programador recibira, das despus, comentarios como "Creo que he cometido algn
error al manejar su excelente programa. Sera tan amable de echarle un vistazo
cuando pueda? No es urgente: habr cometido algn error" (a los chinos no
occidentalizados les es casi imposible manifestar abiertamente desacuerdo con un
interlocutor). El lector puede imaginarse los comentarios que sufrira el programador en
cualquier pas menos educado (o ms franco, segn se mire).
En el siguiente cdigo se lee la entrada estndar y se convierte en caracteres
Unicode, segn la codificacin internacional para caracteres griegos:
I nput St r eamReader ent r adaCar act er es = new I nput St r eamReader (
Syst em. i n, " I SO- 8859- 7" ) ;
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 140/313 -
Cada vez que se llame a un mtodo r ead( ) , 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:
Fi l eI nput St r eamar chi vo = new Fi l eI nput St r eam( " r uso. t xt " ) ;
I nput St r eamReader ent r adaCar act er es = new I nput St r eamReader (
ar chi vo, " I SO- 8859- 5" ) ;
Para leer el primer carcter cirlico de [Link] y mostrarlo en pantalla, se podra
escribir esto:
char c = ( char ) ent r adaCar act er es. r ead( ) ;
Syst em. out . pr i nt l n( c) ;
En un sistema con fuentes cirlicas, se mostrara el primer carcter (por ejemplo,
).
Dado un objeto I nput St r eamReader , puede obtenerse el nombre de la
codificacin de caracteres que se est usando mediante el mtodo publ i c St r i ng
get Encodi ng( ) . Veamos un ejemplo:
I nput St r eamReader ent r adaCar act er es = new
I nput St r eamReader ( Syst em. i n) ;
Syst em. out . pr i nt l n( " Codi f i caci n " : +
ent r adaCar act er es. get Encodi ng( ) ) ;
En mi sistema, este cdigo muestra en pantalla la cadena "Codificacin:
ISO8859_1", que corresponde a ISO Latin 1.
La nica subclase de I nput St r eamReader es Fi l eReader , que permite leer
archivos de texto usando la codificacin por defecto del sistema. Esta clase
proporciona una interfaz de flujos de caracteres para leer archivos de texto usando la
codificacin por defecto. Uno de sus constructores es ste:
publ i c Fi l eReader ( St r i ng nombr eAr chi vo) t hr ows Fi l eNot FoundExcept i on
Este constructor crea un objeto Fi l eReader que lee, usando la codificacin por
defecto del sistema, del archivo denotado por nombr eAr chi vo.
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.
[Link]
Miguel ngel Abin, Julio 2004 - 141/313 -
3.6. La clase [Link]
Esta subclase de Wr i t er modela un flujo de salida basado en bytes como un flujo
de caracteres, tambin de salida. Proporciona mtodos de escritura (publ i c voi d
wr i t e( ) ; publ i c voi d wr i t e( char [ ] ar r ay, i nt of f set , i nt
l ongi t ud); publ i c voi d wr i t e( St r i ng cadena, i nt of f set , i nt
l ongi t ud) ) que permiten escribir en un Out put St r eamlos bytes que resultan de
codificar los caracteres, de acuerdo con la codificacin especificada en el constructor
(si no se especifica ninguna, se toma por defecto la del sistema).
Cada vez que se llama a uno de los tres mtodos de escritura, se obtienen los
bytes (o el byte) que corresponden al carcter o al grupo de caracteres que se
introduce como argumento; pero los bytes no se escriben inmediatamente en el flujo de
salida: permanecen en un buffer. El mtodo publ i c voi d f l ush( ) se encarga de
hacer que se escriban cuando se le llama, este lleno o no el buffer.
Los dos constructores ms usados de esta clase son
publ i c Out put St r eamWr i t er ( Out put St r eamsal i da)
publ i c Out put St r eamWr i t er ( Ouput St r eamsal i da, St r i ng
codi f i caci on) t hr ows Unsuppor t edEncodi ngExcept i on
En el siguiente cdigo:
Out put St r eamWr i t er sal i daCar act er es = new Out put St r eamWr i t er (
Syst em. out , " ASCI I " ) ;
cada vez que se llame a un mtodo wr i t e( ) , seguido de un f l ush( ) , se escribirn
en el flujo estndar de salida los bytes que correspondan, segn la privilegiada
codificacin US-ASCII, a los caracteres introducidos dentro del argumento de
wr i t e( ) .
Si, por ejemplo, se quiere escribir en un archivo codificado con el juego de
caracteres ISO-8859-5 (cirlico), se puede usar
Fi l eOut put St r eamf i s = new Fi l eOut put St r eam( " r uso. t xt " ) ;
Out put St r eamWr i t er sal i daCar act er es = new Out put St r eamWr i t er (
ar chi vo, " I SO- 8859- 5" ) ;
Para escribir la letra rusa en el flujo de salida se necesita este cdigo:
char c = ( char ) 1174; / / t ambi n se podr a usar el cdi go
/ / Uni code del car ct er
sal i daCar act er es. wr i t e( c) ;
Para obtener el nombre de la codificacin usada en un Out put St r eamWr i t er ,
se usa el mtodo publ i c St r i ng get Encodi ng( ) .
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 142/313 -
La nica subclase de Out put St r eamWr i t er es Fi l eWr i t er , que permite
escribir en archivos de texto mediante la codificacin por defecto del sistema. Esta
clase proporciona una interfaz de flujos de caracteres para escribir en archivos de texto
mediante la codificacin por defecto. Uno de sus constructores tiene esta forma:
publ i c Fi l eWr i t er ( St r i ng nombr eAr chi vo, bool ean anyadi r )
t hr ows I OExcept i on
Este constructor crea un objeto Fi l eWr i t er que escribe en el archivo al que se
refiere nombr eAr chi vo usando la codificacin por defecto del sistema. El parmetro
anyadi r indica si los datos deben aadirse a un archivo ya existente (t r ue) o si debe
eliminarse el archivo que ya exista (f al se).
[Link]
Miguel ngel Abin, Julio 2004 - 143/313 -
3.7. La clase [Link]
Esta subclase de la superclase raz Reader decora los objetos Reader
aadindoles la posibilidad de usar buffers, lo que mejora la eficiencia.
Esta clase incorpora un nuevo mtodo: publ i c St r i ng r eadLi ne( ) t hr ows
I OExcept i on, que permite leer lneas de texto desde un archivo de texto.
Siempre que se vaya a procesar el contenido de archivos de texto es conveniente
usar esta clase. Para ver un ejemplo de su uso, vamos a considerar un archivo
sagan. t xt , ubicado en el directorio donde se ejecutar la clase Leer Ar chi vo. Su
contenido se muestra a continuacin:
Figura 64. El archivo [Link]
Para mostrar por pantalla su contenido y contar las lneas que tiene, se va a usar
este programa (el resultado se muestra en la figura 65):
import [Link].*;
public class LeerArchivo {
public static void main(String args[]) {
BufferedReader br = null;
String linea;
int contador = 0;
try {
br = new BufferedReader(new FileReader("[Link]"));
Nota: En Java una lnea de texto acaba en \r, \n o \r\n, segn
el sistema que se est usando (Windows, Mac, Solaris, etc).
Ejemplo 13: [Link]
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 144/313 -
while ( (linea = [Link]()) != null) {
contador++;
[Link] ("Linea " + contador + ": " + linea);
}
}
catch (IOException e1) {
[Link]( "No se ha podido leer del archivo");
[Link]();
}
finally {
try {
[Link]();
}
catch (Exception e2) {
[Link]("No se ha podido cerrar el flujo");
}
} // fin del bloque try-catch-finally
}
}
Figura 65. Salida del programa LeerArchivo
[Link]
Miguel ngel Abin, Julio 2004 - 145/313 -
Una manera muy visual de entender las clases de E/S de Java es imaginar que
son ros (la palabra filtro de las clases Fi l t er XXX slo me hace pensar en filtros de
caf y en filtros pasabanda, pasabaja, etc). Un objeto como Buf f er edReader es
como un ro con un cauce ms grueso que el de un objeto I nput St r eamReader . As
pues, el ro I nput St r eamReader cabe dentro del ro Buf f er edReader . 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).
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 146/313 -
3.8. La clase [Link]
Esta subclase de la superclase raz Wr i t er decora los objetos Wr i t er
aadindoles la posibilidad de usar buffers, lo que mejora la eficiencia.
Esta clase incorpora un nuevo mtodo: publ i c St r i ng newLi ne( ) t hr ows
I OExcept i on, que permite introducir saltos de lnea (en cada plataforma se traducen
a lo que corresponda: \n, etc.)
Como ejemplo de su uso, se presenta un programa en que se emplea para
insertar una lnea en blanco entre cada lnea del texto recogido en sagan. t xt ; el texto
resultante se almacena en un archivo llamado sagan2. t xt .
import [Link].*;
public class EscribirArchivo {
public static void main(String args[]) {
String linea = null;
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader("[Link]"));
bw = new BufferedWriter(new FileWriter("[Link]"));
while ( (linea = [Link]()) != null) {
[Link](linea);
[Link]();
[Link]();
[Link]();
}
}
catch (IOException e1) {
[Link]( "No se ha podido leer o escribir.");
[Link]();
}
finally {
try {
[Link]();
[Link]();
}
catch (Exception e2) {
[Link]("No se podido cerrar el flujo.");
}
} // fin del bloque try-catch-finally
}
}
Ejemplo 14: [Link]
[Link]
Miguel ngel Abin, Julio 2004 - 147/313 -
Figura 66. Contenido del archivo [Link]
Consejo: A menudo resulta til decorar un objeto
Fi l eWr i t er con un Buf f er edWr i t er , aunque no se
necesite usar buffers, pues as se puede emplear el mtodo
newLi ne( ) .
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 148/313 -
3.9. La clase [Link]
Esta subclase de la superclase raz Wr i t er permite usar los mtodos pr i nt ( ) y
pr i nt l n( ) . Sus constructores son
publ i c Pr i nt Wr i t er ( Wr i t er out )
publ i c Pr i nt Wr i t er ( Wr i t er out , bool ean aut oFl ush)
publ i c Pr i nt Wr i t er ( Out put St r eamout )
publ i c Pr i nt Wr i t er ( Out put St r eamout , bool ean aut oFl ush)
Cuando el argumento aut oFl ush se establece igual a t r ue, el objeto
Pr i nt Wr i t er creado vaca automticamente su buffer cada vez que se llama a
pr i nt l n( ) . A diferencia de la antigua clase Pr i nt St r eam, esta clase usa un
separador de lneas dependiente de la plataforma, en lugar de un carcter de nueva
lnea, y emplea la codificacin de caracteres establecida en el sistema, sea ISO Latin 1
o no. Pr i nt Wr i t er permite escribir tipos primitivos, arrays de caracteres, cadenas y
objetos. En el siguiente ejemplo se usa dicha clase para escribir en un archivo el
alfabeto ruso (por brevedad, se ha omitido la gestin de las posibles excepciones):
import [Link].*;
public class AlfabetoRuso {
public static void main(String args[]) throws IOException {
FileOutputStream archivoSalida = new FileOutputStream( "[Link]");
BufferedOutputStream salidaBuffer = new BufferedOutputStream(archivoSalida);
PrintWriter salida = new PrintWriter(new OutputStreamWriter(salidaBuffer, "UTF-8" ));
//Se escribe el alfabeto cirlico
for (char i = 0x0401; i < 0x0460; i++) {
[Link](i);
}
[Link]();
}
}
El archivo resultante se muestra en la pgina siguiente (se incluye tambin la
codificacin ISO 8859-5 para que el lector pueda comprobar que est todo el alfabeto
ruso).
Ejemplo 15: [Link]
[Link]
Miguel ngel Abin, Julio 2004 - 149/313 -
Figura 67. El resultado del programa 15
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 150/313 -
3.10. El patrn decorador y el paquete [Link]
En el subapartado 3.2 se mencion el patrn decorador. Este patrn se ha usado
en la elaboracin de todas las jerarquas de clases de [Link]; por tanto, conocer
cmo funciona ayuda a comprender por qu las clases de E/S de Java se usen o no
para comunicaciones en red se crearon as. El lector sin inters en l puede pasar
directamente al apartado 4.
Para entender por qu [Link] usa el patrn decorador, no hay nada ms fcil
que suponer que no se hubiera usado. Consideremos, por caso, la jerarqua de clases
de [Link].
Figura 68. La jerarqua de clases InputStream. Extrada de la documentacin
oficial de Sun
Supongamos que no existiera la clase abstracta Fi l t er I nput St r eam. Para que
clases como Fi l eI nput St r eam, Pi pedI nput St r eam, etc., tuvieran disponibles las
funciones adicionales que aportan Li neNumber I nput St r eam, Dat aI nput St r eam,
Buf f er edI nput St r eam y PushbackI nput St r eam sera necesario tener clases
como
Li neNumber Fi l eSt r eam
Li neNumber Pi pedI nput St r eam
Li neNumber Sr i ngBuf f er I nput St r eam
Dat aFi l eI nput St r eam
Dat aPi pedI npudSt r eam,
Buf f er edPi pedI nput St r eam
Buf f er edFi l eI nput St r eam
Buf f er edPi pedI nput St r eam
Buf f er edSt r i ngBuf f er I nput St r eam
. . .
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:
Estas clases no existen: gracias al
patrn decorador no son necesarias
[Link]
Miguel ngel Abin, Julio 2004 - 151/313 -
Entrada o salida.
Fuente o destino: archivos, arrays de Strings, sockets, etc.
Uso de buffers o ausencia de ellos.
Formato de bytes o de caracteres Unicode.
Tipos de operaciones: acceso secuencial, aleatorio, por lnea, por palabra,
etc.
El patrn decorador, cuyo esquema se representa en la figura 69; pone coto a
estos crecimientos cancerosos de las jerarquas de clases.
Este patrn permite aadir de modo dinmico nuevas funciones a objetos
individuales (no a clases completas). En vez de usar la herencia tradicional, este patrn
encapsula un objeto dentro de un objeto decorador, que se encarga de proporcionar las
nuevas funciones.
Figura 69. Esquema del patrn decorador.
En este esquema,
El elemento Component e define la interfaz para los objetos a los que
se les pueden aadir funciones. En Java, puede ser una clase
abstracta o una interfaz.
El elemento Component eConcr et o define un objeto al cual se pueden
aadir funciones.
El elemento Decor ador mantiene una referencia al objeto
Component e (composicin) y define una interfaz conforme a la de
Component e. Puede ser una clase abstracta o una concreta.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 152/313 -
Los elementos del tipo Decor ador Concr et o aaden funciones
especficas al objeto Component e (o modifican las que ya tena).
Como una imagen vale ms que mil palabras, voy a abordar un ejemplo donde la
decoracin es visible. Para ello, abandono momentneamente el paquete [Link] 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
publ i c cl ass J But t onBor deRect o ext ends J But t on {. . . }
publ i c cl ass J CheckBoxRect o ext ends J CheckBox {}
publ i c cl ass J ComboBoxRect o ext ends J ComboBox {}
Esta aproximacin es psima por cuanto aumenta el nmero de clases que se
necesita manejar. Si usamos el patrn decorador, el cdigo que deberamos escribir
para responder a la pregunta anterior sera similar a ste:
import [Link].*;
import [Link].*;
public class DecoradorBorde extends JComponent {
protected JComponent componenteHijo;
private int forma;
public final static int RECTANGULO = 0;
public final static int REDONDO = 1;
public DecoradorBorde(JComponent componente, int forma) {
componenteHijo = componente;
[Link](new BorderLayout());
[Link](componenteHijo);
[Link] = forma;
}
public void paint(Graphics g) {
[Link](g);
int alto = [Link]();
int ancho = [Link]();
if (forma == RECTANGULO) {
[Link](0, 0, ancho - 1, alto - 1);
} else if (forma == REDONDO) {
[Link](0, 0, ancho - 1, alto - 1, 75, 75);
Ejemplo 16a: [Link]
[Link]
Miguel ngel Abin, Julio 2004 - 153/313 -
}
}
}
Para conseguir que un componente de Swing adquiera un borde rectangular
bastar con escribir lneas como sta:
Decor ador Bor de db = new Decor ador Bor de( new component e (
" Decor at ed J Label " ) , Decor ador Bor de. RECTANGULO) ;
Para conseguir componentes con bordes redondos bastar con usar lneas as:
Decor ador Bor de db = new Decor ador Bor de( new component e (
" Decor at ed J Label " ) , Decor ador Bor de. REDONDO) ;
Veamos un ejemplo:
import [Link].*;
import [Link].*;
public class Frame1 extends JFrame {
// Componentes
DecoradorBorde etiqueta = new DecoradorBorde(new JLabel("JLabel decorado"),
[Link]);
DecoradorBorde checkBox = new DecoradorBorde(new JCheckBox(
"JCheckbox decorado"), [Link]);
DecoradorBorde boton = new DecoradorBorde(new JButton("JButton decorado"),
[Link]);
DecoradorBorde comboBox = new DecoradorBorde(new JComboBox(),
[Link]);
public Frame1() {
try {
[Link](EXIT_ON_CLOSE);
getContentPane().setLayout(null);
[Link](new Rectangle(30, 20, 140, 30));
[Link](new Rectangle(30, 120, 140, 30));
[Link](new Rectangle(30, 220, 140, 30));
[Link](new Rectangle(30, 320, 140, 30));
[Link]().add(etiqueta, null);
[Link]().add(checkBox, null);
[Link]().add(boton, null);
[Link]().add(comboBox, null);
}
catch(Exception e) { [Link]();}
}
public static void main(String[] args) {
Ejemplo 16b: [Link]
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 154/313 -
Frame1 frame1 = new Frame1();
[Link](0, 0, 400, 600);
[Link](true);
}
}
El resultado se muestra aqu:
Figura 70. Ejemplo grfico del patrn decorador
Comprendiendo este ejemplo grfico, podemos retornar al paquete [Link]. La
misteriosa clase Fi l t er I nput St r eam del subapartado 3.2. es un decorador
abstracto. I nput St r eames el componente abstracto raz del patrn decorador, y
clases como Dat aI nput St r eam, Buf f er edI nput St r eam, etc., son decoradores
concretos (recurdese la figura 68). Lo mismo puede decirse, mutatis mutandis, para la
jerarqua [Link].
Si consideramos la jerarqua [Link] (vase la figura 59), Reader es el
componente abstracto raz en el patrn decorador; Fi l t er Reader , el decorador
abstracto; y Buf f er edReader , Char Ar r ayReader , PushBackReader ,
St r i ngReader , etc., decoradores concretos. Algo similar puede decirse para la
jerarqua [Link], mutatis mutandis.
A la luz del patrn decorador, podemos profundizar en lo que significan lneas
como stas:
[Link]
Miguel ngel Abin, Julio 2004 - 155/313 -
Fi l eI nput St r eamf i s = new Fi l eI nput St r eam( " hi st or i al . t xt " ) ;
I nput St r eamReader i sr = new I nput St r eamReader ( f i s) ;
Buf f er edReader br = new Buf f er edReader ( i sr ) ;
El objeto f i s se decora con la clase I nput St r eamReader y adopta nuevas
funciones. Los mtodos r ead( ) de Fi l eI nput St r eampermiten leer bytes del flujo de
entrada del archivo; ahora; los mtodos r ead( ) de I nput St r eamReader permiten
leer caracteres del flujo de entrada de caracteres asociado al archivo. No es que el
objeto i sr no use los mtodos r ead( ) de la clase a la que pertenece el objeto que
encapsula: s los usa, pero luego aade su propio cdigo (que convierte los bytes en
caracteres mediante el juego de caracteres especificado o el que est por defecto en el
sistema). Externamente, la interfaz del objeto i sr es compatible con la de f i s (el
decorador tiene, al menos, la misma interfaz que el objeto que decora o encapsula).
Buf f er edI nput St r eam aade funciones al objeto i sr : le proporciona
capacidad para usar buffers con la entrada y le aade los mtodos mar k( ) y r eset ( ) .
El primer mtodo registra un punto en el flujo de entrada, y el segundo causa que todos
los bytes ledos desde la ltima llamada a mar k( ) sean reledos antes de que se
vuelvan a leer nuevos bytes del flujo de entrada.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 156/313 -
4. Aplicaciones y sistemas distribuidos
4.1. Introduccin. De los mainframes a los sistemas distribuidos
Cuando los primeros dinosaurios informticos poblaban este planeta, el mainframe
(macroordenador, ordenador central) era el Tyrannosaurus Rex. La configuracin ms
habitual en los sistemas bancarios de los aos sesenta y setenta consista en disponer
de un mainframe con una base de datos de tipo jerrquico y en el que se ejecutaba una
aplicacin COBOL. Incluso hoy da, esta configuracin persiste en algunos sistemas
bancarios. Por lo general, los clientes eran terminales tontos: mquinas sin
procesador que se limitaban a enviar peticiones al mainframe y a mostrar las
respuestas al usuario; sus funciones eran simplonas: recoger las seales elctricas que
se producan al presionar las teclas, enviarlas al mainframe y mostrar por pantalla los
caracteres que envaba ste. La inteligencia, si as se puede llamar, resida en otra
parte: en el mainframe.
Una aplicacin que se ejecutaba en un entorno de mainframes y clientes tontos
era lo que hoy conocemos como aplicacin monoltica (en aquellos tiempos, desde
luego, las cosas se vean de otro modo). Estas aplicaciones siguen al pie de la letra
estos versos (espero que Tolkien, o su espritu, no se moleste: son tantos los que lo
nombran sin reparos en estos tiempos):
One ring to rule them all,
One ring to find them,
One ring to bring them all
and in the Darkness bind them.
En este apartado uso arquitectura de un sistema (informtico) o, simplemente,
arquitectura en el sentido de una representacin conceptual o lgica del sistema que
incluya lo siguiente:
La identificacin de todos los componentes del sistema.
Las funciones de cada componente.
Las relaciones e interacciones entre los componentes.
En general, las funciones desempeadas por cualquier aplicacin pueden dividirse
en tres funciones o componentes generales (en otras palabras: una aplicacin tiene
estas partes):
Lgica de acceso a datos.
Lgica de la aplicacin.
Lgica de la presentacin.
La lgica de acceso a datos se encarga del almacenamiento de los datos, as
como de mantenerlos actualizados. Como casi todas las aplicaciones usan bases de
datos, la lgica de acceso a datos suele implementarse mediante un sistema de gestin
de bases de datos (Database Management System, DBMS): Oracle, MySQL,
SQLServer, Access, etc. El sistema de gestin tambin puede corresponder a un
mecanismo de gestin de archivos de texto, binarios, etc, si bien no es lo habitual en
las aplicaciones empresariales. Esta capa se encarga de las interacciones con la base
de datos para modificar, aadir o borrar registros, as como para efectuar consultas. La
base de datos es la verdadera encargada de almacenar los datos en un medio fsico
[Link]
Miguel ngel Abin, Julio 2004 - 157/313 -
(un disco, p. ej.) y de recuperarlos. Esta capa no es responsable de manipular o
procesar los datos. En ocasiones, se separa est lgica en dos: lgica de acceso a
datos y lgica del almacenamiento de datos.
La lgica de la aplicacin es responsable de manejar la lgica del procesado de
los datos (validacin e identificacin de los errores de procesado), las reglas de
negocio y la lgica de la gestin de datos (identificacin de los datos necesarios para
procesar las transacciones y consultas). Si uno quiere recurrir a palabras sencillas y
claras, puede identificar esta parte de la aplicacin con el cdigo: los i f , whi l e, do...
La lgica de la presentacin se encarga de dar formato a los datos, de
presentarlos a los usuarios y de gestionar las entradas de stos (pulsaciones de teclas,
del ratn, etc.)
En el caso de una aplicacin monoltica o centralizada, las tres funciones o
componentes generales estn mezcladas en la aplicacin. La situacin se muestra en
la siguiente figura.
Figura 71. Cuando los mainframes dominaban la Tierra...
Mainframe
Aplicacin
Interfaz de usuario
Lgica de la
aplicacin
Datos
BD
ESTRUCTURA DE UNA APLICACIN MONOLTICA
M
i
g
u
e
l
n
g
e
l
A
b
i
n
J
u
l
i
o
2
0
0
4
Clientes
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 158/313 -
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
[Link]
Miguel ngel Abin, Julio 2004 - 159/313 -
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.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 160/313 -
Figura 72. Estructura de una aplicacin cliente-servidor de dos capas
En su momento, las aplicaciones cliente-servidor de dos capas resultaron de una
novedad espeluznante. Hoy da, con los continuos avances (y retrocesos) informticos,
nos parecen demasiado simples. Para apreciar lo que supusieron hay que verlas con
los ojos de las personas que estaban acostumbradas a ver gigantescos mainframes y
pantallas verdes o grisceas. En la actualidad se continan usando las aplicaciones de
dos capas, sobre todo en aplicaciones para intranets de tamao pequeo o mediano.
Servidor
Aplicacin
Interfaz de
usuario
Lgica de la
aplicacin
Datos
BD
ESTRUCTURA DE UNA APLICACIN C-S DE 2 CAPAS
M
i
g
u
e
l
n
g
e
l
A
b
i
n
J
u
l
i
o
2
0
0
4
Lgica de la
aplicacin
Clientes
[Link]
Miguel ngel Abin, Julio 2004 - 161/313 -
Figura 73. Tipos de arquitecturas cliente-servidor de dos capas. El sistema de
gestin de la base de datos se representa separado de la lgica de acceso a
datos
TIPOS DE ARQUITECTURAS CLIENTE-SERVIDOR
DE DOS CAPAS
Centralizada o monoltica Basada en el servidor (cliente delgado)
Cooperativa Basada en el cliente (cliente gordo)
DBMS: Sistema de gestin de la base de datos
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 162/313 -
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
EJEMPLO DE LA ARQUITECTURA C-S DE DOS CAPAS
CON CLIENTES GORDOS
Cliente gordo Cliente gordo
Servidor de archivos Servidor de archivos
[Link]
Miguel ngel Abin, Julio 2004 - 163/313 -
A pesar de las ventajas con respecto a las aplicaciones monolticas, las
aplicaciones basadas en las arquitecturas c-s de dos capas tambin tienen sus
problemas. A menudo, se encapsulan en el cliente funciones como el acceso a los
datos y la lgica de la aplicacin. Este enfoque tiene aparejado un importante
problema: el de la distribucin de la aplicacin del cliente. Supongamos, por ejemplo,
que la aplicacin en el lado del cliente tiene cdigo de acceso a una base de datos
(mediante consultas SQL, p. ej.) mezclado con el de la lgica de la aplicacin.
Cualquier cambio en el cdigo de acceso a los datos o en la lgica de aplicacin har
que la aplicacin del cliente tenga que ser recompilada y, luego, reinstalada en cada
uno de los clientes. En un entorno en que las aplicaciones se modifican a menudo y
donde hay muchos clientes, el proceso de distribucin puede ser costoso o imposible.
Otro problema lo constituye la falta de escalabilidad: las aplicaciones c-s de dos
capas no son escalables. Conforme aumenta el nmero de usuarios, la red se va
saturando, porque los clientes y el servidor intercambian mensajes de control
continuamente, aun cuando no se estn atendiendo peticiones. Este tipo de
aplicaciones no resultan prcticas para Internet, donde un servidor puede recibir
cientos o miles de peticiones simultneas. En general, no son recomendables para ms
de 100 150 clientes.
La solucin para los problemas anteriores vino de mano de las aplicaciones
cliente-servidor de tres capas, que aparecieron a principios de los aos noventa y se
hicieron populares a partir de 1995 (las figuras 76, 77, 78, 79 y 80 muestran varios
ejemplos). En una aplicacin de esta clase existe tres capas:
La capa del cliente, asociada a la lgica de la presentacin. Se encarga
de la presentacin de los datos, de darles formato, de recibir las
peticiones de los usuarios y de controlar la interfaz grfica.
La capa intermedia, asociada a la lgica de la aplicacin. Esta capa no
existe como tal en las arquitecturas de dos capas. La capa se encarga
de lo que se conoce como reglas de negocio: aplicar un IVA del 16% a
las compras de combustible, retirar de una cuenta la cantidad solicitada,
comprobar que un camin no sale sin carga, etc.
La capa de almacenamiento de datos o capa de persistencia, tambin
llamada capa de datos, asociada a la lgica de acceso a datos. La capa
de datos administra y maneja la informacin de la aplicacin, lo cual
incluye el almacenamiento, mantenimiento y consulta de los datos.
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.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 164/313 -
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.
Figura 76. Ejemplo de una aplicacin de tres capas que se ejecuta en dos
mquinas
Servidor
Aplicacin
Interfaz de
usuario
BD
EJEMPLO DE UNA APLICACIN DE 3 CAPAS
M
i
g
u
e
l
n
g
e
l
A
b
i
n
J
u
l
i
o
2
0
0
4
Clientes
Lgica de acceso a datos
Lgica de la aplicacin
[Link]
Miguel ngel Abin, Julio 2004 - 165/313 -
Figura 77. Ejemplo de una aplicacin de tres capas que se ejecuta en tres
mquinas. Extrado de una propaganda comercial
EJEMPLO DE LA ARQUITECTURA C-S DE TRES CAPAS
CON CLIENTES DELGADOS
Clientes Clientes
delgados delgados
Lgica de negocio Lgica de negocio
en un servidor en un servidor
DBMS en un DBMS en un
solo servidor solo servidor
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 166/313 -
Figura 78. Ejemplo de una aplicacin de tres capas que se ejecuta en N
mquinas. La lgica de la aplicacin puede repartirse entre varios servidores.
Figura 79. Comparacin entre una aplicacin c-s de dos capas y una de tres
capas
Lgica de presentacin
Lgica de la
aplicacin
Datos
compartidos
Internet
Al igual que un servidor
puede atender a varios
clientes, un servidor de datos
puede atender a varios
servidores de aplicacin.
EJEMPLO DE LA ARQUITECTURA C-S DE TRES CAPAS
[Link]
Miguel ngel Abin, Julio 2004 - 167/313 -
Figura 80. La WWW como un sistema de tres capas. La realidad es ms
complicada, pero vale como una primera aproximacin
A diferencia de lo que sucede en las arquitecturas de dos capas, en las de tres no
hay comunicacin directa entre el cliente y el servidor de bases de datos: la primera
hace sus peticiones a una capa intermedia (el servidor de aplicaciones), que determina
qu datos se necesitan, dnde estn localizados y los solicita al servidor de bases de
datos. En consecuencia, la capa intermedia es cliente del servidor de bases de datos.
La divisin de las aplicaciones es ms de dos capas favorece el reparto de la
carga de trabajo entre varias mquinas. Si el servidor de la figura 76 recibiera
demasiadas peticiones, una de las capas (lgica de acceso a datos o lgica de la
aplicacin) podra ubicarse en otro anfitrin. Si esa solucin no fuera suficiente, incluso
se podra dividir cada capa en subcapas que se repartiran entre varios anfitriones.
Esta divisin tambin simplifica el proceso de distribucin de las aplicaciones.
Como la lgica de la aplicacin (el cdigo, en definitiva) est ubicada en un nico lugar
(el servidor de aplicaciones), cuando hay que cambiarla basta con hacer los cambios
en el servidor de aplicaciones para que todos los clientes accedan a la nueva lgica.
Asimismo, si hay cambios en la lgica de acceso a datos, los clientes permanecen
aislados de ellos gracias a la capa intermedia del servidor de aplicaciones.
LA WEB: UN SISTEMA DE TRES CAPAS
Capa del cliente
(Lgica de la presentacin)
Servidor web
DBMS
Cdigo de la aplicacin
Achivos
World Wide
Web
HTTP
Navegador web
Navegador web
Navegador web
Navegador web
Capa de datos
(Lgica de acceso a datos)
Capa intermedia
(Lgica de la aplicacin)
BD
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 168/313 -
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
Lgica Acc. datos
EVOLUCIN DE LAS
ARQUITECTURAS INFORMTICAS
Sistemas c-s 2 capas
Sistemas monolticos
Base de datos
Log. aplicacin
Log. presentacin
Log. aplicacin
Log. presentacin
LgicaAcc. datos
Log. aplicacin
LgicaAcc. datos
Log. aplicacin
Log. presentacin
Sistemas c-s 3 capas
[Link]
Miguel ngel Abin, Julio 2004 - 169/313 -
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:
Pginas JSP, encargadas de crear el HTML para las pginas web
que actan como interfaz grfica para el usuario.
Servlets o JavaBeans encargados de la lgica de la aplicacin.
Servlets, JavaBeans o clases Java que se encargan del acceso a los
datos (suelen usar JDBC para extraer registros de las bases de
datos).
En una aplicacin EJB (Enterprise JavaBeans) sencilla, el cdigo que reside en el
servidor de aplicaciones suele dividirse en estas tres partes.
Pginas JSP, servlets o aplicaciones Java de tipo cliente, que se
encargan de la interfaz grfica para el usuario.
Beans de sesin (Session Beans) o de entidad (Entity Beans) que
implementan la lgica de la aplicacin.
Beans de entidad cuyos campos representan datos. La persistencia
de estos campos se consigue mediante los propios Beans de entidad
o mediante un servidor EJB.
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.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 170/313 -
La seguridad puede contralarse de manera precisa porque se
pueden hacer comprobaciones en cada capa o subcapa.
Adems, los clientes no interaccionan directamente con los
datos, sino con la lgica de la implementacin (que puede estar
dividida en varias subcapas).
El esquema ms general posible de las arquitecturas cliente-servidor multicapa se
muestra en la siguiente figura. Cuando las subcapas de cada nivel se funden en una
sola capa, tenemos el caso particular de las arquitecturas de tres capas.
Figura 82a. Esquema general de las arquitecturas c-s de N capas
Base de datos
ARQUITECTURA C-S MULTICAPA
Lgica de presentacin
Lgica de aplicacin
Lgica de acceso a datos
Subcapas
Subcapas
Subcapas
Cada subcapa puede estar en una mquina. Una lgica dada puede estar repartida
entre muchos anfitriones
[Link]
Miguel ngel Abin, Julio 2004 - 171/313 -
Figura 82b. Ejemplo concreto de arquitectura de N capas. Corresponde al
caso en que la figura 82a tiene una capa de lgica de la presentacin, dos
subcapas de lgica de la aplicacin y una capa de acceso a datos.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 172/313 -
Figura 82c. Ejemplo concreto de arquitectura J2EE de N capas. Corresponde
al caso en que la figura 82a tiene dos subcapas de lgica de la presentacin, una
capa de lgica de la aplicacin, una capa de acceso a datos y una capa de
almacenamiento de datos. Extrado de la documentacin de Sun sobre J2EE
Los sistemas distribuidos nacieron a partir de las arquitecturas cliente-servidor
multicapa. En esencia, un sistema distribuido consiste en un sistema cliente-servidor de
N capas en el que hay un gran nmero de clientes y servidores, ubicados en distintos
anfitriones.
La principal diferencia entre un sistema distribuido y uno de N capas estriba que
en el primero no existen necesariamente los papeles explcitos de cliente o servidor.
Cada elemento o componente de un sistema distribuido es, o puede ser, cliente y
servidor. Debo aclarar que la falta de estos papeles explcitos no significa que un
elemento distribuido sea cliente para unos elementos y servidor para otros, sino que
puede ser cliente para un elemento dado y, despus, servidor para ese mismo
elemento (en lo dicho, se puede cambiar cliente por servidor). En un sistema
distribuido pueden existir, segn las necesidades del sistema, elementos que siempre
acten como clientes o servidores en relacin con otros; pero si fuera preciso se
podran alternar en el papel de cliente y en el de servidor. En un sistema de N capas
resulta imposible esa flexibilidad: el papel de una capa con respecto a otra (cliente,
servidor) no puede variar.
Aparte de la diferencia anterior, existen otras importantes diferencias entre los
sistemas distribuidos y los basados en arquitecturas multicapa. Los sistemas
[Link]
Miguel ngel Abin, Julio 2004 - 173/313 -
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:
Un servicio de nombres, encargado de permitir que un elemento de la
aplicacin encuentre de manera dinmica a otros.
Un servicio de representacin comn de los datos que son
transmitidos a las redes, de manera independiente del hardware y del
sistema operativo usados por cada nodo.
Un servicio de control de las transacciones. Una transaccin es una
operacin que debe ser realizada atmicamente: o se ejecuta
correctamente cada paso de la operacin, o se anula la operacin en
su conjunto. Por motivos evidentes, los sistemas bancarios son muy
cuidadosos con las transacciones: a los bancos les disgusta
sobremanera ver cuentas con 1.500.000 por un fallo en el
suministro elctrico, o descubrir que una hipoteca en vigor consta
como cancelada en 1910 porque un servidor ha fallado en mitad de un
pago de la hipoteca. En los sistemas de N capas, los sistemas de
gestin de bases de datos implementan mecanismos para el control
de las transacciones que afectan a los datos; pero este control es
parcial: slo afecta a la capa de persistencia. En un sistema
distribuido, todo elemento que opere con otros debe contar con un
mecanismo que le permita volver a su estado inicial si hay problemas
en la operacin. Un solo servidor que quedara en un estado invlido o
inconsistente podra dar respuestas absurdas a millones de clientes (la
situacin sera el equivalente distribuido a preguntar Quin
descubri Amrica? y recibir la respuesta La manzana es buena para
la dentadura; es decir, un dilogo de besugos distribuidos).
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 174/313 -
Internet (un sistema distribuido, a fin de cuentas) ha influido mucho en la
popularidad de los sistemas distribuidos. Internet ofrece una base fsica y lgica
para el desarrollo de aplicaciones distribuidas. La familia de protocolos TCP/IP
permite edificar aplicaciones sobre la capa de transporte; el protocolo HTTP
puede usarse para los mensajes entre elementos o componentes distribuidos,
etc.
En el caso de muchas empresas, la posibilidad de contar con un medio
como Internet como base para sus aplicaciones distribuidas ha ayudado a que
estas empresas hayan optado por soluciones distribuidas, pues no necesitan
disponer de redes propias (WAN) para hacerlas funcionar entre oficinas,
sucursales, departamentos, etc.
Figura 83. Evolucin de los sistemas distribuidos
Arriba se muestra un esquema muy simplificado de la evolucin de los sistemas
distribuidos. En 2004 todava conviven muchas de las tecnologas de la figura. Pese a
todas las inversiones en tecnologas distribuidas enfocadas al comercio electrnico, el
correo electrnico viene a ser el sistema ms usado para encargar pedidos, enviar
facturas, enviar albaranes, etc.
La tecnologa RPC fue el antecesor directo de CORBA y se podra considerar
como una tecnologa distribuida procedural, no orientada a objetos. Actualmente ha
cado en desuso.
[Link]
Miguel ngel Abin, Julio 2004 - 175/313 -
4.2. Aplicaciones y sistemas distribuidos
Se llama sistema distribuido a aquel cuyos componentes de hardware y
software, ubicados en diferentes mquinas conectadas en red, se comunican slo
mediante el intercambio de mensajes. Internet es un buen ejemplo de sistema
distribuido, con una ms que aceptable tolerancia a fallos de las redes que la
componen.
Se llama aplicacin distribuida a la que se ejecuta en un sistema distribuido; en
consecuencia, tiene repartidas sus funciones o servicios entre varias mquinas de una
red. En una aplicacin as, el cdigo y los datos se reparten entre distintas mquinas.
Muchas aplicaciones distribuidas se usan para lograr dos metas: a) compartir recursos
(disco duro, RAM, impresoras, etc.); y b) repartir la carga de trabajo entre varias
mquinas, en funcin de la capacidad de cada una.
De acuerdo con la European Conference on Object Oriented Programming
(ECOOP) de 1996, un componente se define como una unidad de composicin con
interfaces contractuales especificas y dependencias de contexto explcitas. De
acuerdo con Component Software: Beyond Object Oriented Programming [C.
Szyperski, 1998], Un componente de software puede desarrollarse de manera
independiente y puede ser usado por terceras partes para integrarlo mediante
composicin a sus sistemas. Un componente distribuido es una unidad binaria que
puede instalarse y usarse en cualquier mquina de una red. No es, por tanto, una
biblioteca de clases, una biblioteca dinmica o un conjunto de cdigo.
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 Cal cMat 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.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 176/313 -
En cambio, si Cal cMat se creara como un componente distribuido, podra ser usado
mediante los protocolos pertinentes por muchas mquinas, cumplieran o no los
requisitos para ejecutarlo en modo local. En este caso, Cal cMat vendra a ser un
servicio de red, como el de transferencia de archivos (basado en FTP) o el de acceso a
pginas web (basado en HTTP). Un usuario podra llamar al servicio Cal cMat desde
un ordenador domstico y enviar sus clculos. Cal cMat repartira el esfuerzo de
clculo necesario entre las mquinas donde se ejecuta el componente y devolvera los
clculos al usuario. Sera equivalente, en cuanto a proceso, a llamar a una pgina web
desde un navegador.
Figura 85. El componente CalcMat en funcionamiento
Las posibilidades de las aplicaciones distribuidas son infinitas: uno puede imaginar
servicios financieros, mdicos, de meteorologa, de comercio electrnico...
Imaginemos, por poner un solo ejemplo, que una empresa desarrolla un componente
distribuido para llevar el seguimiento del estado actual de un pedido, de modo que en
cada momento se puede saber el lugar donde se encuentra, el medio de transporte en
que viaja, si se esperan retrasos, etc. Esa empresa puede ofrecer el componente a las
tiendas virtuales de Internet para que no tengan que preocuparse de llevar el control de
los envos. Si un usuario quisiera saber el estado de su pedido, se conectara a la
tienda virtual donde lo hizo, se identificara y solicitara la informacin concerniente a su
pedido; la tienda virtual llamara, mediante los protocolos adecuados, al componente
distribuido y mostrara al usuario la informacin que aqul le devolviera. Miles de
compradores podran estar usando a la vez el componente distribuido, aunque no lo
supiesen. Por lo que s, UPS usa un sistema similar al descrito.
Mtodo 1
Componente
CalcMat
Mtodo 2
Mtodo 3
Mquina A
Cliente 1
Cliente 3
Cliente 2
Mquina B
Mquina C
Miguel ngel Abin, Mayo 2004
EJEMPLO DE USO DEL COMPONENTE CalcMat
[Link]
Miguel ngel Abin, Julio 2004 - 177/313 -
Disear e implementar sistemas distribuidos obliga a considerar muchos factores
que se obvian cuando se hace lo propio con aplicaciones que se ejecutan en una sola
mquina. stos son algunos factores que obligatoriamente deben tenerse en cuenta a
la hora de disear sistemas distribuidos:
La heterogeneidad de los elementos usados: hardware, sistemas
operativos, redes, protocolos...
La ejecucin de aplicaciones o procesos concurrentes.
El tratamiento de los fallos: cada componente, sea de hardware o de
software, puede fallar, y se necesita que cada componente conozca todos
los posibles fallos que pueden suceder en los otros. Por aadidura, se
presenta el problema de que muchos fallos no son reproducibles.
La escalabilidad del sistema, entendiendo como tal la capacidad de que el
coste de aadir nuevos usuarios al sistema sea constante en relacin con
los recursos que requerira su incorporacin. Un sistema escalable se
adaptar con facilidad a futuros aumentos de su carga de trabajo.
La seguridad del sistema. Lo usual es que exista informacin que deba
transmitirse codificada, as como servicios restringidos a ciertos usuarios.
El grado de apertura del sistema. Interesa que cada parte sea lo ms
estndar posible y que su documentacin sea clara.
La localizacin de los servicios ofrecidos. Debe saberse cmo localizarlos.
La persistencia de los datos. Debe especificarse dnde y cmo se
guardan.
Muchas aplicaciones distribuidas, si bien no todas, pueden disearse e
implementarse siguiendo el modelo cliente-servidor. Deben tomarse los trminos
cliente y servidor en el sentido general dado en el apartado 2.3.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 178/313 -
La programacin orientada a objetos (POO) simplifica el desarrollo de software
mediante la agrupacin en clases de datos y operaciones relacionados, y mediante
la separacin clara entre interfaz e implementacin. En general, los programas OO
muestran estructuras recurrentes que promueven la abstraccin, el encapsulado, la
modularidad, la flexibilidad. La motivacin para usar la POO en el diseo e
implementacin de aplicaciones distribuidas reside en lo decisivas que resultan esas
caractersticas para crear sistemas robustos y flexibles. Si bien pueden escribirse
componentes no basados en objetos, la tendencia dominante hoy da consiste en
construir los componentes mediante POO.
En las aplicaciones distribuidas que usan objetos, los objetos que viven en un
anfitrin pueden llamar a mtodos de objetos residentes en otros anfitriones, ya sea
para trabajar con ellos interactivamente o para delegar en ellos parte de sus tareas. Los
objetos que residen en un cierto espacio de direcciones de memoria (conjunto de
posiciones de memoria asociadas a un proceso) de un anfitrin son objetos locales; los
que residen en otros espacios de direcciones son objetos remotos. Estos ltimos
espacios de direcciones pueden ubicarse en distintos anfitriones; es ms, sa
constituye la situacin habitual en las aplicaciones distribuidas. Remoto y local no son
trminos absolutos, pues un objeto remoto siempre es local para el espacio de
direcciones que lo alberga. Siempre deben interpretarse estos trminos como relativos
a una determinada comunicacin entre objetos, no como asociados permanentemente
a la ubicacin de los anfitriones o de los objetos.
Las llamadas a mtodos de objetos remotos se conocen como llamadas a
mtodos remotos o llamadas remotas. En ellas, un objeto almacenado en un espacio
de direcciones de un anfitrin llama a mtodos de objetos almacenados en otros
espacios de direcciones (estn o no en el mismo anfitrin). Por contraposicin, las
llamadas a mtodos locales o llamadas locales son llamadas a mtodos entre objetos
que viven en un mismo espacio de direcciones (es decir, que forman parte de un
mismo proceso).
Se denomina objeto cliente al objeto que llama a un mtodo remoto, y objeto
servidor a aquel cuyos mtodos son invocados. En este apartado usar de forma
intercambiable objeto cliente y objeto local, as como objeto remoto y objeto servidor;
verdad es que un objeto local puede no ser cliente y que uno remoto puede no ser
servidor, pero entonces careceran de inters para el estudio de las aplicaciones
distribuidas. Asimismo, en lo que sigue usar indistintamente objeto cliente y cliente,
as como objeto servidor y servidor; cuando me interese llamar la atencin sobre los
procesos y no sobre los objetos, antepondr la palabra proceso (proceso servidor).
De modo general, en una aplicacin distribuida en ejecucin, la parte que acta
como cliente estar formada por un conjunto de objetos (donde estarn los objetos
cliente); y la parte que acta como servidor, por otro conjunto de objetos (donde
estarn los objetos servidor).
En la figura 86 se muestra un ejemplo de integracin de las tecnologas de objetos
distribuidos con una aplicacin cliente-servidor web.
[Link]
Miguel ngel Abin, Julio 2004 - 179/313 -
Figura 86. Ejemplo de integracin entre las tecnologas distribuidas y la navegacin
web
Al lector interesado en conocer a fondo los sistemas distribuidos le recomiendo
estos libros: Distributed Systems, Concepts and Design 3rd Edition [G. Coulouris et
al., 2001], Advanced CORBA Programming with C++ [M. Henning, 2001] y UNIX
Distributed Programming [M. Henning y S. Vinoski, 1999]. Son libros densos, que
requieren paciencia y un buen conocimiento de C/C++ y de la estructura de los
sistemas operativos actuales; con todo, vale la pena leerlos si uno quiere manejar con
soltura sistemas distribuidos. En cuanto a libros del estilo Aprenda CORBA en 24
horas, le aseguro que no podrn cumplir la promesa del ttulo salvo que usted conozca
muy bien la estructura de los sistemas distribuidos y sepa programar ms que
competentemente en C/C++; y, en ese caso, para qu los necesita?
Hace poco (en abril de 2004), se public el libro Network Distributed Computing:
Fitscapes and Fallacies [Max K. Goff, 2004]. Es este un libro muy recomendable para
cualquiera que desee conocer el estado actual de los sistemas distribuidos y sus
expectativas. Dedica bastante espacio a las tecnologas de Sun, en parte porque la
actividad profesional de Goff se ha centrado en ellas y en parte porque las
observaciones y principios contenidos de aqu en adelante transcienden cualquier
agenda o aproximacin especfica de una empresa; la tesis de Church-Turing se aplica
tambin a la computacin distribuida en redes.
EJEMPLO DEL USO DE OBJETOS DISTRIBUIDOS EN
UNA APLICACIN NAVEGADOR-SERVIDOR WEB
Navegador
HTTP/HTML
Servidor de
aplicaciones
Tecnologa
de objetos
distribuidos:
CORBA, RMI,
etc.
HTTP/HTML/DHTML
Miguel ngel Abin, Abril 2004
Servidor web
Servidor de
aplicaciones
web
Servidor de
aplicaciones
HTTP/HTML
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 180/313 -
4.3. Dos ejemplos de arquitecturas distribuidas: CORBA y los servicios web
He escogido dos ejemplos de arquitecturas distribuidas: CORBA y los servicios
web. Ambas son las ms populares y extendidas, y proporcionan un buen comienzo
para ver cmo pueden solucionarse los problemas inherentes a las aplicaciones
distribuidas.
Los servicios web han sufrido tal exceso de promocin y publicidad que se hace
necesario entender qu aportan con respecto a tecnologas anteriores como CORBA.
Los ingenieros del software suelen decantarse por CORBA, mientras que los
programadores prefieren usar servicios web. Los motivos que suelen dar unos y otros
para su predisposicin hacia una u otra tecnologa corresponden ms a las respuestas
a un cuestionario religioso que a otra cosa.
Dado que no tengo dios ni amo en cuanto a tecnologas informticas, dar al final
del subapartado mis propias opiniones sobre los servicios web. Con ellas, no trato de
dar un trato de favor a CORBA, como comprobar si contina leyendo (mis objeciones
a esta tecnologa aparecen en los siguientes prrafos y en el apartado 6); sino sealar
los fallos y carencias que los comerciales y publicistas de los servicios web parecen
olvidar y callar, en una amnesia y un mutismo cuando menos sospechosos. Como
CORBA se explicar con mucho ms detalle en el apartado 6, si el lector desea
comparar ambas tecnologas disponiendo de ms criterios de juicio puede volver aqu
cuando termine dicho apartado.
CORBA (Common Object Request Broker Architecture: arquitectura comn de
intermediacin de solicitudes de objetos) es una especificacin abierta e independiente
del vendedor, desarrollada por el OMG (Object Management Group: grupo de gestin
de objetos) para disear aplicaciones distribuidas mediante objetos.
El OMG es un consorcio internacional con ms de 850 miembros, entre los cuales
se encuentran empresas como IBM, Sun, Boeing, Alcatel, e instituciones y
universidades como la NASA, INRIA y LIFL. Este consorcio funciona como una
organizacin no comercial. Se fund en 1989 como una organizacin estadounidense
sin nimo de lucro, con representacin en todo el mundo. El OMG cuenta con una
plantilla bastante reducida porque no se dedica a construir o vender software, sino a
publicar especificaciones o normas (como el Centro Europeo de Normalizacin o CEN).
Las especificaciones publicadas por el OMG pueden ser implementadas por cualquier
empresa u organizacin, sin pagar al OMG derechos de autor o licencias. Las
empresas fabricantes de software tienen el control de sus implementaciones basadas
en especificaciones del OMG, pero carecen de derechos sobre las especificaciones.
Slo el OMG puede modificar las especificaciones que define o decidir cul ser su
evolucin. Si una empresa miembro del consorcio hace una propuesta para una
especificacin y es aceptada, la propuesta queda como propiedad del consorcio, no de
la empresa que la ha hecho.
El objetivo ltimo de CORBA consiste en dar a quienes sigan la especificacin la
capacidad de que un proceso pueda llamar a procesos que se ejecuten en otros
anfitriones, con independencia de las plataformas y lenguajes usados. La versin 1.1
de CORBA se lanz en 1991.
CORBA es independiente del lenguaje o lenguajes utilizados para implementar las
aplicaciones distribuidas; y, por ende, permite ahora trabajar con cdigo que ya exista
y permitir en el futuro comunicarse con lenguajes que todava no existen (siempre que
fueren compatibles con CORBA). CORBA se usa en empresas qumicas, de comercio
[Link]
Miguel ngel Abin, Julio 2004 - 181/313 -
electrnico, aeroespaciales, de finanzas, de recursos humanos, de investigacin, de
telecomunicaciones, de defensa, etc. Entre las grandes empresas que usan CORBA
estn AT&T, Lucent, Nokia y Boeing.
Con todo, la compleja estructura interna de CORBA y el elevado coste de sus
implementaciones han supuesto un pesado lastre para su aceptacin en el mercado.
Pese a sus indudables cualidades y pese a contar con el respaldo del OMG, apenas ha
conseguido introducirse en las pequeas y medianas empresas. Otros dos problemas
que han obstaculizado la introduccin de CORBA en el mundo empresarial han sido
sus deficientes primeras implementaciones, que daban lugar a problemas de
interoperabilidad entre productos de distintos vendederos, y la nula integracin de los
primeros productos CORBA con los cortafuegos, presentes en cualquier red
empresarial o corporativa. Existen desde hace tiempo implementaciones que solventan
los dos problemas; pero nada ha podido remediar la desconfianza inicial de muchas
empresas hacia esta tecnologa, consecuencia de implementar especificaciones en las
que se debera haber trabajado ms antes de ponerlas a disposicin de los fabricantes
de software.
En el apartado 6 se ver una exposicin de la estructura de CORBA y se explicar
cmo puede usarse desde Java. Por ello, prefiero no alargarme aqu en torno a
CORBA.
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.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 182/313 -
Figura 87. Arquitectura de los servicios web. Figura de Sandra Aguirre
En la figura anterior hay tres elementos:
UDDI: Permite obtener listas de los servicios disponibles y localizarlos
de manera rpida. Una vez localizado un servicio mediante UDDI,
puede usarse la interfaz pblica del servicio. UDDI es un servicio web
que se usa para encontrar dinmicamente otros servicios web.
WDSL: Permite describir las interfaces de los servicios, de manera
que las aplicaciones puedan utilizarlas para saber cmo interoperar
con los servicios (qu campos XML deben tener las peticiones, etc.).
Las interfaces descritas por WDSL tienen una apariencia muy similar a
las interfaces de Java.
SOAP: Incluye los mecanismos para la ejecucin de llamadas remotas
entre aplicaciones.
Suministrador de
servicios web
ARQUITECTURA DE LOS SERVICIOS WEB
3. Utilizar el servicio
1. Describir y
publicar
el servicio
2. Localizar
el servicio
XML
(SOAP)
XML
(SOAP)
XML
(WSDL)
XML
(WSDL)
XML
(UDDI)
XML
(UDDI)
XML
(SOAP)
XML
(SOAP)
Servicio
Servicio
Servicio
Servicio
W
E
B
Directorio
servicios web
Directorio
servicios web
UDDI
XML
(WSDL)
XML
(WSDL)
Cliente
[Link]
Miguel ngel Abin, Julio 2004 - 183/313 -
Figura 88. Llamadas y respuestas con SOAP. Figura de Sandra Aguirre
Figura 89. Los servicios web se construyen sobre HTTP
<?xml version="1.0" encoding="iso-8859-1" ?>
<SOAP-ENV:Envelope >
<SOAP-ENV:Body >
<VerPrecioProducto >
<codigo>GRP0112</codigo>
</VerPrecioProducto>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
<?xml version="1.0" encoding="iso-8859-1" ?>
<SOAP-ENV:Envelope >
<SOAP-ENV:Body >
<VerPrecioProductoRespuesta >
<precio divisa=euro>62800</precio>
</VerPrecioProductoRespuesta>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Llamada a un
servicio web
(SOAP)
Respuesta del
servicio
(SOAP)
LLAMADA Y RESPUESTA A UN SERVICIO WEB
MEDIANTE SOAP
Argumento
de la
llamada
Valor
devuelto
por la
llamada
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 184/313 -
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 [ WebMet hod] .
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 [ WebMet hod] 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 [ WebMet hod] 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
[Link]
Miguel ngel Abin, Julio 2004 - 185/313 -
as: tienen que considerar todas las situaciones en las que puede verse envuelta una
aplicacin distribuida de tipo empresarial.
Figura 90. Cdigo en C#. No intente usarlo para escribir aplicaciones
empresariales. Como puede suponer, los ingenieros de CORBA, de Sun y de
muchas empresas no han gastado aos de trabajo y millones de dlares para que
todos los problemas de las llamadas remotas se resuelvan con [WebMethod]
Imagino que CORBA sobrevivir en la parte de servidor de las aplicaciones
distribuidas, en mainframes y servidores UNIX, donde la escalabilidad y la eficacia son
imprescindibles; y que los servicios web se usarn en el lado del cliente, donde la
configuracin de CORBA nunca ha sido tan fcil como debera haber sido. No creo que
los servicios web sean un punto de partida para construir nuevas aplicaciones, mejores
y ms eficaces. Ms bien considero que definen una aproximacin sencilla para
resolver los problemas de interoperabilidad entre aplicaciones escritas en distintos
lenguajes y que se ejecutan en diferentes plataformas. CORBA tiene tambin
soluciones para esos problemas (comunes a todos los sistemas distribuidos), pero no
son sencillas.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 186/313 -
Figura 91. Integracin entre sistemas heterogneos mediante servicios web
Figura 92. Ms integracin entre sistemas heterogneos mediante servicios web
LOS SERVICIOS WEB COMO ENVOLTORIOS
Clientes
.NET
J2EE
CORBA
COBOL
C/C++
Smalltalk
Mensajes XML
Servidores
Envoltorio de los servicios web
Miguel ngel Abin Julio 2004
[Link]
Miguel ngel Abin, Julio 2004 - 187/313 -
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 [ WebMet hod] , 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 [ WebMet hod] 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 doubl e cal cul ar Amor t i zaci on1987
( doubl e i mpor t e) . 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
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 188/313 -
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.
[Link]
Miguel ngel Abin, Julio 2004 - 189/313 -
5. RMI: llamando desde lugares remotos
5.1. Fundamentos de la RMI: el modelo de objetos distribuidos de Java
Los sockets de Java, basados en TCP/IP, se usan para programar aplicaciones
distribuidas (en el apartado 2 vimos varios ejemplos simples, y veremos ms en
prximos apartados); pero a veces se necesitan enfoques ms complejos, ms
cercanos a CORBA. En esos casos, la API RMI de Java (Remote Method Invocation:
invocacin de mtodos remotos o ejecucin de mtodos remotos) es la mejor opcin,
salvo que se quiere programar con sockets gran parte de las funciones que la interfaz
de mtodos remotos ya incluye. Internamente, esta interfaz utiliza sockets TCP por
defecto. Como los sockets estn ms cercanos al sistema operativo que la RMI,
consumen menos recursos y son ms fciles de integrar con redes protegidas por
cortafuegos. En contrapartida, la RMI es ms fcil de integrar con otras API de Java
(JDBC, por ejemplo) y con sistemas heredados.
Con la RMI, un objeto de Java puede sealarse como remoto, de forma que los
procesos remotos de las aplicaciones distribuidas puedan acceder a l como si fuera
un objeto de Java normal.
De acuerdo con David Curtis, director de tecnologas de plataforma en el OMG, la
RMI de Java es una tecnologa de programacin, mientras que CORBA es una
tecnologa de integracin. Ambas llevan grabadas en sus objetivos una misma leyenda:
INTEROPERABILIDAD, si bien RMI es una tecnologa mongama en cuanto al
lenguaje y CORBA es polgama.
La API RMI, incluida en todos los JDK de Java desde la versin 1.1 (1995), incluye
su propio modelo de objetos distribuidos, optimizado para las caractersticas de Java.
De este hecho se derivan tres importantes consecuencias:
El modelo de objetos distribuidos de Java no coincide con el de CORBA,
que es independiente del lenguaje de programacin usado. CORBA se
puede usar desde Java, si bien se hace necesario traducir los objetos de un
modelo a otro, y viceversa.
Cualquier plataforma para la que exista un JDK (1.1 o posterior) puede usar
la RMI.
La RMI es mucho ms sencilla y eficaz que CORBA si se va a usar Java
como lenguaje de desarrollo, pues se adapta como un guante al modelo de
objetos de Java (mucho ms simple que el de CORBA) y saca partido de
todas las cualidades de Java. Si en una aplicacin distribuida se va a
emplear slo Java, la RMI tiene muchas ventajas sobre CORBA. Si hay
partes escritas en C o C++, debe valorarse la opcin de CORBA, siempre
que la aplicacin sea lo bastante compleja.
En el modelo de objetos distribuidos de Java, un objeto remoto es aquel cuyos
mtodos pueden llamarse desde otra mquina virtual Java (MVJ), la cual puede
ejecutarse en otro anfitrin o nodo. En consecuencia, un objeto remoto ubicado en un
proceso puede recibir llamadas desde otros procesos (distintos procesos se ejecutan
en distintos espacios de direcciones). Una clase remota es cualquier clase cuyas
instancias son objetos remotos. Dentro del espacio de direcciones de la MVJ donde se
crea un objeto remoto, ste es un objeto normal y corriente: puede usarse como
cualquier objeto de Java.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 190/313 -
Una llamada a un mtodo remoto o una llamada remota es una llamada a un
mtodo de un objeto remoto desde un espacio de direcciones donde ste no reside.
Dos objetos pertenecientes a distintas MVJ pueden interaccionar mediante llamadas
remotas. Las llamadas a mtodos locales o llamadas locales son llamadas entre
objetos que residen en una misma MVJ. Todo clase remota en Java implementa a una
o ms interfaces remotas en las que se declaran los mtodos remotos (uso aqu
interfaces en el sentido de construcciones del lenguaje Java definidas mediante la
palabra reservada i nt er f ace).
Java permite trabajar con objetos situados en anfitriones remotos como si
estuvieran en el local, con la misma sintaxis que tienen las llamadas locales y de un
modo absolutamente transparente para el programador. La palabra clave es como: tras
las bambalinas slo se oye el zumbido sordo y constante de los datagramas que van y
vienen, sabedores de que el tiempo juega en contra de ellos; delante de ellas, RMI
representa una obra teatral en la que todo ese vaivn de datagramas se muestra en
forma de lmpidas llamadas a interfaces remotas. Incluso hace posible que en un
anfitrin se puedan crear objetos de forma dinmica y que los dems anfitriones
puedan usar los mtodos de los nuevos objetos, aun cuando la aplicacin distribuida
nunca hubiera tratado antes con esos objetos.
Otra caracterstica del modelo de objetos distribuidos de Java es que los objetos
locales no llaman directamente a los mtodos de los objetos remotos: utilizan las
interfaces remotas de estos ltimos. Los clientes no necesitan ms que la interfaz
remota para llamar a los mtodos de los objetos remotos. La interfaz local de un objeto
puede no coincidir con la interfaz remota. Asimismo, un objeto remoto puede presentar
distintas interfaces remotas, dependiendo del modo de acceso. As, un objeto remoto
puede ofrecer distintas interfaces remotas a los objetos, dependiendo de si se ejecutan
con unos permisos u otros (en un sistema suelen convivir en paz y armona usuarios
normales, usuarios con privilegios, administradores de red, etc.).
El uso de las interfaces remotas proporciona varias ventajas a RMI:
Las implementaciones de los mtodos quedan a salvo de las miradas de
los clientes.
Si hay modificaciones en las implementaciones de los mtodos remotos,
no necesitan ser comunicadas a los clientes (siempre que se respete la
interfaz remota).
Para ilustrar lo expuesto, considerar el ejemplo del componente Cal cMat del
subapartado 4.2. En Java se implementara mediante una clase y una interfaz:
[Link]
Miguel ngel Abin, Julio 2004 - 191/313 -
i mpor t j ava. r mi . *;
publ i c i nt er f ace Cal cMat ext ends Remot e {
doubl e hacer Cal cul oMuyCompl i cado( doubl e a, doubl e b)
t hr ows r emot eExcept i on;
/ / Rest o de decl ar aci ones de mt odos
}
i mpor t j ava. r mi . *;
i mpor t j ava. r mi . ser ver . *;
publ i c cl ass Cal cMat I mp ext ends Uni cast Remot eObj ect
i mpl ement s Cal cMat {
publ i c doubl e hacer Cal cul oMuyCompl i cado( doubl e a, doubl e b)
t hr ows r emot eExcept i on {
/ / Cuer po del mt odo
}
/ / Rest o de decl ar aci ones de mt odos y mt odo mai n
}
Un cliente que deseara acceder al servicio de clculo matemtico se conectara
as:
Cal cMat cm= new Regi st r o( " anf i t r i on" , " nombr eObj et o" ) ;
cm. hacer Cal cul oMuyCompl i cado( 2. 5656, 3. 14159265358972) ;
Regi st r o sera una clase encargada de conectar con el anfitrin donde se
ejecute Cal cMat , de localizar el objeto remoto nombr eObj et o, instancia de la clase
Cal cMat I mp, 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 Regi st r o: 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
Toda interfaz remota debe
extender la interfaz
j ava. r mi . Remot e
Toda mtodo remoto debe declarar la
excepcin
j ava. r mi . Remot eExcept i on
Es conveniente que extienda a
Uni cast Remot eObj ect
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 192/313 -
transmisin de la solicitud por la red y la respuesta resultante. Pero no incluye al
software que presta el servicio real; esto pertenece a los dominios del servidor.
Tampoco a la interfaz del usuario ni a la lgica de la aplicacin, en los dominios
del cliente.
Sin pecar de puristas, se puede aceptar que el middleware es una capa de
software que media entre clientes y servidores, y que separa las comunicaciones
cliente-servidor de los protocolos de red y de los mecanismos de comunicacin entre
procesos (como sockets). Con el middleware se ocultan a los programadores los
orgenes reales de los datos de las aplicaciones distribuidas y los detalles de las redes
que median entre los anfitriones. Gracias a l, todas las aplicaciones pueden trabajar
con una API comn, independiente de la plataforma.
Figura 93. Ubicacin del middleware en una arquitectura c-s de dos capas
[Link]
Miguel ngel Abin, Julio 2004 - 193/313 -
Figura 94. Representacin lgica del middleware
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 194/313 -
5.2. Anatoma de las aplicaciones RMI: adaptadores y esqueletos. La arquitectura
RMI. El servicio de registro remoto RMI
5.2.1. Anatoma de las aplicaciones RMI: adaptadores y esqueletos
Una aplicacin RMI admite la descomposicin en dos aplicaciones separadas: un
servidor y un cliente. El servidor se encarga de crear los objetos remotos, los hace
accesibles a los otros objetos de la aplicacin y permanece a la espera de peticiones
para dichos objetos remotos (llamadas). El cliente consigue referencias remotas a uno
o ms objetos remotos y usa estas referencias para hacer llamadas remotas.
Aunque toda la estructura de la RMI de Java corresponde al modelo cliente-
servidor, est adornada con sus propios ornamentos. En ella, un objeto cliente nunca
accede directamente a los servicios o mtodos de un objeto remoto: entre uno y otro
siempre median un adaptador y un esqueleto.
Un adaptador (stub; mi traduccin es, en realidad, una adaptacin: stub significa
cabo o resguardo) es un objeto que acta como representante local (proxy) de un
objeto remoto. Una clase adaptadora implementa exactamente el conjunto de
interfaces remotas de la clase remota a la cual aparece vinculada. Cuando un objeto
local llama a cualquier mtodo de la interfaz remota de un objeto remoto, en verdad
llama a los mtodos del adaptador local (los cuales, como ya he avanzado, coinciden
fielmente con los declarados remotos), que se encargan de transmitir su llamada al
remoto objeto. En consecuencia, no hay comunicacin directa entre los objetos locales
y los remotos: cuando un objeto local llama a un mtodo de un objeto remoto, la
llamada pasa al adaptador asociado a este ltimo. Al momento, el adaptador o stub
inicia una conexin con la MVJ donde reside el objeto remoto, enva los argumentos del
mtodo a esa MVJ, espera el resultado de la llamada, lee el valor devuelto por sta
(suponiendo que el mtodo no sea voi d y que no se haya lanzado ninguna excepcin)
y lo devuelve al objeto local que comenz la llamada remota.
Un esqueleto (skeleton) es un objeto que acta como representante remoto
(proxy) del objeto remoto; reside, pues, en la MVJ remota. Es la contrapartida remota
del adaptador. El esqueleto se encarga de transmitir las llamadas que vienen desde
fuera al objeto remoto. Cuando recibe una llamada entrante desde una MVJ fornea,
lee los argumentos enviados, llama localmente al mtodo correspondiente del objeto
remoto y enva su respuesta a la MVJ que hizo la peticin.
Las clases de los adaptadores y los esqueletos no se programan, sino que las
genera RMI, si bien se necesita compilarlas manualmente (salvo en el JDK 1.5, que
permite la compilacin dinmica de las primeras; esta propiedad no se explorar aqu).
En el subapartado 5.5 veremos cmo generarlas.
Advertencia: En la versin 1.2 del JDK, se desarroll una implementacin de
la RMI que no necesita esqueletos (los suple con el uso de la reflexin). Por
lo tanto, slo es imprescindible usar esqueletos con el JDK 1.1. En este texto
seguir usando esqueletos por compatibilidad, pese a su fnebre nombre y
destino; pero no son ya necesarios. Si el lector slo trabaja con el JDK 1.2 o
posterior, puede leer el texto olvidndose de los esqueletos. Con ese
nombre, su destino estaba escrito desde el principio.
[Link]
Miguel ngel Abin, Julio 2004 - 195/313 -
Figura 95. Relaciones entre varios elementos de RMI
Los aficionados a la navaja de Occam, ilustre navajista del siglo XIV, harn muy
bien preguntndose por qu se necesitan dos entidades ms o si son realmente
imprescindibles. Pues bien: s lo son. Un objeto remoto y uno local viven en mquinas
virtuales Java distintas. Directamente, un objeto local no puede pasarse por referencia
a un mtodo de un objeto remoto, pues las direcciones locales de memoria no tienen
sentido para las MVJ remotas. Una direccin de memoria que corresponda a un objeto
en la pila de la MVJ remota puede corresponder a cualquier otro objeto (o a ninguno)
en otra MVJ. Dado que la comunicacin directa es imposible, deben existir
intermediarios que operen de puente entre unas MVJ y otras. Precisamente, esos
intermediarios son los adaptadores y esqueletos.
Cuando un objeto local llama a un mtodo remoto, su llamada pasa al adaptador
correspondiente. Un adaptador es, a fin de cuentas, una referencia al objeto remoto
con que se halla vinculado o, si se prefiere, una referencia remota. Esta referencia no
es una referencia de memoria o un puntero, pues no tendra sentido en un espacio de
direcciones que no fuera aquel donde se cre. Una referencia remota contiene una
direccin de Internet (la del anfitrin donde est el objeto remoto), un nmero de puerto
(por donde el objeto remoto espera peticiones), un nmero nico con respecto a un
anfitrin, que identifica al objeto remoto, y una interfaz remota.
Objeto
cliente
Stub Skeleton
Objeto
servidor
Interfaz remota
implementa
implementa
MVJ LOCAL
MVJ REMOTA
Miguel ngel Abin, Mayo 2004
IMPLEMENTACIN DE LA INTERFAZ
REMOTA
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 196/313 -
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 . cl ass
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 . cl ass?
La contestacin a la primera es que se utilizan unas subclases de
[Link] y de [Link], no estas
clases. Por ejemplo, se usa la subclase de Obj ect Out put St r eam
[Link]. Obj ect Out puSt r eam define un
mtodo pr ot ect ed voi d annot at eCl ass ( Cl ass cl ase) t hr ows
I OExcept i on que no hace nada (no est implementado). Pese a ello, siempre que
Obj ect Out put St r eam escribe las descripciones de las clases, llama a
annot at eCl ass( ) . Si se incluye este mtodo es con vistas a que los programadores
y la RMI puedan implementarlo en las subclases de Obj ect Out put St r eam. 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 Obj ect I nput St r eam, la subclase encargada del proceso de
deserializacin redefine el mtodo pr ot ect ed Cl ass
r esol veCl ass( Obj ect St r eamCl ass descr i pci on) t hr ows I OExcept i on,
Cl assNot FoundExcept i on, 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 Obj ect I nput St r eamy Obj ect Out put St r eam; 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 . cl ass 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
.cl ass de la aplicacin estn en los sistemas locales de archivos de todos los
anfitriones donde se ejecuta. Por ello, las subclases de Obj ect Out put St r eamque
usa RMI redefinen el mtodo annot at eCl ass( ) para que permita grabar en el flujo de
bytes informacin sobre la codebase (especificada en la propiedad
[Link]
Miguel ngel Abin, Julio 2004 - 197/313 -
j ava. r mi . ser ver . codebase, que veremos un poco ms adelante). Una codebase
no es ms que un lugar (o varios) desde donde se pueden cargar clases en una MVJ,
en forma de URL. Dicho de otro modo, no es ms que un URL que especifica una
localizacin en la red desde la cual pueden cargarse los bytecodes de los ficheros
. cl ass que se necesitan para deserializar los objetos dentro del flujo. Veamos un
ejemplo de codebase (considero que las clases estn en un fichero mi scl ases. j ar ):
ht t p: / / www. uv. es: 9000/ di r ect or i ocl ases/ mi scl ases. j ar
Usando codebases, la RMI puede cargar dinmicamente nuevas clases
basndose en la informacin sobre ellas que obtenga del flujo; para ello usa la clase
[Link], que veremos ms adelante. Resulta lgico
que codebase tenga la forma de un URL: si al serializar se grabara informacin sobre la
localizacin de las clases en el sistema local de archivos, la MVJ que deserializara
instancias de estas clases se encontrara con que esas localizaciones no existen en el
sistema de archivos de su anfitrin (la probabilidad de tener dos mquinas con
idnticas estructuras de directorios es muy reducida).
Usando la versin redefinida de annot at eCl ass( ) , la RMI graba para cada
objeto que serializa (no olvidemos que todos los argumentos de mtodos remotos y sus
valores de retorno se pasan serializados) la propiedad
j ava. r mi . ser ver . codebase, que contiene las codebases y debe ser establecida
al compilar la clase del objeto. Los objetos que deserialicen el flujo leern esta
propiedad mediante la versin redefinida del mtodo r esol veCl ass( ) y sabrn de
dnde cargar las clases que necesiten para reconstruir los objetos dentro del flujo. Por
ejemplo, consideramos la ejecucin de una clase Nomi na que deserialice instancias de
una clase Empl eado (reduzco el tipo de letra para que el comando quepa en una
lnea):
j ava Dj ava. r mi . ser ver . codebase=ht t p: / / www. uv. es/ di r ect or i ocl ases/ Nomi na
Cualquier objeto remoto Nomi na que trate de deserializar en tiempo de ejecucin
una instancia de Empl eado buscar por medio de
[Link] en el URL especificado el archivo . cl ass
(Empl eado. cl ass) que necesita para cargar dinmicamente la clase Empl eado. Eso
s, antes de buscar en el URL, buscar en el directorio actual y en el CLASSPATH, y si
la encuentra ignorar la propiedad j ava. r mi . ser ver . codebase. Si la propiedad
j ava. r mi . ser ver . codebase no se especifica, y los archivos . cl ass que necesita
un objeto que deserializa no estn en su directorio actual ni aparecen en su
CLASSPATH local, la MVJ lanzar una excepcin [Link].
En general, si para ejecutar una clase se establece la propiedad
[Link], cualquier proceso remoto que necesite cargar
archivos .class para objetos recibidos durante una sesin RMI usar ese URL
para encontrar los .class (siempre que no pudiera hallarlos antes en el
CLASSPATH local). Veamos un ejemplo:
j ava Dj ava. r mi . ser ver . codebase=ht t p: / / www. uv. es/ mi scl ases/ Cal cMat
La MVJ donde se ejecute Cal cMat intentar buscar todas los archivos . cl ass
que necesite (si no los encuentra antes en su directorio actual ni en su CLASSPATH
local) en el URL ht t p: / / www. uv. es/ mi scl ases. Si los encuentra, los descargar.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 198/313 -
Descargar clases implica considerar ciertas cuestiones relativas a la seguridad,
que se vern en el subapartado 5.5.
Cuando un esqueleto recibe a travs de la red un flujo de bytes enviado por un
adaptador, flujo donde se encuentran incrustados los argumentos de la llamada remota,
para deserializarlo lee las descripciones de las clases de los objetos incluidos en el flujo
y busca los archivos . cl ass correspondientes. Primero busca en su directorio, luego
en su CLASSPATH; si no los encuentra, contina buscando en el codebase o los
codebases que figuren en el flujo (suponiendo que se especificara la propiedad
j ava. r mi . ser ver . codebase). Si los encuentra, crea las instancias de los objetos
en su espacio de direcciones. En caso contrario (el URL puede ser incorrecto o estar
fuera de servicio), lanza una excepcin [Link].
En el caso de que se devuelva algn objeto como valor de retorno, el esqueleto lo
enva (serializado) al adaptador, que se encarga de deserializarlo. La situacin se
representa en la siguiente figura.
Figura 96. Tras una llamada remota hay muchos subprocesos
mtodo A
mtodo C
Proceso servidor
Proceso cliente
llamada
referencia
Objeto cliente
Objeto servidor
UNA LLAMADA REMOTA EN RMI (1)
Red fsica
Miguel ngel Abin, Mayo 2004
TCP/IP
010010101001
skeleton
stub
Serializacin
Deserializacin
Nota: En los URL especificados en la propiedad j ava. r mi . ser ver . codebase
tambin puede usarse f t p o f i l e en lugar de ht t p. Si esta propiedad especifica
un directorio debe incluirse la barra / al final del URL; si especifica un archivo, no.
[Link]
Miguel ngel Abin, Julio 2004 - 199/313 -
Para saber qu argumentos y valores de retorno puede admitir un mtodo remoto,
se debe conocer cmo se transmiten los distintos tipos de objetos en las llamadas
remotas (en Java, un objeto remoto debe implementar obligatoriamente la interfaz
[Link], que se ver ms adelante):
Los tipos de datos primitivos (shor t , i nt , doubl e, char ...) y los
objetos predefinidos en Java cuyas clases implementan la interfaz
[Link] (St r i ng, etc.) se pasan por valor. Esto es,
se copian del espacio de direcciones de una MVJ al de otra. Lo mismo
vale para los valores de retorno del mtodo remoto.
Los objetos no remotos cuyas clases implementan la interfaz
[Link] se pasan tambin por valor (lo mismo
aplica a los valores de retorno).
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.
Los objetos que no son remotos ni serializables (es decir, que no
implementan las respectivas interfaces) no pueden enviarse a un
objeto remoto ni tampoco ser devueltos por l: la MVJ lanzar una
excepcin.
Con respecto a los objetos que son a la vez remotos y serializables
(esto es, que implementan las respectivas interfaces), albergo algunas
dudas. Por un lado, he comprobado (en el JDK 1.2 y en el 1.4.2) que
estos objetos son admitidos por el compilador y que no arrojan
excepciones en tiempo de ejecucin. Sin embargo, recomiendo no
utilizarlos, pues me parece una posibilidad bastante confusa y que no
aporta ninguna ventaja. Desconozco el mecanismo interno por el cual
se transmiten las llamadas remotas cuando tienen argumentos de este
tipo, aunque supongo que coincidir con el que se usa para los
adaptadores. Agradecer cualquier sugerencia al respecto.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 200/313 -
Figura 97. El paso de argumentos en una MVJ
Figura 98. Argumentos que se pasan por valor en una llamada remota
public int suma (int a,
int b) {
return (a + b);
}
suma(2, 5);
2 y 5 se pasan por
valor
Empleado empleado = new Empleado(...)
subirSueldo (empleado, 37,67)
La referencia empleado
a un objeto Empleado se
pasa por valor
MVJ
PASO DE ARGUMENTOS EN UNA NICA MVJ
Miguel ngel Abin, Mayo 2004
Miguel ngel Abin, Mayo 2004
suma(2, 5);
2 y 5 se pasan por
valor
MVJ local
PASO POR VALOR Y POR REFERENCIA EN UNA
APLICACIN RMI (1)
Plantilla plantilla
= new Plantilla();
MVJ remota
Empleado empleado
= new Empleado();
subirSueldo(empleado);
empleado se pasa por
valor: se copia en la
MVJ remota usando
la serializacin de
objetos
Objeto local
Objeto remoto
plantilla
[Link]
Miguel ngel Abin, Julio 2004 - 201/313 -
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 guar dar Empl eado( Empl eado empl eado) un adaptador del
objeto empl eado en lugar de una copia de empl eado. El objeto remoto al cual va
dirigida la llamada podra necesitar informacin sobre la instancia empl eado: edad,
sueldo, tipo de contrato, etc. Necesitara, pues, consultar al objeto cliente y llamar a
mtodos como get Edad( ) , get Suel do( ) , 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.
Miguel ngel Abin, Mayo 2004
MVJ local
PASO POR VALOR Y POR REFERENCIA EN UNA
APLICACIN RMI (2)
Comprador comp
= new Comprador();
producto:getProducto()
GestorCompra gestorCompra
= new GestorCompra()
gestorCompra
producto
CarroCompra carro = new
CarroCompra()
carro
comp
AadirProducto(producto)
MVJ remota
MVJ remota
Objeto local
Objetos
remotos
Objeto
remoto
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 202/313 -
La copia por valor se realiza mediante la serializacin de objetos de Java, vista en
el apartado dedicado al paquete [Link] 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 [Link], 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
pr ot ect ed Obj ect r epl aceObj ect ( Obj ect obj et o) t hr ows I OExcept i on
de la clase [Link].
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.
[Link]
Miguel ngel Abin, Julio 2004 - 203/313 -
5.2.2. La arquitectura RMI
Simplificando un poco, puede decirse que la RMI presenta una arquitectura de tres
capas, representada en la figura 100.
a) La capa adaptador-esqueleto (stub-skeleton) dota a unos y a otros de
una interfaz comn.
b) La capa remota o RMI. Se encarga de controlar la creacin y gestin de
las referencias a objetos remotos (mantiene una tabla de objetos
distribuidos), y de convertir las llamadas remotas en peticiones a la capa
de transporte. Para ello utiliza un protocolo independiente de los
adaptadores y esqueletos, as como de la plataforma donde se ejecuta
la MVJ. En el JDK 1.1 y 1.2, RMI usaba el protocolo JRMP (Java
Remote Method Protocol: protocolo de mtodos remotos de Java).
JRMP slo se usa con Java y no coincide con el protocolo equivalente
que usa CORBA (IIOP: Internet Inter-ORB Protocol). Con el JDK 1.3 se
aadi la posibilidad de trabajar tambin con IIOP, lo cual ha abierto
nuevos horizontes a Java: ahora se puede acceder a los objetos
remotos RMI (escritos en Java) desde clientes CORBA escritos en otros
lenguajes (C/C++, Ada, etc.), y viceversa.
Las peticiones RMI, descritas segn establece el protocolo JRMP,
suelen ser bloqueadas por los cortafuegos, ya que se usan puertos
aleatorios que pueden tener restricciones de seguridad. Cuando se
trabaja con cortafuegos, RMI encapsula automticamente las llamadas
RMI dentro de peticiones POST del protocolo HTTP (esta tcnica se
conoce como HTTP tunneling o pasarela HTTP). Esta encapsulacin
empeora el rendimiento de las aplicaciones RMI, pero muchas veces
resulta inevitable.
c) La capa de transporte es la capa de transporte del conjunto de
protocolos TCP/IP, ya vista en el apartado 2. Por defecto, RMI usa el
protocolo de transporte TCP, pero admite otros.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 204/313 -
Figura 100. Esquema parcial de la arquitectura RMI
Figura 101. Esquema completo de la arquitectura RMI
Capa de los objetos
clientes
Capa de los
adaptadores (stubs)
Capa de referencia
remota (RMI)
Capa de transporte
Capa de red
Capa de enlace
Capa de los objetos
clientes
Capa de los
esqueletos (skeletons)
Capa de referencia
remota (RMI)
Capa de transporte
Capa de red
Capa de enlace
Red fsica
Comunicacin virtual
Comunicacin real Miguel ngel Abin, Mayo 2004
ARQUITECTURA COMPLETA DE LA RMI DE JAVA
ARQUITECTURA SIMPLIFICADA DE
LA RMI DE JAVA
Objeto cliente
Objeto Objeto cliente cliente
Objeto servidor
Objeto servidor Objeto servidor
Stub (adaptador)
Stub Stub ( (adaptador adaptador) )
Skeleton (esqueleto)
Skeleton Skeleton ( (esqueleto esqueleto) )
CAPA REMOTA O RMI
CAPA REMOTA O RMI CAPA REMOTA O RMI
CAPA DE TRANSPORTE
CAPA DE TRANSPORTE CAPA DE TRANSPORTE
MVJ LOCAL
MVJ REMOTA
Miguel ngel Abin, Mayo 2004
[Link]
Miguel ngel Abin, Julio 2004 - 205/313 -
5.2.3. El servicio de registro remoto RMI
La nica pieza que falta para completar el puzzle de las comunicaciones con RMI
se obtiene de contestar a esta pregunta: cmo pueden los clientes encontrar los
servicios? Pues mediante un servicio de nombres y directorios. En el apartado 2 ya
vimos uno: el DNS (Domain Name Service: servicio de nombres de dominio), que
asigna nombres de mquina a las direcciones IP. Un sistema de nombres es un
mecanismo para asociar nombres con objetos o dispositivos de una red, que
proporciona un medio de encontrar un objeto o dispositivo a partir de un nombre dado.
El proceso de bsqueda de un objeto a partir de un nombre se llama resolucin. En un
sistema de nombres y directorios, un nombre de fichero por ejemplo est asociado
con una referencia que las aplicaciones pueden usar para acceder al archivo. Todo
servicio de nombres y directorios viene a ser equivalente a un listn telefnico; pero, en
vez de asociar nmeros de telfono con direcciones y nombres de personas, asocia
nombres lgicos con objetos o componentes de una red.
Por diseo, RMI puede usar como servicio de nombres y directorios la JNDI (Java
Naming and Directory Interface: interfaz de nombres y directorios de Java) o su propio
servicio: el servicio de registro remoto de la RMI o servicio de registro de objetos
remotos de la RMI de Java (por brevedad, usar simplemente servicio de registro RMI).
La JNDI ofrece muchas ms posibilidades que el servicio de registro RMI, pero tambin
es de manejo mucho ms complicado, amn de exigir el estudio de una nueva API.
Aqu se usar solamente el servicio de registro RMI, que se implementa mediante la
aplicacin de servidor r mi r egi st r y, incluida en el directorio bi n de los JDK.
El servidor de registro RMI (r mi r egi st r y) debe estar en ejecucin antes de que
lo estn los objetos que acten como clientes y servidores en una aplicacin RMI. Sin
l, los clientes no pueden localizar los servicios remotos buscados (los mtodos
ofrecidos por los servidores) ni los servidores pueden atenderlos. Asimismo, si en una
aplicacin RMI falla el registro remoto, no podr funcionar. A diferencia de la JNDI, el
registro remoto de RMI no admite persistencia: cuando la aplicacin acaba, se pierden
para siempre los vnculos entre objetos remotos y nombres lgicos.
Cuando se ejecuta r mi r egi st r y en el anfitrin donde reside el objeto remoto
(servidor), se lanza un proceso que utiliza por defecto el puerto TCP 1099. En el caso
de que no se pueda usar el protocolo TCP (por el uso de cortafuegos, por ejemplo),
RMI es compatible tambin con protocolos de transporte como SSL y UDP. Para que
los clientes puedan acceder remotamente a un servidor, ste debe antes ser registrado
en el servicio de registro RMI (lo cual implica asociarlo con un nombre lgico). Registrar
un objeto remoto no es ms que asociarle un nombre, de manera que el nombre
asignado pueda usarse ms tarde para buscarlo y acceder a sus servicios. Un cliente
que llame a un mtodo remoto de un servidor buscar a ste por el nombre que se le
diera al registrarse, obtendr una referencia remota a l (un adaptador o stub) y, luego,
llamar a sus mtodos. La idea clave del servicio de registro RMI radica en
proporcionar a los clientes referencias a objetos que residen en distintos anfitriones (o
quizs en otras MVJ que se ejecutan en la misma mquina).
Personalmente, me resulta til la idea de imaginarme el servidor de registro
remoto como una centralita donde hubiera una persona con un listn de dos columnas:
una para los nombres y otra para los adaptadores. Cuando se recibiera una peticin
referida a un nombre (l ui s. aument ar Sal ar i o( ) , [Link].), la persona buscara el
nombre (l ui s) en el listn, mirara cul es el adaptador asociado y lo enviara al cliente.
El adaptador contiene toda la informacin necesaria para conducir las llamadas hasta
el objeto remoto asociado.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 206/313 -
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):
1) Se ejecuta el servidor de registro RMI en la mquina remota (debe estar
en ejecucin antes de que se ejecuten los dems objetos), el cual
permanece a la espera de peticiones por el puerto TCP 1099 (puerto por
defecto). Para ello se crea un socket de servidor que permanece a la
espera de peticiones.
2) Se crea el objeto remoto, se exporta (esto es, se deja preparado para
que escuche llamadas a sus mtodos por un determinado puerto del
anfitrin remoto o por un puerto annimo) y se registra en el servicio de
registro RMI con un nombre (pueden crearse varios, pero al menos uno
debe registrarse). Al registrarse, se crea en la mquina remota una
instancia de la clase esqueleto. La escucha de peticiones se hace
mediante un socket de servidor asociado al puerto por el cual se ha
exportado.
3) Se crea el objeto local, que llama a un mtodo de la interfaz remota del
objeto remoto, usando el nombre con que se registr este ltimo.
Objeto adaptador
(stub)
Objeto esqueleto
(skeleton)
Servidor de registro remoto
Objeto cliente Objeto servidor
UNA LLAMADA REMOTA EN RMI (2)
Comunicacin virtual
Comunicacin real
MVJ local MVJ remota
Queda
registrado
con un
nombre
Red
Miguel ngel Abin, Mayo 2004
[Link]
Miguel ngel Abin, Julio 2004 - 207/313 -
4) El servidor de registro RMI enva a la MVJ local una referencia remota al
objeto remoto (una instancia de la clase adaptadora o stub del objeto
remoto), pero no el objeto remoto. Realmente, el servidor de registro
RMI enva un flujo de bytes serializado en el que est codificado el
adaptador; el cliente, al deserializarlo, crea la instancia del adaptador. El
adaptador contiene la direccin IP del anfitrin donde est el objeto
remoto al que hace referencia, el nmero del puerto que usa ste para
escuchar llamadas a sus mtodos y un identificador nico del objeto.
5) El adaptador abre un flujo de salida, serializa los argumentos (si son
objetos remotos exportados, serializa sus adaptadores, no los
verdaderos objetos), enva a la capa remota o RMI una peticin de
conexin y delega en ella la llamada.
6) La capa remota informa a la capa de transporte de que necesita iniciar
una conexin y le enva el flujo de salida.
7) La capa de transporte crea un socket de cliente y por l enva el flujo de
salida.
8) La llamada recorre las capas por debajo de la de transporte y se
transmite a la MVJ remota a travs de la red.
9) La llamada recorre las capas TCP/IP del anfitrin remoto y llega a la
capa de transporte. All, el socket de servidor asociado al objeto remoto
lee el flujo entrante y lo transmite a la capa remota.
10) La capa remota pasa la llamada al esqueleto.
11) El esqueleto abre un flujo de entrada, deserializa los objetos incluidos en
el flujo entrante y enva la llamada al objeto remoto.
12) El objeto remoto ejecuta el mtodo llamado, con los argumentos que se
le proporcionan y, si corresponde, devuelve un valor al objeto esqueleto
o una excepcin.
13) El esqueleto enva a la capa remota una peticin de conexin y delega
en ella el envo del valor de retorno.
14) La capa remota se encarga de abrir un flujo de salida, de serializar el
valor de retorno (si es un objeto remoto exportado, serializa su
adaptador) y de enviar el flujo a la capa de transporte, adems de
informar a esta ltima de que necesita iniciar una conexin.
15) La capa de transporte del anfitrin remoto abre un socket de cliente y lo
usa para enviar el valor de retorno al anfitrin local.
16) El valor devuelto recorre las capas TCP/IP del anfitrin remoto, pasa por
la red y llega a la capa de transporte del anfitrin que desencaden el
proceso. All, un socket de servidor lee el flujo entrante y lo transmite a
la capa remota.
17) La capa remota abre un flujo de entrada, deserializa el valor de retorno
incluido en el flujo entrante y lo enva al adaptador.
18) El adaptador o stub enva este valor al objeto local.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 208/313 -
Figura 103. Procesos que subyacen bajo una llamada remota con RMI
En la figura anterior se esquematizan algunos de los pasos, no todos, por razones
de espacio.
Como puede ver el lector, se ha recorrido un largo camino para llegar hasta aqu.
Arquitecturas de comunicaciones, capas, protocolos, sockets, serializacin de objetos:
todos estos conceptos han sido necesarios para entender cmo funciona la RMI de
Java. En el apartado 6, usaremos estas ideas para avanzar un poco ms en la
comprensin de los sistemas de objetos distribuidos.
Objecto
remoto
Anfitrin servidor
Servidor de registro remoto
Socket
Servidor
Puerto TCP 1099
Anfitrin servidor
Se registra en el servicio de registro
remoto con un nombre: miObjeto, por
ejemplo. A partir de entonces, todas las
peticiones a un objeto con ese nombre
se dirigirn al objeto remoto que
escucha por el puerto X
Objecto
cliente
Anfitrin cliente
Se llama al registro
para localizar el
objeto miObjeto
miObjeto_Stub
Se
devuelve un
stub
1
3
4
Miguel ngel Abin, Mayo 2004
ESQUEMA DE LAS COMUNICACIONES CON RMI
Se exporta el objeto; a
partir de entonces
escuchar peticiones
por un puerto X
Se enva la llamada al stub
Puerto X
Socket
Cliente
6
7
El stub enva la llamada
al skeleton
miObjeto_Skeleton
Se crea el objeto skeleton
2
5
Socket
Servidor
8
El skeleton
enva la
llamada al
obj. remoto
[Link]
Miguel ngel Abin, Julio 2004 - 209/313 -
5.3. Recorrido rpido por el paquete [Link]
La API RMI se implementa mediante las clases pertenecientes a estos paquetes:
[Link]
[Link]
[Link]
[Link]
[Link]
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.
[Link]
El paquete [Link] proporciona la interfaz Remot e y las clases
Mar shal l edObj ect , Nami ng y RMI Secur i t yManager , as como unas cuantas
excepciones.
La interfaz Remot e carece de mtodos. Toda clase remota debe implementarla;
en caso contrario, Java no la considera como tal.
La clase Mar shal l edObj ect 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 Nami ng incluye mtodos para obtener y almacenar referencias a objetos
remotos mediante el URL de la RMI. Los mtodos ms usados son
publ i c st at i c voi d bi nd( St r i ng nombr e,
Remot e obj et o) t hr ows Al r eadyBoundExcept i on,
Mal f or medURLExcept i on, Remot eExcept i onBi nds
publ i c st at i c voi d r ebi nd( St r i ng nombr e, Remot e
obj et o) t hr ows Remot eExcept i on, Mal f or medURLExcept i on
publ i c st at i c Remot e l ookup( St r i ng nombr e) t hr ows
Not BoundExcept i on, Mal f or medURLExcept i on,
Remot eExcept i on.
El mtodo bi nd( ) 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 nombr e de los mtodos de Nami ng deben ser St r i ngs con la forma
de los URL de la RMI.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 210/313 -
El URL de un objeto remoto registrado tiene este formato:
r mi : / / anf i t r i on: puer t o/ nombr eobj et or emot o
Por ejemplo:
r mi : / / www. uv. es: 9000/ Li st aNot as
En el caso de que el URL incluya un protocolo que no sea r mi , se obtendr una
excepcin [Link]. 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 r mi r egi st r y
de la RMI. Una llamada tpica a bi nd( ) tiene esta forma:
Mi Cl ase i nst anci a = new Mi Cl ase( . . . ) ;
Nami ng. bi nd( r mi : / / anf i t r i on: puer t o/ di r ect or i o, i nst anci a) ;
Dicho cdigo registra una instancia de Mi cl ase con el nombre i nst anci a en un
URL.
Para el ejemplo de Cal cMat del subapartado 4.1, el registro, que se hace en el
servidor, podra tomar esta forma:
Cal cMat I mp cal cul o = new Cal cMat I mp( ) ;
Nami ng. bi nd( r mi : / / www. uv. es: 9000/ Cent r oCal cul o, cal cul o) ;
El mtodo r ebi nd( ) funciona como bi nd( ) , pero permite volver a asociar un
nombre a un objeto remoto, reemplazando al que ya tena. Si se intenta registrar con
bi nd( ) un objeto ya registrado, se lanzar una excepcin
[Link].
El mtodo l ookup( ) devuelve una referencia al objeto remoto especificado en el
URL introducido en su argumento nombr e. 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 l ookup( ) tiene la forma
Nami ng. l ookup( r mi : / / anf i t r i on: puer t o/ nombr eobj et or emot o) ;
Para buscar la instancia cal cul o de Cal cMat registrada pocas lneas ms
arriba, debera escribirse en el cliente
Nami ng. l ookup( r mi : / / www. uv. es: 9000/ Cent r oCal cul o/cal cul o) ;
Protocolo Anfitrin del
objeto remoto
Nombre con el que se
ha registrado el objeto
remoto
[Link]
Miguel ngel Abin, Julio 2004 - 211/313 -
Como l ookup( ) devuelve un objeto genrico del tipo de la interfaz
[Link], se hace necesaria la conversin
Cal cMat mi Cal cul o = ( Cal cMat )
Nami ng. l ookup( r mi : / / www. uv. es: 9000/ Cent r oCal cul o/cal cul o) ;
para poder usarlo. He aqu un ejemplo de uso:
mi Cal cul o. hacer Cal cul oMuyCompl i cado( 2. 5656, 3. 141592653589) ;
La clase RMI Secur i t yManager proporciona un controlador de seguridad para
las aplicaciones que usan cdigo procedente de descargas. Si no se ha establecido un
RMI Secur i t yManager , el cargador de clases de RMI no permitir descargar ninguna
clase remota desde un anfitrin que no sea el local; esto no es vlido para los applets,
que usan otro controlador de seguridad.
[Link]
El paquete [Link] proporciona las interfaces Regi st r y y
Regi st r yHandl er , as como la clase Locat eRegi st r y.
La interfaz Regi st r y define los mtodos bi nd( ) , l ookup( ) , r ebi nd( ) ,
unbi nd( ) y l i st ( ) de la clase Nami ng, y define la constante publ i c st at i c
f i nal i nt REGI STRY_PORT, correspondiente al puerto TCP que se usa para
registrar objetos.
La interfaz Regi st r yHandl er figura en la documentacin de Sun como
deprecated (censurada o desaprobada) desde la versin 1.2 del JDK y no debe
utilizarse.
La clase Locat eRegi st r y se usa para recuperar objetos Regi st r y de un par
anfitrin-puerto o para crear objetos Regi st r y a partir de un nmero de puerto o de
puertos y de factoras de sockets RMI. Los mtodos get Regi st r y( ) se encargan de
recuperar los objetos Regi st r y; y los mtodos cr eat eRegi st r y( ) 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.
[Link]
Este paquete proporciona clases (Obj I D, Remot eObj ect , Remot eSer ver ,
Remot eSt ub, RMI Cl assLoader , RMI Cl assLoader Spi , RMI Socket Fact or y, UI D
y Uni cast Remot eObj ect ) e interfaces (Remot eRef , RMI Cl i ent Socket Fact or y,
RMI Fai l ur eHandl er , RMI Ser ver Socket Fact or y, Ser ver Ref y Unr ef er enced),
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).
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 212/313 -
La clase Obj I D genera identificadores de objetos que los anfitriones declaran
como remotos. Proporciona mtodos para crear identificadores y para leerlos de flujos
de bytes o escribirlos en stos. Vimos en el apartado anterior que las referencias
remotas contienen nmeros nicos que identifican a los objetos remotos referenciados.
Pues bien, est clase genera esos nmeros.
La clase Remot eObj ect implementa, para objetos remotos, el comportamiento
de [Link] (superclase de todos las clases de Java; cuando se dice que
la clase X hereda de Y, se sobreentiende que hereda de Y y de [Link]),
amn de implementar la interfaz [Link]. Por tanto, implementa los
mtodos hashCode( ) , equal s( ) y t oSt r i ng( ) .
La clase Remot eSer ver es subclase de Remot eObj ect . Constituye la
superclase comn para todas las implementaciones de objetos remotos. Su mtodo
st at i c St r i ng get Cl i ent Host ( ) devuelve el identificador del anfitrin que est
ejecutando la invocacin remota de mtodos.
La clase Remot eSt ub tambin es subclase de Remot eObj ect . Esta clase
abstracta es la superclase comn para los stubs de los clientes.
La clase RMI Cl assLoader incluye mtodos estticos para permitir la carga
dinmica de clases remotas. Si un cliente o servidor de una aplicacin RMI necesita
cargar una clase desde un lugar remoto, llama a RMI Cl assLoader para que lo haga.
RMI Cl assLoader Spi implementa algunos de los mtodos de la anterior.
La clase RMI Socket Fact or y es usada por RMI para obtener sockets de cliente y
de servidor para las llamadas RMI.
La clase Uni cast Remot eObj ect es subclase de Remot eSer ver e incluye la
implementacin por defecto de los objetos remotos. Con ella se puede llamar a los
mtodos remotos mediante conexiones TCP ligadas por defecto al puerto 1099. Por lo
general, cuando se necesitan objetos que tengan un comportamiento remoto ms
especializado, se crean heredando de Uni cast Remot eObj ect . Tambin podran
heredar directamente de Remot eObj ect ; pero entonces deberan implementarse los
mtodos hashCode( ) , equal s( ) y t oSt r i ng( ) , heredados de
[Link].
Cuando una clase hereda de Uni cast Remot eObj ect , debe incluir un
constructor que declare que puede arrojar excepciones del tipo Remot eExcept i on. El
constructor, al llamar a super ( ) , activa el cdigo de Uni cast Remot eObj ect
encargado de enlazar el objeto con la infraestructura de la RMI e inicializa el objeto
remoto. Enlazar un objeto con la infraestructura de la RMI es lo mismo que exportarlo,
esto es, dejarlo disponible para que acepte peticiones remotas por un puerto.
En el caso de que se usen objetos remotos que no sean instancias de una
subclase de Uni cast Remot eObj ect , se deber codificar explcitamente la
exportacin mediante Uni cast Remot eObj ect . expor t Obj ect ( Remot e obj et o) o
Uni cast Remot eObj ect . expor t Obj ect ( Remot e obj et o, i nt numpuer t o) . El
primero exporta obj et o de modo que permanezca a la escucha de peticiones por un
puerto annimo, establecido por la RMI; y el segundo lo exporta para que escuche por
un puerto establecido por el programador.
[Link]
Miguel ngel Abin, Julio 2004 - 213/313 -
La interfaz Remot eRef es usada por los objetos Remot eSt ub para referirse a
objetos remotos. Incluye mtodos para llamar a mtodos de objetos remotos, para
comparar objetos remotos y para trabajar con aquellos objetos que implementan la
interfaz Remot eCal l .
La interfaz RMI Cl i ent Socket Fact or y es usada por RMI para obtener sockets
de cliente para las llamadas RMI.
Su nico mtodo es publ i c Socket Socket cr eat eSocket ( St r i ng
anf i t r i on, i nt puer t o) t hr ows I OExcept i on, que crea un socket de cliente
asociado al par anfitrin-puerto especificado.
La interfaz RMI Fai l ur eHandl er especifica los mtodos que se encargan de
manejar los fallos derivados de los intentos de crear Ser ver Socket s.
La interfaz RMI Ser ver Socket Fact or y es usada por RMI para obtener sockets
de servidor para las llamadas RMI.
Su nico mtodo es publ i c Ser ver Socket cr eat eSer ver Socket ( i nt
puer t o) t hr ows I OExcept i on, que crea un socket de servidor para el puerto
especificado.
La interfaz Ser ver Ref extiende la interfaz Remot eRef y es implementada por los
objetos remotos para poder acceder a sus objetos Remot eSt ub.
La interfaz Unr ef er enced se usa para que los objetos remotos puedan recibir
mensajes de aviso cuando no existan ms clientes que mantengan referencias a un
objeto remoto.
[Link]
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.
[Link]
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.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 214/313 -
Figura 104. Algunas clases e interfaces del paquete [Link]
ALGUNAS CLASES E INTERFACES DE [Link]
Remote
RemoteServer
RemoteObject
UnicastRemoteObject
Object
hashCode
equals
Implementacin de
la interfaz remota
RemoteStub
Skeleton del servidor
Una clase stub implementa los
mtodos de la interfaz remota del
cliente, al igual que lo hace la
implementacin de esa interfaz que
reside en el lado del servidor.
Stub del cliente
Interfaz remota del cliente
implements
extends
M
i
g
u
e
l
n
g
e
l
A
b
i
n
J
u
l
i
o
2
0
0
4
[Link]
Miguel ngel Abin, Julio 2004 - 215/313 -
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 . cl ass de la aplicacin
se encuentran en una misma mquina. En el siguiente subapartado dar las directrices
para distribuir los . cl ass cuando clientes y servidores residen en anfitriones distintos.
La secuencia de pasos para desarrollar una aplicacin con RMI se representa en
la siguiente figura.
Figura 105. Secuencia general de pasos para programar aplicaciones RMI
Pasos para programar con RMI
Se escribe la
interfaz remota
Se implementa la
interfaz remota Se generan archivos
.class para la
interfaz remota y
para la clase que
implementa la
interfaz remota
a)
b)
c)
d)
javac ...
rmic ...
Se genera el archivo .class del
esqueleto
Se inicia el servicio de registro
de RMI (rmiregistry)
Se inicia un objeto servidor y
se registra en rmiregistry
Se genera el fichero .class del
adaptador (stub)
Se escribe la clase cliente
javac ...
Se inicia un objeto cliente
e)
f)
g)
h)
i)
Se genera el .class
de la clase cliente
Anfitrin servidor
Anfitrin cliente
Miguel ngel Abin, Mayo 2004
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 RMI 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).
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 216/313 -
Paso a) En primer lugar, se escribe la interfaz remota del servidor. Toda interfaz
remota debe declararse como publ i c y debe extender la interfaz [Link],
incluida en el paquete [Link]. 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
[Link] o declararla con t hr ows.
/**
* Definicin de la interfaz CalculoVectorial, que se usar
* para permitir calcular la norma de vectores 3D y sus vectores unitarios.
*/
import [Link].*;
// Necesariamente, la interfaz debe extender la interfaz [Link]
public interface CalculoVectorial extends [Link] {
// Devuelve el mdulo del vector
double getModulo (double x, double y, double z) throws [Link];
// Devuelve la primera coordenada del vector unitario asociado al vector
double getUnitarioX (double x, double y, double z) throws [Link];
// Devuelve la segunda coordenada del vector unitario asociado al vector
double getUnitarioY (double x, double y, double z) throws [Link];
// Devuelve la tercera componente del vector unitario asociado al vector
double getUnitarioZ (double x, double y, double z) throws [Link];
}
Paso b) Se implementa la interfaz remota. La clase remota que la implementa
debe heredar de la clase Remot eSer ver . Tal como ya se dijo, lo habitual es hacer que
herede de la clase Uni cast Remot eObj ect del paquete [Link]. Si no se
hiciera as, habra que exportar explcitamente los objetos remotos antes de registrarlos
mediante
Uni cast Remot eObj ect . expor t Obj ect ( obj et or emot o) ;
/**
* Implementacin de la interfaz CalculoVectorial.
* Esta clase hereda de UnicastRemoteObject
* (que es el modo ms simple para crear clases disponibles
* para llamadas remotas).
*/
Ejemplo 17a: [Link]
Ejemplo 17b: [Link]
[Link]
Miguel ngel Abin, Julio 2004 - 217/313 -
import [Link].*;
import [Link].*;
import [Link].*;
/** 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.
[Link]("rmi://localhost/CalculosVector", this);
}
catch (AccessException e1) {
[Link]("Se rechaz el acceso. Su sistema no tiene los permisos " +
" necesarios para realizar la operacin remota." );
[Link](-1);
}
catch ([Link] e2) {
[Link]("La URL para el registro no es vlida.");
[Link](-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 ([Link](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
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 218/313 -
* 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 Y como un double.
*/
private double calcularUY (double x, double y, double z) {
return (y/calcularModulo(x, y, z));
}
/** calcularUZ es un mtodo no remoto y privado que calcula la coordenada Z 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 Z como un double.
*/
private double calcularUZ (double x, double y, double z) {
return (z/calcularModulo(x, y, z));
}
/** getModulo es un mtodo remoto accesor de calcularModulo().
* @param x,y,z son las tres coordenadas (en formato double) del vector.
* @return devuelve la coordenada Z como un double.
*/
public double getModulo (double x, double y, double z) throws RemoteException {
return calcularModulo(x, y, z);
}
/** getUnitarioX es un mtodo remoto accesor de calcularUX.
* @param x,y,z son las tres coordenadas (en formato double) del vector.
* @return devuelve la coordenada X como un double.
*/
public double getUnitarioX (double x, double y, double z) throws RemoteException {
return calcularUX(x, y, z);
}
/** getUnitarioY es un mtodo remoto accesor de calcularUY.
* @param x,y,z son las tres coordenadas (en formato double) del vector.
* @return devuelve la coordenada Y como un double.
*/
public double getUnitarioY (double x, double y, double z) throws RemoteException {
return calcularUY(x, y, z);
}
/** getUnitarioZ es un mtodo remoto accesor de calcularUZ.
* @param x,y,z son las tres coordenadas (en formato double) del vector.
* @return devuelve la coordenada Z como un double.
*/
public double getUnitarioZ (double x, double y, double z) throws RemoteException {
return calcularUZ(x, y, z);
}
}
[Link]
Miguel ngel Abin, Julio 2004 - 219/313 -
Paso c) Se compilan la interfaz remota y la clase que la implementa. En nuestro
caso, tendremos como resultado dos archivos: Cal cul oVect or i al . cl ass y
Cal cul oVect or i al I mp. cl ass.
Paso d) Se generan los archivos . cl ass stub y skeleton a partir de la clase que
implementa la interfaz remota (Cal cul oVect or i al I mp). Para ello se utiliza el
compilador RMI r mi c, sito en el subdirectorio bi n del directorio donde se haya
instalado el JDK. Para ejecutar r mi c se puede escribir
r mi c nombr ecl ase
y se generarn los archivos stub y skeleton en el directorio actual. Si se usa
r mi c d di r ect or i o nombr ecl ase
los archivos se guardaran en el directorio especificado. A continuacin pongo dos
ejemplos, uno para Windows y otro para UNIX:
> r mi c d C: \ j ava\ RMI \ cl ases Cal cul oVect or i al (Windows)
%r mi c d / usr / l ocal / RMI / cl ases Cal cul oVect or i al (UNIX)
Para este ejemplo, he obtado por colocar todos los archivos . j ava y . cl ass del
ejemplo en el directorio bi n del JDK. Me parece la mejor opcin para que el lector o
lectora siga los pasos, pues as no tengo que despistarle configurando el CLASSPATH
con directorios que slo funcionarn en mi mquina, mejor dicho, en una que tenga la
misma estructura de directorios que la ma. Desde luego, lo normal al desarrollar una
aplicacin (con RMI o sin ella) es configurar adecuadamente el CLASSPATH o usar la
propiedad classpath (o cp) al compilar, no colocar todos los archivos en el
directorio bi n; si no lo hago as en este texto es por claridad expositiva. Recomiendo
usar dos directorios diferentes (con los subdirectorios que sean precisos): uno para los
archivos del cliente y otro para los del servidor.
Si no se desea el archivo esqueleto (Java ya no necesita esqueletos desde la
versin 1.2), basta con compilar as:
r mi c v1. 2 nombr ecl ase
Advertencia: La clase que se va a compilar con r mi c debe
estar en el directorio donde est r mi c, debe figurar en el
CLASSPATH local o debe definirse su ubicacin con la opcin
cl asspat h del compilador. En caso contrario, el compilador
no la encontrar.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 220/313 -
Teniendo en cuenta lo dicho, aqu est la captura de pantalla correspondiente a la
compilacin RMI de Cal cul oVect or i al I mp.
Figura 106. Resultado de compilar con rmic CalculoVectorialImp
Nota: Como ya avanc, el JDK 1.5 (ahora JDK 5.0) permite la
generacin dinmica de los ficheros stub (los skeleton ya no son
necesarios); se vuelve innecesaria, pues, la compilacin manual
con r mi c. Si no hago uso de esta cmoda propiedad es por
compatibilidad con las versiones anteriores, que son las
predominantes en el mercado.
Nota: Si se desea generar adaptadores y esqueletos que usen el
protocolo IIOP en lugar de JRMP, hay que usar r mi c i i op. Esta
opcin permite construir aplicaciones RMI capaces de interoperar
con objetos CORBA. El proceso exacto se explicar en el
subapartado 6.5.
[Link]
Miguel ngel Abin, Julio 2004 - 221/313 -
Como vemos, la aplicacin r mi c genera dos archivos . cl ass:
Cal cul oVect or i al I mp_Skel . cl ass y Cal cul oVect or i al I mp_St ub. cl ass.
Tal como indiqu en la pgina 219, mantendr Cal cul oVect or i al . cl ass,
Cal cul oVect or i al I mp. cl ass, Cal cul oVect or i al I mp_Skel . cl ass,
Cal cul oVect or i al I mp_St ub. cl ass en un mismo directorio: el bi n del JDK.
Por defecto, r mi c no genera los archivos . j ava correspondientes a las clases
stub y skeleton; pero pueden obtenerse mediante las opciones keep y
keepgener at ed de r mi c.
ste es el cdigo de la clase Cal cul oVect or i al I mp_St ub, generado
automticamente por la RMI de Java:
// Stub class generated by rmic, do not edit.
// Contents subject to change without notice.
public final class CalculoVectorialImp_Stub
extends [Link]
implements CalculoVectorial, [Link]
{
private static final [Link][] operations = {
new [Link]("double getModulo(double, double, double)"),
new [Link]("double getUnitarioX(double, double, double)"),
new [Link]("double getUnitarioY(double, double, double)"),
new [Link]("double getUnitarioZ(double, double, double)")
};
private static final long interfaceHash = -8424770855087595345L;
private static final long serialVersionUID = 2;
private static boolean useNewInvoke;
private static [Link] $method_getModulo_0;
private static [Link] $method_getUnitarioX_1;
private static [Link] $method_getUnitarioY_2;
private static [Link] $method_getUnitarioZ_3;
static {
try {
[Link]("invoke",
new [Link][] {
[Link],
[Link],
[Link][].class,
[Link]
});
useNewInvoke = true;
$method_getModulo_0 = [Link]("getModulo", new
[Link][] {[Link], [Link], [Link]});
Advertencia: Si se editan los archivos . j ava asociados a
adaptadores y esqueletos, no deben modificarse. En general,
nunca es necesario utilizarlos.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 222/313 -
$method_getUnitarioX_1 = [Link]("getUnitarioX", new
[Link][] {[Link], [Link], [Link]});
$method_getUnitarioY_2 = [Link]("getUnitarioY", new
[Link][] {[Link], [Link], [Link]});
$method_getUnitarioZ_3 = [Link]("getUnitarioZ", new
[Link][] {[Link], [Link], [Link]});
} catch ([Link] e) {
useNewInvoke = false;
}
}
// constructors
public CalculoVectorialImp_Stub() {
super();
}
public CalculoVectorialImp_Stub([Link] ref) {
super(ref);
}
// methods from remote interfaces
// implementation of getModulo(double, double, double)
public double getModulo(double $param_double_1, double $param_double_2, double
$param_double_3)
throws [Link]
{
try {
if (useNewInvoke) {
Object $result = [Link](this, $method_getModulo_0, new [Link][]
{new [Link]($param_double_1), new [Link]($param_double_2), new
[Link]($param_double_3)}, -1906106596166222523L);
return (([Link]) $result).doubleValue();
} else {
[Link] call = [Link](([Link])
this, operations, 0, interfaceHash);
try {
[Link] out = [Link]();
[Link]($param_double_1);
[Link]($param_double_2);
[Link]($param_double_3);
} catch ([Link] e) {
throw new [Link]("error marshalling arguments", e);
}
[Link](call);
double $result;
try {
[Link] in = [Link]();
$result = [Link]();
} catch ([Link] e) {
throw new [Link]("error unmarshalling return", e);
} finally {
[Link](call);
}
return $result;
}
} catch ([Link] e) {
Se crea un flujo de
salida
Se escriben los
argumentos
(codificados) en el
flujo de salida
Se lee el resultado del flujo
de entrada y se decodifica
Se llama al mtodo
Se devuelve el resultado
Se crea un flujo de
entrada
[Link]
Miguel ngel Abin, Julio 2004 - 223/313 -
throw e;
} catch ([Link] e) {
throw e;
} catch ([Link] e) {
throw new [Link]("undeclared checked exception", e);
}
}
// implementation of getUnitarioX(double, double, double)
public double getUnitarioX(double $param_double_1, double $param_double_2, double
$param_double_3)
throws [Link]
{
try {
if (useNewInvoke) {
Object $result = [Link](this, $method_getUnitarioX_1, new
[Link][] {new [Link]($param_double_1), new
[Link]($param_double_2), new [Link]($param_double_3)},
185093586419828030L);
return (([Link]) $result).doubleValue();
} else {
[Link] call = [Link](([Link])
this, operations, 1, interfaceHash);
try {
[Link] out = [Link]();
[Link]($param_double_1);
[Link]($param_double_2);
[Link]($param_double_3);
} catch ([Link] e) {
throw new [Link]("error marshalling arguments", e);
}
[Link](call);
double $result;
try {
[Link] in = [Link]();
$result = [Link]();
} catch ([Link] e) {
throw new [Link]("error unmarshalling return", e);
} finally {
[Link](call);
}
return $result;
}
} catch ([Link] e) {
throw e;
} catch ([Link] e) {
throw e;
} catch ([Link] e) {
throw new [Link]("undeclared checked exception", e);
}
}
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 224/313 -
// implementation of getUnitarioY(double, double, double)
public double getUnitarioY(double $param_double_1, double $param_double_2, double
$param_double_3)
throws [Link]
{
try {
if (useNewInvoke) {
Object $result = [Link](this, $method_getUnitarioY_2, new
[Link][] {new [Link]($param_double_1), new
[Link]($param_double_2), new [Link]($param_double_3)}, -
6040331168870031281L);
return (([Link]) $result).doubleValue();
} else {
[Link] call = [Link](([Link])
this, operations, 2, interfaceHash);
try {
[Link] out = [Link]();
[Link]($param_double_1);
[Link]($param_double_2);
[Link]($param_double_3);
} catch ([Link] e) {
throw new [Link]("error marshalling arguments", e);
}
[Link](call);
double $result;
try {
[Link] in = [Link]();
$result = [Link]();
} catch ([Link] e) {
throw new [Link]("error unmarshalling return", e);
} finally {
[Link](call);
}
return $result;
}
} catch ([Link] e) {
throw e;
} catch ([Link] e) {
throw e;
} catch ([Link] e) {
throw new [Link]("undeclared checked exception", e);
}
}
// implementation of getUnitarioZ(double, double, double)
public double getUnitarioZ(double $param_double_1, double $param_double_2, double
$param_double_3)
throws [Link]
{
try {
if (useNewInvoke) {
Object $result = [Link](this, $method_getUnitarioZ_3, new
[Link][] {new [Link]($param_double_1), new
[Link]($param_double_2), new [Link]($param_double_3)}, -
5640072250555346327L);
[Link]
Miguel ngel Abin, Julio 2004 - 225/313 -
return (([Link]) $result).doubleValue();
} else {
[Link] call = [Link](([Link])
this, operations, 3, interfaceHash);
try {
[Link] out = [Link]();
[Link]($param_double_1);
[Link]($param_double_2);
[Link]($param_double_3);
} catch ([Link] e) {
throw new [Link]("error marshalling arguments", e);
}
[Link](call);
double $result;
try {
[Link] in = [Link]();
$result = [Link]();
} catch ([Link] e) {
throw new [Link]("error unmarshalling return", e);
} finally {
[Link](call);
}
return $result;
}
} catch ([Link] e) {
throw e;
} catch ([Link] e) {
throw e;
} catch ([Link] e) {
throw new [Link]("undeclared checked exception", e);
}
}
}
Esta clase stub declara los mtodos de la interfaz remota de
Cal cul oVect or i al I mp y delega las llamadas de los mtodos en la implementacin
RMI, que se encarga de serializar los argumentos y de enviar los datos al servidor.
Paso e) Se inicia el servicio de registro de RMI. Cualquier anfitrin que quiera
exportar referencias remotas (adaptadores) a los objetos locales de Java, de modo que
stos puedan llamar a los mtodos remotos, debe estar ejecutando un servidor de
registro RMI.
En Windows, se arranca este servicio mediante
st ar t r mi r egi st r y
En UNIX se usa r mi r egi st r y &. El proceso de usar r mi r egi st r y es muy
parecido a llamar al demonio por t map de un sistema UNIX.
Si se desea arrancar este servicio para que escuche por un puerto que no sea el
estndar (1099), hay que usar
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 226/313 -
st ar t r mi r egi st r y numpuer t o (Windows)
o
r mi r egi st r y numpuer t o & (UNIX)
Al ejecutarse, la aplicacin r mi r egi st r y crea un objeto Regi st r y que escucha
por un puerto y entra en un letargo aparente, a la espera de procesos clientes que
registren objetos remotos y de procesos clientes que busquen objetos remotos en el
registro RMI. Ntese que, para el servicio de registro, tantos los clientes RMI como los
servidores RMI son clientes. Los procesos de registro de objetos remotos deben
ejecutarse en el mismo anfitrin donde se est ejecutando r mi r egi st r y; en caso
contrario, se lanzar una excepcin [Link].
En mi sistema (Windows XP), ejecutar r mi r egi st r y lanza una nueva ventana
negra.
Figura 107. Ejecucin de rmiregistry
Paso f) Se inicia un objeto servidor y se registra en r mi r egi st r y. La clase que
acta como servidor en el ejemplo es Ser vi dor Cal cul oVect or i al , que se limita a
crear una instancia de Cal cul oVect or i al I mp.
Advertencia: En general, si el servidor y el cliente estn en la
misma mquina, el registro debe iniciarse incluyendo los archivos
stub en el CLASSPATH. En el ejemplo no es necesario hacerlo
porque todos los archivos estn en un mismo directorio (bi n).
[Link]
Miguel ngel Abin, Julio 2004 - 227/313 -
/**
* Clase que acta como servidor. Se limita a crear una instancia de
* CalculoVectorialImp. Al crearla, se registra en el servicio de registro RMI.
*/
import [Link].*;
import [Link].*;
public class ServidorCalculoVectorial {
public static void main(String args[]) {
try {
new CalculoVectorialImp();
[Link]("Servicio de clculo vectorial disponible.");
}
catch (Exception e) {
[Link]("No pudo arrancarse el servicio.");
}
}
}
Una vez compilada y ejecutada, el resultado se muestra en la siguiente captura de
pantalla.
Figura 108. El servicio de clculo vectorial en marcha
Ejemplo 17c: [Link]
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 228/313 -
Paso g) Se escribe la clase cliente. En ella se llama a un objeto
Cal cul oVect or i al con el nombre que se le dio en Cal cul oVect or i al I mp
(Cal cul osVect or )
/**
* Cliente de ejemplo para ServidorCalculoVectorial
*
* Muestra por la salida estndar el mdulo de un vector y las
* coordenadas del vector unitario asociado.
*/
import [Link].*;
import [Link].*;
public class ClienteCalculoVectorial {
public static void main(String args[]) {
try {
// El servidor de registro de RMI devuelve un objeto genrico, que debe
// ser convertido al tipo correspondiente. Ojo: el nombre por el que buscamos
// debe coincidir con el que se le dio al servicio en CalculosVectorImp.
CalculoVectorial cv =
(CalculoVectorial)[Link]("rmi://localhost/CalculosVector");
[Link]("El mdulo es: " + [Link](7, 2, 4));
[Link]("La primera coordenada del vector unitario es: " +
[Link](7, 2, 4));
[Link]("La segunda coordenada del vector unitario es: " +
[Link](7, 2, 4));
[Link]("La tercera coordenada del vector unitario es: " +
[Link](7, 2, 4));
}
catch (AccessException e1) {
[Link]("Se rechaz el acceso. Su sistema no tiene los permisos " +
"necesarios para realizar la operacin remota.");
[Link]();
}
catch (NotBoundException e2) {
[Link]("El nombre del objeto no est asociado a un objeto remoto " +
"registrado.");
[Link]();
}
catch ([Link] e3) {
[Link]("El nombre del objeto no est asociado a un objeto remoto " +
"registrado.");
[Link]();
}
catch (RemoteException e4) {
[Link]("No se encontr el servicio o hubo errores al llamar a los " +
"mtodos remotos.");
Ejemplo 17d: [Link]
[Link]
Miguel ngel Abin, Julio 2004 - 229/313 -
[Link]();
}
}
}
Paso h) Se compila la clase cliente. El resultado para el ejemplo es el archivo
Cl i ent eCal cul oVect or i al . cl ass.
Paso i) Se inicia un objeto cliente. Tras ejecutar la clase
Cl i ent eCal cul oVect or i al , mi sistema muestra la imagen de la captura de pantalla
siguiente.
Figura 109. Resultado de una llamada al servicio de clculo vectorial
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 230/313 -
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 . cl ass 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 . cl ass 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. cl ass de
los siguientes elementos:
La interfaz remota.
La clase adaptadora o stub que implementa a la interfaz remota.
Las clases del servidor cuyas instancias usa el cliente.
Las clases propias del cliente.
En el servidor, el cargador de clases debe poder acceder a los archivos. cl ass de
los siguientes elementos:
La interfaz remota.
La clase que implementa a la interfaz remota.
La clase esqueleto o skeleton asociada a la clase que implementa la
interfaz remota (slo es obligatoria en el JDK 1.1).
La clase adaptadora o stub que implementa a la interfaz remota.
[Link]
Miguel ngel Abin, Julio 2004 - 231/313 -
Las clases propias del servidor.
Lo dicho se representa en la siguiente figura.
Figura 110. Distribucin de los archivos en una aplicacin RMI
Gracias a la posibilidad de la carga dinmica de clases, la RMI de Java
proporciona un sencillo y potente mecanismo para distribuir aplicaciones. Vimos ya en
el subapartado 5.2.1 lo que sucede cuando un objeto intenta deserializar un flujo que
contiene algn objeto:
a) Se lee la descripcin de la clase, incluida en el flujo.
b) El cargador de clases de Java intenta cargar los bytecodes de
esa clase desde el directorio actual.
c) Si no la encuentra, contina buscando en los directorios
especificados en el CLASSPATH local.
d) Si no la encuentra, recurre al codebase que figura en el flujo
(siempre que se haya especificado la propiedad
j ava. r mi . ser ver . codebase). Esta propiedad puede
especificarse al ejecutar las clases.
[Link]
Object Client host Object Server host
object server directory
[Link]
[Link]
[Link]
[Link]
SomeImpl_Skel.class
SomeImpl_Stub.class
object client directory
Anfitrin del cliente Anfitrin del servidor
Directorio del cliente
Directorio del servidor
[Link]
[Link]
Implem_Stub.class
Implem_Stub.class
[Link]
Implemen_Skel.class
[Link]
DISTRIBUCIN DE LOS ARCHIVOS EN UNA
APLICACIN RMI
Las clases skeleton no son necesarias en el JDK 1.2 y posteriores
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 232/313 -
En consecuencia, colocando los archivos adecuados en un lugar comn y
especificando la propiedad j ava. r mi . ser ver . codebase, clientes y servidores
pueden acceder a ellos pese a no tenerlos en los anfitriones donde se ejecuten. Los
candidatos idneos para ser depositados en un lugar comn son los archivos . cl ass
de las clases adaptadoras o stub, porque son necesarios para clientes y servidores.
Las interfaces tambin deben estar disponibles para clientes y servidores; pero su
distribucin no plantea problemas, pues rara vez cambian.
La configuracin ms frecuente (y la que usar ms adelante) para distribuir una
aplicacin RMI consiste en hacer accesibles todos los archivos adaptadores mediante
un servidor web o FTP, con lo que se evita tenerlos en los anfitriones, y en configurar
adecuadamente la propiedad j ava. r mi . ser ver . codebase. Sun proporciona un
pequeo servidor HTTP para RMI, muy sencillo de usar, que incluyo en la pgina
siguiente.
La configuracin descrita slo es una de las posibles, existen otras muchas: por
ejemplo, se pueden usar clientes de tipo applet (que no necesitan tener ningn . cl ass
en el sistema local), o bien clientes o servidores que se limiten a descargar todos los
bytecodes necesarios (interfaz remota, etc.) desde un servidor web o FTP.
El uso de applets como clientes RMI vuelve trivial la instalacin y configuracin de
los clientes. Si se opta por una distribucin mediante applets RMI para el lado del
cliente, basta con tener un navegador compatible con Java para poder acceder siempre
a las versiones ms actuales de los clientes. En este caso, las peticiones de carga
dinmica de los .class pasarn por el navegador web, que las traducir a peticiones
HTTP y las enviar al servidor web donde se almacenen los . cl ass. Una vez
descargados los bytecodes, se ejecutarn; despus, las llamadas remotas sern
conducidas por los objetos del cliente hasta los objetos servidores.
Nota: Si ha ledo detenidamente los prrafos anteriores, habr notado que
afirmo que los archivos . cl ass de las clases adaptadoras (stubs) son
necesarias para clientes y servidores. No se trata de un error. Los
adaptadores tratan con las llamadas remotas en el lado del cliente, pero
tambin se necesitan en el lado del servidor.
En la documentacin de Sun sobre RMI, la necesidad de los adaptadores
en el lado del servidor no queda clara; pero la prueba del algodn nunca
falla: si se intenta ejecutar un objeto servidor sin acceso (ya sea mediante
CLASSPATH o mediante la propiedad j ava. r mi . ser ver . codebase) a los
adaptadores, se obtendr un error Stub class not found.
El lado del servidor utiliza los adaptadores cuando registra objetos remotos
en el servicio de registro RMI (este servicio viene a ser, a fin de cuentas, un
almacn de adaptadores y de nombres). Luego, los clientes reciben por
serializacin esos adaptadores cuando llaman a un mtodo remoto
mediante algn nombre de los que figuran en el servicio de registro RMI.
[Link]
Miguel ngel Abin, Julio 2004 - 233/313 -
/*
* Copyright (c) 1996, 1996, 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
* THIS SOFTWARE OR ITS DERIVATIVES.
*/
package server;
import [Link].*;
import [Link].*;
/**
* The ClassFileServer implements a ClassServer that
* reads class files from the file system. See the
* doc for the "Main" method for how to run this
* server.
*/
public class ClassFileServer extends ClassServer {
private String classpath;
private static int DefaultServerPort = 2001;
/**
* Constructs a ClassFileServer.
*
* @param classpath the classpath where the server locates classes
*/
public ClassFileServer(int port, String classpath) throws IOException
{
super(port);
[Link] = classpath;
}
/**
* 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.
*/
public byte[] getBytes(String path)
throws IOException, ClassNotFoundException
{
[Link]("reading: " + path);
Servidor web de Sun: [Link]
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 234/313 -
File f = new File(classpath + [Link] +
[Link]('.', [Link]) + ".class");
int length = (int)([Link]());
if (length == 0) {
throw new IOException("File length is zero: " + path);
} else {
FileInputStream fin = new FileInputStream(f);
DataInputStream in = new DataInputStream(fin);
byte[] bytecodes = new byte[length];
[Link](bytecodes);
return bytecodes;
}
}
/**
* Main method to create the class server that reads
* class files. This takes two command line arguments, the
* port on which the server accepts requests and the
* root of the classpath. To start up the server: <br><br>
*
* <code> java ClassFileServer <port> <classpath>
* </code><br><br>
*
* The codebase of an RMI server using this webserver would
* simply contain a URL with the host and port of the web
* server (if the webserver's classpath is the same as
* the RMI server's classpath): <br><br>
*
* <code> java -[Link]=[Link] RMIServer
* </code> <br><br>
*
* You can create your own class server inside your RMI server
* application instead of running one separately. In your server
* main simply create a ClassFileServer: <br><br>
*
* <code> new ClassFileServer(port, classpath);
* </code>
*/
public static void main(String args[])
{
int port = DefaultServerPort;
String classpath = "";
if ([Link] >= 1) {
port = [Link](args[0]);
}
if ([Link] >= 2) {
classpath = args[1];
}
try {
new ClassFileServer(port, classpath);
} catch (IOException e) {
[Link]("Unable to start ClassServer: " +
[Link]
Miguel ngel Abin, Julio 2004 - 235/313 -
[Link]());
[Link]();
}
}
}
/*
* Copyright (c) 1996, 1996, 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
* THIS SOFTWARE OR ITS DERIVATIVES.
*
* CopyrightVersion 1.1_beta
*/
package server;
import [Link].*;
import [Link].*;
/**
* ClassServer is an abstract class that provides the
* basic functionality of a mini-webserver, specialized
* to load class files only. A ClassServer must be extended
* and the concrete subclass should define the <b>getBytes</b>
* method which is responsible for retrieving the bytecodes
* for a class.<p>
*
* The ClassServer creates a thread that listens on a socket
* and accepts HTTP GET requests. The HTTP response contains the
* bytecodes for the class that requested in the GET header. <p>
*
* For loading remote classes, an RMI application can use a concrete
* subclass of this server in place of an HTTP server. <p>
*
* @see ClassFileServer
*/
public abstract class ClassServer implements Runnable {
private ServerSocket server = null;
private int port;
/**
* Constructs a ClassServer that listens on <b>port</b> and
* obtains a class's bytecodes using the method <b>getBytes</b>.
*
* @param port the port number
* @exception IOException if the ClassServer could not listen
Servidor web de Sun: [Link]
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 236/313 -
* on <b>port</b>.
*/
protected ClassServer(int port) throws IOException
{
[Link] = 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 = [Link]();
} catch (IOException e) {
[Link]("Class Server died: " + [Link]());
[Link]();
return;
}
// create a new thread to accept the next connection
newListener();
try {
DataOutputStream out =
new DataOutputStream([Link]());
try {
// get path to class file from header
DataInputStream in =
new DataInputStream([Link]());
String path = getPath(in);
[Link](path);
// retrieve bytecodes
byte[] bytecodes = getBytes(path);
[Link]
Miguel ngel Abin, Julio 2004 - 237/313 -
// send bytecodes in response (assumes HTTP/1.0 or later)
try {
[Link]("HTTP/1.0 200 OK\r\n");
[Link]("Content-Length: " + [Link] +
"\r\n");
[Link]("Content-Type: application/java\r\n\r\n");
[Link](bytecodes);
[Link]();
} catch (IOException ie) {
return;
}
} catch (Exception e) {
// write out error response
[Link]("HTTP/1.0 400 " + [Link]() + "\r\n");
[Link]("Content-Type: text/html\r\n\r\n");
[Link]();
}
} catch (IOException ex) {
// eat exception (could log error to log file, but
// write out to stdout for now).
[Link]("error writing response: " + [Link]());
[Link]();
} finally {
try {
[Link]();
} catch (IOException e) {
}
}
}
/**
* Create a new thread to listen.
*/
private void newListener()
{
(new Thread(this)).start();
}
/**
* Returns the path to the class file obtained from
* parsing the HTML header.
*/
private static String getPath(DataInputStream in)
throws IOException
{
String line = [Link]();
String path = "";
[Link](line);
// extract class from GET line
if ([Link]("GET /")) {
line = [Link](5, [Link]()-1).trim();
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 238/313 -
int index = [Link](".class ");
if (index != -1) {
path = [Link](0, index).replace('/', '.');
}
}
// eat the rest of header
do {
line = [Link]();
[Link](line);
} while (([Link]() != 0) &&
([Link](0) != '\r') && ([Link](0) != '\n'));
if ([Link]() != 0) {
return path;
} else {
throw new IOException("Malformed Header");
}
}
}
Para utilizar con RMI el elemental servidor web de Sun, hay que compilar las
clases y ejecutar Cl assFi l eSer ver especificando el puerto elegido para escuchar
peticiones HTTP y el camino donde se almacenan los archivos . cl ass que se quieran
poner a disposicin de clientes y servidores (stubs). Por ejemplo:
j ava ser ver . Cl assFi l eSer ver 8080 / home/ ej empl osRMI / cl ases
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/ ej empl osRMI / cl ases.
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 . cl ass 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:
Syst em. set Secur i t yManager ( new RMI Secur i t yManager ( ) ) ;
RMI Secur i t yManager es un gestor muy restrictivo, y en general conviene definir
una poltica de seguridad personalizada. La poltica se almacena en un archivo
(segur i dad. pol i cy, por ejemplo) y se instala as:
j ava - Dj ava. r mi . ser ver . codebase=ht t p: / / www. mi ser vi dor web. com/
- Dj ava. secur i t y. pol i cy=segur i dad. pol i cy Nomi na
As, cualquier descarga de bytecodes que necesite Nomi na se descargar de
ht t p: / / www. mi ser vi dor web. com/ (si esos bytecodes no aparecen en el
CLASSPATH local) y se tendr en cuenta la poltica de seguridad definida en el archivo
segur i dad. pol i cy.
[Link]
Miguel ngel Abin, Julio 2004 - 239/313 -
A continuacin pongo tres ejemplos de archivos de poltica de seguridad (el
formato general se describe en la documentacin de Sun):
gr ant { per mi ssi on j ava. net . Socket Per mi ssi on *: 1024- 65535, connect ; }
gr ant { / / Poco r ecomendabl e: dej a al si st ema despr ot egi do
per mi ssi on j ava. secur i t y. Al l Per mi ssi on;
};
gr ant {
per mi ssi on j ava. i o. f i l ePer mi ssi on / t mp/ *, r ead, wr i t e;
per mi ssi on j ava. net . Socket Per mi ssi on
anf i t r i on. domi ni o. com: 1025, connect ;
per mi ssi on j ava. net . Socket Per mi ssi on *: 1024- 65535,
connect , r equest ;
per mi ssi on j ava. net . Socket Per mi ssi on *: 80, connect ;
};
El tercer ejemplo especifica lo siguiente:
El cdigo Java que proceda de otras mquinas puede leer cualquier
archivo (y escribir en l) que est en el directorio / t mp o en sus
subdirectorios.
Todas las clases de Java pueden establecer una conexin de red con el
anfitrin anf i t r i on. domi ni o. compor el puerto TCP 1025.
Las clases pueden conectarse o aceptar conexiones por cualquier
puerto TCP superior a 1024, desde cualquier anfitrin.
Todas las clases pueden conectarse al puerto TCP 80 (HTTP) desde
cualquier anfitrin.
Para concretar todo lo expuesto, voy a considerar un ejemplo de aplicacin
distribuida que tiene en cuenta todo lo dicho. La aplicacin mantiene un registro de
empleados y permite que los clientes aadan o borren empleados, as como que
consulten la informacin de los empleados mediante cdigos alfanumricos.
A diferencia del ejemplo del subapartado anterior, en ste se devuelven objetos
remotos y se considera la sincronizacin de mtodos. Lo ltimo es necesario siempre
que los clientes compartan informacin del servidor; pues RMI asigna un hilo a cada
cliente que se conecta, y es obligacin del programador considerar en el cdigo las
situaciones conflictivas que pudieran generarse. Si no se sincronizaran los mtodos,
podra darse el caso de que un cliente borrara un registro que otro intenta leer al mismo
tiempo.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 240/313 -
En el ejemplo, los archivos stub estn en un servidor web imaginario al que se
accede mediante el URL ht t p: / / www. mi ser vi dor web. com/ mi scl ases/ y por el
puerto HTTP por defecto (80); la aplicacin del servidor reside en un anfitrin con URL
ht t p: / / www. mi ser vi dor RMI . comy escucha por el puerto TCP 9000.
Los clientes deben disponer en su anfitrin de los archivos
Regi st r oEmpl eados. cl ass, Empl eado. cl ass (asociados a interfaces remotas) y
Cl i ent eRegi st r oEmpl eados. cl ass (asociado al cliente). El servidor debe tener en
su sistema local de archivos Regi st r oEmpl eados. cl ass, Empl eado. cl ass,
Regi st r oEmpl eadosI mp. cl ass, Empl eadoI mp. cl ass,
Regi st r oEmpl eadosI mp_Skel . cl ass, Ser vi dor Regi st r oEmpl eados. cl ass,
Empl eadoI mp_Skel . cl ass. El servidor web proporciona los ficheros
Empl eadoI mp_St ub. cl ass y Regi st r oEmpl eadosI mp_St ub. cl ass mediante el
URL ht t p: / / www. mi ser vi dor web. com/ mi scl ases/ .
La aplicacin del servidor registra los objetos remotos por el puerto TCP 9000, por
lo que hay que iniciar r mi r egi st r y por ese puerto. La poltica de seguridad para el
cliente y el servidor viene definida por el archivo segur i dad. pol i cy (se pueden usar
otras extensiones: segur i dad. t xt , por ejemplo):
grant {
// Poltica de seguridad que permite que cualquiera escuche, se conecte
// o acepte peticiones mediante los puertos superiores al 1024
permission [Link] "localhost:1024-", "listen";
permission [Link] "localhost:1024-", "accept";
permission [Link] "localhost:1024-", "connect";
};
El cdigo de la aplicacin se expone a continuacin (he abreviado bastante los
comentarios).
import [Link].*;
public interface Empleado extends [Link] {
String getCodigo() throws [Link];
String getNombre() throws [Link];
double getSueldo() throws [Link];
}
Ejemplo 18a: [Link]
Ejemplo 18b: [Link]
[Link]
Miguel ngel Abin, Julio 2004 - 241/313 -
import [Link].*;
import [Link].*;
import [Link].*;
/**
* Implementacin de la interfaz Empleado
*/
public class EmpleadoImp extends UnicastRemoteObject implements Empleado {
private String codigo = null;
private String nombre = null;
private double sueldo = 0.0;
// Constructor
public EmpleadoImp(String codigo, String nombre, double sueldo) throws
[Link]{
[Link] = codigo;
[Link] = nombre;
[Link] = sueldo;
}
// Mtodos de acceso remotos
public String getCodigo() throws [Link] {
return codigo;
}
public String getNombre() throws [Link] {
return nombre;
}
public double getSueldo() throws [Link] {
return sueldo;
}
// Este mtodo no es remoto y no puede accederse a l mediante llamadas remotas.
// Se pone como ejemplo para ver que una interfaz local y una remota no tienen por qu
// coincidir, pero no se usar en el ejemplo.
public String toString() {
return ("Cdigo: " +[Link]+ " . Nombre: " + [Link] + " . Sueldo: "+
[Link] + " Euros.");
}
}
Ejemplo 18c: [Link]
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 242/313 -
import [Link].*;
public interface RegistroEmpleados extends [Link] {
// Registra un nuevo empleado
boolean registrar(String codigo, String nombre, double salario) throws
[Link];
// Devuelve un objeto Empleado
Empleado getEmpleado(String codigo) throws [Link];
// Borra un empleado
boolean borrar(String codigo) throws [Link];
}
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
/**
* Implementacin de la interfaz RegistroEmpleados
*/
public class RegistroEmpleadosImp extends UnicastRemoteObject implements
RegistroEmpleados {
private List lista= null;
public RegistroEmpleadosImp () throws [Link] {
super();
cargarEmpleados();
try {
// Se registra la clase con el servidor de registro de RMI en el anfitrin
// [Link] con el nombre "Plantilla".
// Se usar el puerto TCP 9000 (rmiregistry deber
// lanzarse con ese puerto).
[Link]("rmi://[Link]/Plantilla", this);
}
catch (AccessException e1) {
[Link]("Se rechaz el acceso. Su sistema no tiene los permisos " +
"necesarios para realizar la operacin remota" );
[Link](-1);
}
catch ([Link] e2) {
[Link]("La URL para el registro no es vlida.");
[Link](-1);
}
}
Ejemplo 18d: [Link]
Ejemplo 18e: [Link]
[Link]
Miguel ngel Abin, Julio 2004 - 243/313 -
public void cargarEmpleados() throws [Link] {
lista = new ArrayList();
EmpleadoImp emp1 = new EmpleadoImp("A0001", "Luis Monsalvez", 1219.68);
EmpleadoImp emp2 = new EmpleadoImp("A0002", "Ernesto Navarro", 967.19);
EmpleadoImp emp3 = new EmpleadoImp("A0003", "Manuel Soriano", 1456.34);
[Link](emp1);
[Link](emp2);
[Link](emp3);
}
public synchronized boolean registrar(String codigo, String nombre, double salario)
throws [Link] {
boolean temp = true;
if ( (codigo == null) || ([Link]("")) )
return false; // No se pudo registrar
Iterator it = [Link]();
while ( [Link]() ) {
if ( ((EmpleadoImp) [Link]()).getCodigo().equals(codigo) ) {
temp = false; // No se puede registrar: hay un empleado con ese cdigo
break;
}
}
if (temp) {
[Link](new EmpleadoImp(codigo, nombre, salario));
return temp; // Registro correcto
} else {
return temp; // Registro incorrecto: existe un empleado con ese cdigo
}
}
public synchronized boolean borrar(String codigo) throws [Link] {
Iterator it = [Link]();
EmpleadoImp emp = null;
if ( (codigo == null) || ([Link]("")) )
return false; // No se pudo borrar
while ( [Link]() ) {
emp = (EmpleadoImp) [Link]();
if ( ([Link]().equals(codigo)) ) { // Hay un empleado con ese cdigo
[Link](); // Se borra el empleado
return true; // Borrado correcto
}
}
return false; // Borrado incorrecto: no existe un empleado con ese cdigo
}
public synchronized Empleado getEmpleado(String codigo) throws
[Link] {
EmpleadoImp emp = null;
Iterator it = [Link]();
if ( (codigo == null) || ([Link]("")) )
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 244/313 -
return null; // Cdigo invlido
while ( [Link]() ) {
emp = (EmpleadoImp) [Link]();
if ( (emp).getCodigo().equals(codigo) )
return emp; // Empleado encontrado
}
return null; // No se encontr el empleado
}
}
import [Link].*;
import [Link].*;
public class ServidorRegistroEmpleados {
public static void main(String args[]) {
// Siempre conviene usar un controlador de seguridad. El controlador de
// seguridad por defecto de RMI es demasiado estricto para permitir que este
// ejemplo funcione, y por eso he definido una poltica propia de seguridad.
// Cuando se compile esta clase debe hacerse con
// java -[Link] = [Link] ServidorRegistroEmpleados
if ([Link]() == null) {
[Link](new RMISecurityManager());
}
try {
new RegistroEmpleadosImp();
[Link]("Servicio de registro de empleados disponible.");
[Link]("Puede registrar, borrar o modificar empleados.");
}
catch (Exception e) {
[Link]("No pudo arrancarse el servicio.");
[Link]();
}
}
}
Ejemplo 18f: [Link]
[Link]
Miguel ngel Abin, Julio 2004 - 245/313 -
import [Link].*;
import [Link].*;
public class ClienteRegistroEmpleados {
public static void main(String args[]) throws Exception {
// Siempre conviene usar un controlador de seguridad. El controlador de
// seguridad por defecto de RMI es demasiado estricto para permitir que este
// ejemplo funcione, y por eso he definido una poltica propia de seguridad.
// Cuando se compile esta clase debe hacerse con
// java -[Link] = [Link] ClienteRegistroEmpleados
if ([Link]() == null) {
[Link](new RMISecurityManager());
}
try {
// El servidor de registro de RMI devuelve un objeto genrico, que debe
// ser convertido al tipo correspondiente. Ojo: el nombre por el que buscamos
// debe coincidir con el que se le dio al servicio en ServidorRegistroEmpleados.
RegistroEmpleados re =
(RegistroEmpleados) [Link]("rmi://[Link]/Plantilla");
// Se intenta registrar un nuevo empleado
if ( ([Link] ("A0004", "Mercedes Romero", 1537.36)) ) {
[Link]("Registro correcto de Mercedes Romero.");
} else
[Link]("El codigo ya corresponde a un empleado.");
// Se intenta registrar un empleado con un cdigo que ya existe
if ( !([Link]("A0001", "Carlos Gandia", 1212.67)) )
[Link]("El codigo ya corresponde a un empleado.");
// Se obtienen los datos de un empleado
Empleado emp = [Link]("A0004");
if ( (emp != null) ) {
[Link]("Nombre: " + [Link]());
[Link]("Sueldo: " + [Link]());
} else
[Link]("No puedo encontrarse a nadie con ese codigo.");
// Se intenta borrar un empleado
if ( [Link]("A0002") ) {
[Link]("Registro borrado");
} else
[Link]("No se pudo encontrar el registro.");
}
catch (Exception e) {
[Link] ("O bien no se encontr el servicio o no se pudo arrancarlo, o " +
" bien hubo problemas en las llamadas a mtodos remotos.");
[Link]();
}
}
}
Ejemplo 18g: [Link]
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 246/313 -
Figura 111. Distribucin de los archivos del ejemplo 18
Al iniciar r mi r egi st r y (en un sistema Windows, con st ar t r mi r egi st r y
9000), hay que asegurarse de que bajo ningn concepto los archivos stub estn
disponibles localmente para r mi r egi st r y, slo mediante el servidor web. Dicho de
otro modo: en la ventana donde se ejecute r mi r egi st r y, el CLASSPATH no debe
incluir caminos a los archivos stub. En caso contrario, r mi r egi st r y los cargara del
sistema local y hara caso omiso de la propiedad j ava. r mi . ser ver . codebase. En
consecuencia, los archivos stub que devolvera a los clientes no tendran configurada
esa propiedad. Las consecuencias seran fatales para los clientes: cuando intentaran
deserializar instancias de la clase adaptadora o stub no encontraran nada en
j ava. r mi . ser ver . codebase y, al no poder cargar la clase, lanzaran excepciones
[Link].
Cuando se ejecute Ser vi dor Regi st r oEmpl eados, habr que hacerlo as
(supongo que el archivo de poltica de seguridad est en el mismo directorio que
Ser vi dor Regi st r oEmpl [Link] ass):
j ava - Dj ava. r mi . ser ver . codebase=ht t p: / / www. mi ser vi dor web. com/ mi scl ases/
- Dj ava. secur i t y. pol i cy=segur i dad. pol i cy Ser vi dor Regi st r oEmpl eados
Espacio en blanco
[Link]
[Link]
[Link]
[Link]
EmpleadoImp_Skel.class
RegistroEmpleadosImp_Skel.class
[Link]
[Link]
RegistroEmpleadosImp_Stub.class
EmpleadoImp_Stub.class
DISTRIBUCIN DE LOS ARCHIVOS DEL EJEMPLO 18
[Link]
[Link]
Anfitrin cliente
Anfitrin servidor
Anfitrin del servidor web
Registro RMI
(rmiregistry)
Llamada RMI
Llamada HTTP
Miguel ngel Abin, Mayo 2004
Espacio en blanco
Llamada HTTP
[Link]
Miguel ngel Abin, Julio 2004 - 247/313 -
Cuando se ejecute Cl i ent eRegi st r oEmpl eados, habr que hacerlo as
(supongo que el archivo de poltica de seguridad est en el mismo directorio que
Cl i ent eRegi st r oEmpl [Link] ass):
j ava - Dj ava. secur i t y. pol i cy=segur i dad. pol i cy Ser vi dor Regi st r oEmpl eados
El ejemplo ha sido probado con la siguiente configuracin, en la que se han usado
tres mquinas distintas, ubicadas en una LAN de tipo Ethernet:
Anfitrin del cliente RMI: PC con Windows XP Profesional.
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.
Al ejecutar el cliente desde el PC con Windows XP as:
obtuve esta salida (en vez de ht t p: / / www. mi ser vi dor web. com/ mi scl ases/
escrib el URL asociado al directorio del PC con Red Hat donde coloqu los . cl ass
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://[Link]/Plantilla" por "rmi://localhost:9000/Plantilla".
F:\JbuilderX\jdk1.4\bin>java -[Link]=
[Link] -[Link]= [Link]
ServidorRegistroEmpleados
Registro Correcto de Mercedes Romero
El cdigo ya corresponde a un empleado.
Nombre: Mercedes Romero
Sueldo: 1537.36
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 248/313 -
5.6. Ventajas e inconvenientes de la RMI
stas son algunas de las ventajas de trabajar con RMI:
Sencillez de uso. Cualquier programador en java aprende enseguida
a desarrollar aplicaciones RMI. En cualquier aplicacin para intranets
que trabajen con entornos Java, RMI puede ser una buena eleccin.
Separacin entre interfaz e implementacin. En sentido general, la
interfaz describe los servicios ofrecidos por un componente de un
sistema de comunicaciones (una capa, por ejemplo) y los protocolos
para usarlos. En los sistemas orientados a objetos, la interfaz de un
objeto es el conjunto de mtodos definidos para ese objeto, incluyendo
los argumentos de entrada y salida. En un sistema distribuido de
objetos, esta separacin resulta decisiva para aprovechar las ventajas
de la orientacin a objetos (polimorfismo, etc.).
Carga dinmica de cdigo. Java permite la descarga automtica de
bytecodes, lo que hace que el proceso de instalacin y configuracin
de los clientes puede ser tan sencillo como uno quiera. En el caso ms
simple, los clientes RMI pueden ser applets accesibles mediante un
navegador web. Si se opta por esta solucin, los usuarios no tendrn
que instalar o configurar nada; bastar con que dispongan de un
navegador y de acceso a la intranet o a Internet.
Sencillez de la localizacin de los servicios. A diferencia de los
sockets, un cliente RMI no necesita saber las direcciones explcitas de
los servidores (nombre del anfitrin y nmero de puerto). Es suficiente
con que sepa los nombres de stos y el registro RMI donde se han
registrado.
Seguridad. Puede usarse con protocolos de seguridad como SSL o
HTTPS.
He aqu algunos de los inconvenientes de trabajar con RMI:
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).
[Link]
Miguel ngel Abin, Julio 2004 - 249/313 -
Falta de control de las transacciones. Tras una transaccin, todos
los objetos involucrados deben actualizar su estado (si la transaccin
se ha completado) o deben volver al estado anterior a la transaccin
(si no ha podido completarse). As se consigue que todos los objetos
estn siempre en estados vlidos o consistentes. RMI carece de un
mecanismo automtico que controle las transacciones y que permita
revertir las modificaciones si finalmente la transaccin no se lleva a
cabo.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 250/313 -
6. CORBA: llamando desde ms lejos an. CORBA y Java
6.1. Introduccin. Para qu se usa CORBA?
Ahora que ya hemos visto cmo funciona la RMI de Java, podemos echar un
vistazo rpido a CORBA, tecnologa ya mencionada en el apartado anterior. No es
propsito del tutorial dar una visin completa de CORBA, ni mucho menos; pero ahora
que hemos profundizado en RMI, podemos entender a la perfeccin los entresijos de
CORBA sin necesidad de adentrarnos en los detalles ms tcnicos. Tenga en cuenta el
lector que CORBA se cre con la idea de ser una tecnologa neutral en cuanto al
lenguaje utilizado para implementarla; es lgico, por tanto, que sea ms detallada y
compleja que RMI, pues esta ltima slo trabaja con Java. Resulta meritorio el esfuerzo
hecho por Sun para sacar productos compatibles con CORBA o basados en su
arquitectura (RMI-IIOP y Enterprise Java Beans son dos ejemplos), pues demuestran
que Sun, al igual que otras muchas empresas, ha reconocido la importancia de un
estndar internacional, neutral en cuanto a plataformas y vendedores. Al lector
interesado en saber ms sobre CORBA, le recomiendo los libros mencionados al final
del subapartado 4.2.
CORBA (Common Object Request Broker Architecture: arquitectura comn de
intermediacin de solicitudes de objetos) es una arquitectura abierta, desarrollada por
el OMG (Object Management Group: grupo de gestin de objetos) para construir
aplicaciones distribuidas. CORBA consiste en un conjunto de especificaciones (no de
implementaciones) que, de seguirse, hacen posible la interaccin entre objetos CORBA
escritos en distintos lenguajes y ejecutados en diferentes plataformas.
Basndose en el modelo de comunicaciones de CORBA, se pueden construir
aplicaciones distribuidas en las que clientes y servidores se implementen en una
mezcla diversa de lenguajes y se ejecuten en una mezcla tambin diversa de sistemas
operativos y hardware. Por ejemplo, un cliente CORBA puede ejecutarse en un Mac y
estar escrito en Java; otro puede ejecutarse en una estacin de trabajo de IBM y estar
escrito en Smalltalk; mientras que el servidor puede ejecutarse en un sistema Windows
y estar escrito en C++. Desarrollar con CORBA viene muy bien, e incluso puede ser la
nica opcin, cuando se trabaja con muchas plataformas y lenguajes distintos.
CORBA tambin puede resultar muy til cuando hay que tratar con aplicaciones
antiguas cuyo cdigo no se puede modernizar a lenguajes ms actuales. Por ejemplo,
imaginemos que debe escribir cdigo que interaccione con una aplicacin monstruosa
escrita en COBOL, cuya reescritura en Java o C++ podra costar meses (o aos) y
millones de euros o dlares. Hoy da, resultara bastante absurdo escribir un cliente en
COBOL para esa aplicacin (s, ya s que existe el Visual COBOL y el Object COBOL;
pero sigue siendo COBOL, maldita sea). Usar CORBA nos permitira escribir el cliente
en el lenguaje que deseramos y evitaramos vernos atados a COBOL.
En general, CORBA resulta una opcin que considerar cuando se desea dar una
interfaz moderna a aplicaciones vetustas o que huelen a rancio. Podra parecer que
este uso de CORBA es inusitado, pero an hay mucho cdigo COBOL o Ada que se
aferra desesperadamente a la vida. Millones de lneas escritas en COBOL y Ada
forman parte de los actuales sistemas bancarios y militares de muchos pases (durante
un tiempo, Ada era, por ley!, el lenguaje que deba usarse en muchas instituciones
pblicas estadounidenses). De todos modos, no hay que irse a grandes sistemas para
ver a COBOL en funcionamiento: me faltan dedos en las manos para contar las
empresas donde me he encontrado aplicaciones de gestin escritas en COBOL. Como
el hardware y los sistemas operativos donde se ejecutaban originalmente estas
[Link]
Miguel ngel Abin, Julio 2004 - 251/313 -
aplicaciones duermen ya el sueo de los justos en los museos de informtica, no queda
ms remedio que ejecutarlas sobre emuladores.
Debido a la gran escalabilidad de CORBA, tambin se usa en servidores que
atienden un gran nmero de peticiones simultneas: permite repartir entre distintas
mquinas el trabajo de contestar las peticiones, aunque stas sean de diferentes
fabricantes (lo cual suele implicar variadas arquitecturas de hardware y sistemas
operativos heterogneos). Por ejemplo, imagnese un sistema bancario internacional
que procese y registre cientos o miles de transacciones monetarias por segundo,
procedentes de todas las sucursales repartidas por el mundo. CORBA podra usarse
para distribuir el procesado y registro de las peticiones entre varias mquinas:
mainframes, estaciones de trabajo UNIX, estaciones de trabajo de IBM, PCs de altas
prestaciones, etc. CORBA se encargara de repartir el trabajo entre todas las
mquinas, dependiendo del volumen de peticiones, de la capacidad de cada mquina y
de la carga de trabajo de cada una. Asimismo, CORBA puede usarse en aplicaciones
de tipo web que reciban muchas peticiones simultneas.
Cuatro son las principales caractersticas arquitectnicas de CORBA
- Separacin entre interfaz e implementacin. Como los clientes
llaman a los objetos por medio de interfaces, no se ven afectados por
cambios en las implementaciones de stos. Ms an: los clientes
desconocen los cambios en las implementaciones de los objetos a los
que llaman. Esta caracterstica simplifica los cambios y actualizaciones
en los objetos de una aplicacin distribuida.
- Independencia de la localizacin. Los clientes pueden acceder a los
objetos sitos en una red sin conocer dnde residen. El cliente
desconoce si los objetos a los que llama estn en procesos distintos
en la misma mquina, en una misma LAN, en una WAN o en una
sonda espacial con una rbita geoestacionaria.
- Independencia del vendedor. Los productos CORBA de un
fabricante pueden interoperar con los de otros.
- Integracin de sistemas mediante la interoperabilidad. Los
productos que cumplen las especificaciones de CORBA son
independientes de la plataforma: cualquier cliente puede llamar a un
servidor, independientemente de las plataformas donde se ejecuten
uno y otro.
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
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 252/313 -
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.
6.2. El modelo de objetos de CORBA
En un sistema de software, un modelo de objetos es un conjunto de
especificaciones de implementacin y de propiedades semnticas que define cmo se
representan los objetos en un determinado lenguaje de programacin y cmo se
implementan las caractersticas de la orientacin a objetos (abstraccin, encapsulado,
herencia, etc.).
Aunque el trmino orientacin a objetos es una caja donde caben muchos
conceptos, hay unanimidad a la hora de definir las caractersticas que debe
proporcionar un modelo de objetos: clase/tipo, objetos, identidad de los objetos,
abstraccin, encapsulado, herencia y polimorfismo.
Los conceptos de clase y tipo son conocidos por cualquiera que programe en
Java. En un lenguaje de programacin, una clase es tanto la definicin de un conjunto
de objetos con propiedades y operaciones comunes como una fbrica de objetos (se
dice que estos objetos son instancias de la clase). En tiempo de ejecucin, una clase
acta como molde para un conjunto de objetos, dotndoles de interfaz (parte externa) y
de implementacin (parte interna). Los tipos resultan un poco mas sutiles: vienen a ser
representaciones software de los tipos de datos abstractos (pilas, colas, etc.). Cuando
se dice que un objeto es de tipo X, se busca expresar que ese objeto tiene la interfaz
definida por el tipo X.
Ambos conceptos suelen usarse de forma intercambiable, pero son distintos.
Varias son las diferencias: a) tipo es un concepto asociado al tiempo de compilacin,
mientras que clase se vincula ms con el tiempo de ejecucin; b) los tipos no definen
implementaciones y, por tanto, no pueden crear objetos; c) un objeto es instancia de
una sola clase, pero puede ser de varios tipos a la vez.
Hay lenguajes OO basados en tipos (Smalltalk, p. ej.), en clases (C++) y basados
en tipos y clases (Java, C#). En los lenguajes que permiten tipos, stos se usan para
comprobar, durante el proceso de compilacin, si los programas son correctos
(comprobacin de tipos). En los lenguajes que no tienen tipos, un error como pasar un
objeto Per sona a un mtodo que espera un argumento Coche no se advertir hasta
que se llame al mtodo en tiempo de ejecucin.
Un objeto es una instancia de una clase. En tiempo de ejecucin, un objeto es un
rea de memoria dentro de un proceso.
[Link]
Miguel ngel Abin, Julio 2004 - 253/313 -
La identidad de un objeto es como el DNI de una persona: permite identificarlo
unvocamente. La identidad de un objeto es nica y no puede ser modificada una vez
creado el objeto.
La abstraccin es la capacidad de un modelo para ignorar algunos aspectos de la
informacin con que trabaja. Cada objeto es una abstraccin que puede recibir
peticiones y contestarlas sin revelar cmo lo hace.
El encapsulado (u ocultacin de la informacin) es el principio por el cual los
objetos se esconden (se encapsulan) tras su interfaz. Un objeto bien diseado revela lo
menos posible de su funcionamiento interno (implementacin). La gran ventaja del
encapsulado estriba en que permite cambiar la implementacin de un objeto sin que los
dems objetos tengan que ser modificados o advertidos.
El polimorfismo es la capacidad de asociar distintos tipos (distintos
comportamientos, en definitiva) a un mismo objeto.
La herencia es el mecanismo por el cual se pueden derivar nuevas clases de las
ya existentes. Una subclase hereda las propiedades y mtodos de la superclase, y
puede modificarlos o incluir otros. Dentro de la herencia, hay dos variedades: la de
tipos y la de implementacin. En la primera, las subclases heredan la interfaz de la
superclase; en la segunda, heredan de sta los datos y el cdigo de los mtodos. Los
lenguajes OO con tipos admiten ambas.
Como CORBA es una arquitectura independiente de cualquier lenguaje o
plataforma, su modelo de objetos se ve obligado a ser abstracto. Un sistema de objetos
CORBA es un conjunto de objetos en el que unos solicitan servicios (clientes) y otros
los proporcionan (servidores). Los clientes pueden hacer peticiones slo mediante la
interfaz de los servidores y desconocen la implementacin de estos ltimos. Como
ocurre en cualquier modelo de objetos, la comunicacin entre objetos se lleva a cabo
exclusivamente mediante el intercambio de mensajes (llamadas y respuestas). Los
objetos CORBA pueden ser creados o destruidos; pero los clientes no tienen ningn
mecanismo para crearlos o destruirlos.
El modelo de objetos de CORBA no proporciona todas las caractersticas
desglosadas antes. Por ejemplo, el concepto de clase no existe: la estructura class de
lenguajes como C++, Java, Smalltalk o C# brilla por su ausencia. Los objetos s
existen: son entidades identificables y encapsuladas que proporcionan al menos un
servicio que puede ser solicitado por uno o ms clientes. El concepto de objeto CORBA
es un tanto escurridizo y lo abordar con detalle en el siguiente subapartado.
Con respecto a los tipos, el IDL del OMG es un lenguaje basado en tipos y en el
cual todo objeto debe declarar su tipo (lo que se conoce como fuertemente tipado).
Hay dos tipos especiales en CORBA: Any y TypeCode.
El tipo Any permite la especificacin de valores que permiten expresar cualquier
tipo IDL (sea primitivo o definido por el usuario, siempre que haya sido definido en
tiempo de compilacin). Un Any contiene un TypeCode y un valor descrito por ste. En
cada traduccin del IDL a un lenguaje concreto, existen operaciones que permiten
insertar un TypeCode en un Any (y extraerlo de l). Los Any resultan muy tiles para
hacer comprobaciones de tipos de manera dinmica.
El tipo TypeCode es un metatipo: un TypeCode representa un tipo de datos
definidos por el IDL del OMG. Es la especificacin de CORBA, TypeCode se define
como una interfaz con operaciones para averiguar cul es el tipo representado por un
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 254/313 -
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.
Figura 112. Representacin del metatipo TypeCode. Extrado de la documentacin
del OMG sobre CORBA
Figura 113. Entidades del IDL. Se incluyen los tipos primitivos
ENTIDADES DEL IDL DEL OMG
Entity
Object reference
Value Type
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
Abstract Interface
He optado por mantener en ingls los nombres de todas las entidades que aparecen en la documentacin del OMG
Miguel ngel Abin Julio 2004
[Link]
Miguel ngel Abin, Julio 2004 - 255/313 -
En el caso de otras caractersticas, el significado en CORBA vara del dado antes.
Por ejemplo, CORBA separa muy claramente (al igual que RMI) interfaz e
implementacin, lo cual tiene consecuencias para la herencia. De hecho, la separacin
no es slo conceptual: la interfaz puede estar en un anfitrin y la implementacin puede
estar repartida entre anfitriones a miles de kilmetros del primero.
La herencia de implementacin no tiene cabida en el modelo de CORBA, pues
esta herencia se basa en heredar atributos y cdigo de mtodos lo cual est vinculado
a lenguajes de programacin concretos, mientras que CORBA es independiente del
lenguaje de programacin. Por tanto, herencia en CORBA significa herencia de
tipos. En este tipo de herencia, se heredan las interfaces (las operaciones). As, en
CORBA una clase Cani che puede heredar una operacin l adr ar ( ) de una clase
Per r o, pero no puede heredar el cdigo de l adr ar ( ) que haya en Per r o. Al igual
que ocurre en cualquier lenguaje OO, una interfaz CORBA puede tener muchas
implementaciones (dicho de otro modo: una operacin puede materializarse en muchos
mtodos). Ahora bien, en CORBA, estas implementaciones de una misma interfaz
pueden estar escritas en distintos lenguajes: C, COBOL, C++, Java, etc. Una operacin
como l adr ar ( ) puede implementarse con C++ en una clase Cani che, y puede
implementarse con Smalltalk en una clase Gal go.
El concepto de identidad del objeto pervive en CORBA, pero transformado en el
de referencia a objeto. Una referencia a un objeto es una prolongacin de la identidad
de ste, con informacin adicional sobre la ubicacin del objeto (anfitrin, nmero de
puerto, protocolo de acceso, etc.). Los clientes llaman a los servidores mediante
referencias a estos ltimos, nunca directamente.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 256/313 -
6.3. Vocabulario bsico de CORBA
Para evitar ambigedades, antes de proseguir expongo la definicin de los
siguientes trminos en el sentido dado por el OMG y por la mayor parte de los textos
sobre CORBA:
- Objeto CORBA (u objeto). Entidad virtual susceptible de ser encontrada
por una aplicacin CORBA y de recibir peticiones por parte de un cliente.
Tiene asociada una identidad inmutable, una interfaz, una implementacin
(sirviente) y una localizacin. Los objetos CORBA pueden implementarse en
lenguajes no orientados a objetos.
- Referencia (a un objeto CORBA). Se asigna en el momento de la creacin
de un objeto CORBA. Los clientes hacen sus peticiones a los objetos
CORBA mediante referencias, pero no tienen acceso a ellas ni pueden
modificarlas (son opacas para ellos). Toda referencia contiene un
identificador del objeto (object ID), nica en un proceso del servidor. Un
objeto tiene un solo identificador, si bien puede tener mltiples referencias.
Las referencias a objetos CORBA se asemejan a los punteros de C++:
pueden apuntar a objetos inexistentes o inalcanzables, o a ningn lugar.
- Sirviente (servant). Entidad de un lenguaje de programacin que
implementa uno o ms objetos CORBA. Por tanto, define los mtodos
especificados por la interfaz IDL del objeto u objetos. En los lenguajes OO,
los sirvientes se definen con clases sirviente y, en consecuencia, los objetos
CORBA se implementan como instancias de las clases sirvientes. En la
documentacin inicial del OMG, objeto sirviente o sirviente se usaba como
sinnimo de implementacin del objeto (object implementation). Cuando una
clase sirviente se activa, genera sirvientes. En tiempo de ejecucin, los
sirvientes tienen asignados unos recursos de CPU y unas zonas de memoria,
que se liberan cuando son destruidos.
- Cliente (o cliente CORBA). Entidad de programacin que realiza
peticiones a un objeto CORBA. No necesariamente tiene que ser instancia de
una clase. Los clientes no trabajan directamente con los objetos CORBA,
sino con referencias a los objetos.
- Servidor (o servidor CORBA). Proceso o aplicacin en la que hay uno o
ms objetos CORBA y que atiende las peticiones de los clientes. Un servidor
contiene implementaciones de uno o ms interfaces IDL (en los lenguajes
OO, dichas implementaciones son clases sirvientes). En general, servidor y
objeto CORBA son trminos intercambiables, si bien no idnticos.
Antepondr a servidor la palabra proceso cuando me interese destacar
esa faceta o evitar la posible confusin con la mquina o anfitrin donde se
ejecuta el proceso servidor.
- Peticin. Llamada de un cliente a una operacin de un objeto CORBA por
parte de un cliente.
El concepto de objeto CORBA es bastante delicado, y pocas veces se explica
correctamente. A pesar de la O de Object, el OMG no clarifica mucho este concepto;
quizs saben demasiado como para caer en esa trampa. El uso de objeto induce a
confusin: un objeto CORBA es un objeto en el sentido de una entidad con estado,
[Link]
Miguel ngel Abin, Julio 2004 - 257/313 -
identidad e interfaz; pero no es necesariamente un objeto en el sentido de instancia
de una clase de un lenguaje orientado a objetos. CORBA trabaja con lenguajes no OO
(COBOL, C, Ada), que carecen de clases y de instancias de clases. De hecho, en el
IDL del OMG prescinde del concepto de clase.
Por otro lado, los objetos CORBA son virtuales: pueden existir sin estar asociados
a cdigo que implemente las operaciones de la interfaz. Cuando se crea un objeto
CORBA, se crea una referencia de objeto que encapsula la informacin de la interfaz
del objeto junto con un identificador (generado por la aplicacin CORBA). Esta
referencia puede enviarse al cliente para que pueda usar hacer sus llamadas remotas;
pero no est asociada a ningn proceso. Crear un objeto CORBA no es crear una
instancia o activar un proceso con una memoria reservada y unos recursos de CPU:
slo es asignarle una referencia. Destruir un objeto es privarle de su referencia, la
cual se vuelve inutilizable. Un objeto destruido ya no puede ser llamado por un cliente.
Como le en alguna parte, no hay nada parecido a un desfibrilador que pueda devolver
la vida a los objetos CORBA.
Cuando un cliente realiza una peticin a un objeto CORBA que acaba de ser
creado, suele producirse la activacin de ste. La activacin es el proceso por el cual
se asigna un sirviente a un objeto CORBA. En los lenguajes OO, un sirviente se deriva
de una clase; en los no OO, un sirviente se deriva de un conjunto de funciones que
manipulan una estructura de datos (un struct, por ejemplo). En los primeros que son
los que nos interesan, la activacin consiste en asignar una instancia de una clase
sirviente a un objeto CORBA (lo cual suele implicar la creacin de la instancia). Dicho
de otra forma: un servidor activa un objeto cuando crea un sirviente, asignndole un
espacio de memoria y unos recursos de CPU, y lo asocia a un objeto CORBA. Como
un sirviente deriva de una clase que implementa los mtodos de la interfaz IDL del
objeto CORBA, puede manejar las llamadas de los clientes al objeto.
En cierto modo, un objeto CORBA es un vestido vaco; cuando se le asigna un
sirviente, se le dota de cuerpo. Desde el punto de vista de los sirvientes, se dice que
un sirviente encarna a un objeto cuando se crea un vnculo o ligadura entre ellos.
Desactivar un objeto CORBA es eliminar el vnculo entre l y su sirviente. Este
proceso no implica destruir el objeto (un objeto desactivado puede ser reactivado si
recibe la llamada de algn cliente), pero suele implicar la destruccin del sirviente (y la
liberacin de la memoria y de los recursos reservados a ste). Cuando se desactiva un
objeto, se le quita el cuerpo del sirviente: vuelve a ser un ente fantasmal, con una
referencia y una interfaz; pero sin cdigo en ejecucin que implemente a esta ltima.
Las maneras ms frecuentes de desactivar un objeto son dos: detener el proceso
de servidor que lo ha creado y destruir el sirviente al cual est asociado. Desde el
momento en que el objeto queda desactivado, no puede responder a las peticiones de
los clientes mientras no se le vuelva a asociar un sirviente.
En las activaciones explcitas, se crean sirvientes para todos los objetos que se
van creando (y se van asociando con stos). En las activaciones bajo demanda, slo
se activan aquellos objetos que reciben llamadas de los clientes.
Durante la vida de un objeto CORBA, ste puede estar asociado a muchos
sirvientes; asimismo, un sirviente puede estar asociado, en un instante determinado, a
varios objetos.
Resulta lgico que uno se pregunte el porqu de tantos trminos: objeto CORBA,
sirviente, creacin, destruccin, activacin, desactivacin, encarnacin, etc. Una
primera respuesta estriba en que se pretende marcar la dicotoma entre los objetos
CORBA y los sirvientes, de modo que se perciban desde el principio como entidades
separadas. A qu obedece esta separacin? No sera mucho ms sencillo identificar
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 258/313 -
un objeto CORBA con un sirviente, y viceversa? S, s lo sera; pero esa identificacin
tendra graves repercusiones en la eficacia de las aplicaciones CORBA.
Veamos un ejemplo de esas consecuencias: imagine una base de datos integrada
en una aplicacin CORBA y que tiene miles o millones de registros. Si a cada objeto
CORBA que representa a un registro se le asociara un sirviente, el servidor debera
crear muchsimas instancias y mantenerlas con vida durante todo el tiempo de la vida
de la aplicacin, por si algn cliente llamara a alguna. Como puede suponer, el
consumo de recursos (RAM, CPU) sera exagerado. En dicho caso, tampoco se podra
reutilizar sirvientes (salvo que se desvistiera a un santo para vestir a otro), pues crear
un objeto CORBA sera idntico a crear un sirviente. Las dificultades no acabaran ah:
al destruirse un sirviente se destruira tambin el objeto CORBA asociado, lo que
impedira la persistencia de los objetos (deseable en muchas ocasiones).
La separacin entre objeto y sirviente complica conceptualmente el entendimiento
de CORBA; pero mejora el rendimiento y la escalabilidad de las aplicaciones CORBA.
Y no olvidemos que CORBA se usa en aplicaciones industriales donde esas
propiedades son tan valiosas como el agua en el desierto. Con esta distincin, un
sirviente se crea slo cuando un cliente llama a un objeto. Asimismo, un sirviente
puede aprovecharse para distintos objetos, sin que haya que crear ms sirvientes.
Un ejemplo valdr para aclarar lo dicho: considere una aplicacin CORBA que
almacena los datos de los empleados de una empresa. Como el servidor no sabe qu
datos van a consultar los clientes, lo normal es que cree un objeto CORBA para cada
empleado. Tendr, pues, que almacenar una referencia por empleado, exigencia que
no resultar devastadora para sus recursos. Cuando un cliente llame al mtodo
get Nombr e( ) del objeto CORBA l ui sNavar r o, el servidor crear un sirviente con la
implementacin de ese mtodo y de los otros que pudiera tener el objeto, as como con
los atributos correspondientes (edad, sueldo, etc.). Pasado un tiempo, si el servidor no
recibe ms peticiones, el objeto CORBA ser desactivado (no destruido). Cuando esto
ocurra, el sirviente afrontar una de estas suertes: ser destruido o se mantendr a la
espera de nuevas peticiones. En el primer caso, una llamada a un mtodo del objeto
j uanSanchez producir la creacin de un nuevo sirviente; en el segundo, el sirviente
de l ui sNavar r o pasar a ser de j uanSanchez.
En CORBA, el cliente siempre es afortunado: ignora cualquiera de las sutilezas
expuestas. Al cliente poco le importa que el objeto al cual llama se active o desactive, o
que haya un cambiazo de sirvientes: l se limita a hacer sus peticiones. Su conveniente
desinters por la manera como se complacen sus peticiones resalta la similitud con
algunos clientes de carne y hueso. Perdonen que asigne cualidades humanas a las
entidades CORBA: ya s que a ellas no les gusta ser tratadas as.
[Link]
Miguel ngel Abin, Julio 2004 - 259/313 -
6.4. Dentro de la arquitectura de CORBA
CORBA es una especificacin de una arquitectura de red (esto es, un conjunto de
capas y protocolos para las comunicaciones en red) cuyas partes y conceptos ms
importantes vamos a ir viendo a lo largo de este subapartado.
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
[Link] 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
RADIOGRAFA DE LA ARQUITECTURA CORBA
Depsito de
interfaces
Compilador IDL
Depsito de
implementaciones
Cliente
Adaptador DII
Interfaz
ORB
Sirviente
DSI Esqueleto
Interfaz
ORB
Ncleo del ORB
Adaptador de objetos
Ncleo del ORB
TCP/IP
IIOP
Comunicacin
lgica
Miguel ngel Abin Julio 2004
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 260/313 -
acomodar sus peticiones a la manera especificada por la interfaz. Un servidor que no
respete la interfaz provocar el desconcierto entre sus clientes (Por qu me devuelve
una patata cuando he pedido una manzana?, Por qu me dice que el dlar ha
subido si le pregunto por el tiempo en Ginebra?). Un servidor que mute su interfaz
repentinamente y sin avisar a los clientes enseguida descubrir una verdad elemental
del comercio, mencionada antes: se tarda una vida en conseguir un cliente, y slo unos
minutos en perderlo para siempre.
Usando IDL, se puede describir:
Las interfaces de objetos o mdulos
Las operaciones y los atributos de un objeto o mdulo
Las excepciones lanzadas por un mtodo.
Los tipos de datos de los argumentos de un mtodo, as como
de sus valores de retorno.
La sintaxis del IDL es un subconjunto de la del ANSI-C++, a la que se le han
aadido algunas palabras para incluir conceptos propios de las arquitecturas
distribuidas. Dicho con un trabalenguas: en cuanto a sintaxis, IDL es un superconjunto
de un subconjunto del ANSI-C++.
Figura 115. Palabras reservadas del IDL de CORBA
Vemos un ejemplo de un mdulo IDL (los mdulos equivaldran a las clases de
C++, Java o Smalltalk):
// Cdigo IDL
module Personal {
struct Persona {
string nombre;
string apellido;
short edad;
double salario;
};
Palabras reservadas del IDL de Palabras reservadas del IDL de
CORBA CORBA
any attribute boolean case char
const context default double enum
exception FALSE fixed float in
inout interface long module
Object octet oneway out
raises readonly sequence short
string struct switch TRUE
typedef unsigned union void
wchar wstring
[Link]
Miguel ngel Abin, Julio 2004 - 261/313 -
exception Excepcion{};
interface Salario {
double getSalario() raises(Excepcion);
// salario es el argumento de setSalario
void setSalario (in double salario);
};
};
La palabra i n indica que estamos ante un argumento de entrada; se puede usar
tambin out (argumento de salida) e i nout (argumento de entrada y salida).
Figura 116. Estructura de un archivo IDL
Para todos los lenguajes compatibles con CORBA, existen traducciones de las
estructuras del IDL a los lenguajes compatibles (se pueden consultar en
[Link] Los compiladores
IDL convierten los archivos con cdigo IDL en cdigo escrito en el lenguaje de destino.
Personalmente, preferira llamar traductor IDL al compilador IDL, pues en realidad no
compila a cdigo nativo ni a bytecode; pero en la documentacin de OMG se usa casi
exclusivamente el trmino compilador.
SINTAXIS DEL IDL DEL OMG
module <i dent i f i cador > {
<decl ar aci ones de t i pos>;
<decl ar aci ones de const ant es>;
<decl ar aci ones de excepci ones>;
interface <i dent i f i cador > [ :<her enci a>] {
<decl ar aci ones de t i pos>;
<decl ar aci ones de const ant es>;
<decl ar aci ones de at r i but os>;
<decl ar aci ones de excepci ones>;
[ <t i po oper aci on>] <i dent i f i cador >(<l i st a ar gument os>)
[ raises <excepci ones>]
[ <t i po oper aci on>] <i dent i f i cador >(<l i st a ar gument os>)
[ raises <except i ones>]
. . .
};
interface <i dent i f i cador > [ :<her enci a>] {. . . };
. . .
};
module <i dent i f i cador > {
<decl ar aci ones de t i pos>;
<decl ar aci ones de const ant es>;
<decl ar aci ones de excepci ones>;
interface <i dent i f i cador > [ :<her enci a>] {
<decl ar aci ones de t i pos>;
<decl ar aci ones de const ant es>;
<decl ar aci ones de at r i but os>;
<decl ar aci ones de excepci ones>;
[ <t i po oper aci on>] <i dent i f i cador >(<l i st a ar gument os>)
[ raises <excepci ones>]
[ <t i po oper aci on>] <i dent i f i cador >(<l i st a ar gument os>)
[ raises <except i ones>]
. . .
};
interface <i dent i f i cador > [ :<her enci a>] {. . . };
. . .
};
Miguel ngel Abin Julio 2004
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 262/313 -
Cuando se usa un compilador IDL con un archivo donde se especifica la interfaz
de una objeto CORBA, se generan en el lenguaje de destino: C, C++, Java, etc.
varios archivos. Dos de ellos corresponden al adaptador (stub) y al esqueleto (skeleton)
para la interfaz. Como ya vimos en el apartado anterior, un adaptador es un
intermediario local para el objeto remoto: su interfaz coincide con la del objeto servidor,
pero se ejecuta en el anfitrin del cliente. Un esqueleto es anlogo al adaptador del
cliente, pero en el lado del servidor. Mediante unos y otros, las llamadas remotas se
simulan como si fuesen locales: para el objeto cliente, los adaptadores simulan los
mtodos del objeto remoto; para el objeto servidor, los esqueletos simulan las llamadas
del objeto cliente como si fueran locales.
Al generar adaptadores y esqueletos, un compilador IDL produce el cdigo que se
usar para codificar los datos que se enven como argumentos en las llamadas
remotas y para decodificarlos (lo mismo hace para RMI el compilador r mi c). En los
lenguajes OO, las clases sirviente suelen derivarse por herencia de las clases
esqueleto generadas por el compilador IDL. Asimismo, las clases que actan como
clientes suelen derivarse por herencia de los adaptadores generados por el compilador
IDL.
Figura 117. Generacin de adaptadores y esqueletos en CORBA
GENERACIN DE ADAPTADORES Y
ESQUELETOS
Definiciones
IDL
Compilador
IDL
Adaptador Esqueleto
El compilador IDL
genera los adaptadores y
los esqueletos en un
cierto lenguaje de
programacin (J ava,
C++, etc.)
Miguel ngel Abin Julio 2004
[Link]
Miguel ngel Abin, Julio 2004 - 263/313 -
El ORB (Object Request Broker: intermediario de peticiones de objetos) es el
ncleo, el corazn de CORBA. Gracias a l, los objetos pueden intercambiar llamadas
con independencia de las plataformas donde se ejecutan. El papel del ORB es de
coordinador general para todos los objetos en una aplicacin CORBA. Se encarga de
identificar y localizar los objetos, de abrir y gestionar las conexiones en las mquinas
donde residen clientes y servidores (de forma independiente de las plataformas
usadas) y de la entrega y devolucin de los datos. Clientes y servidores acceden a las
funciones del ORB mediante la interfaz que ste ofrece. El trabajo que el ORB ahorra a
los programadores es monumental: no tienen que preocuparse de la localizacin de los
objetos, de los protocolos de red, de las implementaciones de los objetos, etc. En el
lado del cliente, el ORB es responsable de
aceptar las peticiones a los objetos remotos;
encontrar las implementaciones de los objetos (sirvientes);
aceptar las referencias a objetos remotos;
encaminar las llamadas que hacen los clientes mediante referencias a
objetos a la implementacin del objeto llamado (sirviente).
En el lado del servidor, el ORB
permite que los objetos servidores registren nuevos objetos;
recibe peticiones de los clientes;
usa la interfaz de los objetos esqueletos para llamar a los mtodos de
activacin de los objetos;
crea referencias para los nuevos objetos y se las transmite a los
clientes.
La comunicacin entre adaptadores y esqueletos se realiza a travs del ORB. Ms
adelante veremos cmo lo hace.
Figura 118. Otra vista de la arquitectura de CORBA
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 264/313 -
Figura 119. Todo pasa por el ORB
CORBA REPOSA SOBRE EL ORB
Cliente
IDL IDL
J ava COBOL
IDL
C++
IDL
Servidor
IDL IDL
J ava COBOL
IDL
C++
IDL
n
g
e
l
A
b
i
n
J
u
l
i
o
2
0
0
4
[Link]
Miguel ngel Abin, Julio 2004 - 299/313 -
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:
Se compila el archivo Mensaj er i a. i dl con i dl j f al l
Mensaj er i a. i dl Se generar un directorio Mensaj er i a con los
archivos Eco. j ava, EcoPOA. j ava y EcoOper at i ons. j ava,
_EcoSt ub. j ava, EcoHel per . j ava y EcoHol der . j ava.
Se compilan los archivos anteriores.
Los archivos . cl ass generados en el paso anterior se copian en el
anfitrin del cliente y del servidor, dentro de sendos directorios
llamados Mensaj er i a.
Se compila el archivo Ser vi dor Eco. j ava en el anfitrin servidor.
Se compila el archivo Cl i ent eEco. j ava en el anfitrin cliente.
Se ejecuta el servicio de nombres en un anfitrin (puede ser distinto
de los dos anteriores).
Se arranca la aplicacin servidor en el anfitrin servidor mediante
j ava Ser vi dor Eco ORBI ni t i al Host nombr emaqui na
JERARQUA DE CLASES DEL CLIENTE
abst r act publ i c cl ass EcoHel per
{
pr i vat e st at i c St r i ng _i d =
" I DL: Mensaj er i a/ Eco: 1. 0" ;
publ i c st at i c voi d i nser t
( or g. omg. CORBA. Any a, Mensaj er i a. Eco t hat )
. . .
_EcoStub
[Link]
Interface
Eco
EcoHelper
[Link]
implements
extends
extends
ClienteEco
publ i c cl ass Cl i ent eEco {
publ i c st at i c voi d mai n( St r i ng
ar gs[ ] ) {
t r y {/ / Se cr ea y se
i ni ci al i za el ORB.
ORB or b = ORB. i ni t ( ar gs, nul l ) ;
(Los mtodos definidos en la
interfaz Eco se implementan
en esta clase)
extends
usa
usa
abst r act publ i c cl ass EcoHel per
{
pr i vat e st at i c St r i ng _i d =
" I DL: Mensaj er i a/ Eco: 1. 0" ;
publ i c st at i c voi d i nser t
( or g. omg. CORBA. Any a, Mensaj er i a. Eco t hat )
. . .
_EcoStub
[Link]
Interface
Eco
EcoHelper
[Link]
implements
extends
extends
ClienteEco
publ i c cl ass Cl i ent eEco {
publ i c st at i c voi d mai n( St r i ng
ar gs[ ] ) {
t r y {/ / Se cr ea y se
i ni ci al i za el ORB.
ORB or b = ORB. i ni t ( ar gs, nul l ) ;
ClienteEco
publ i c cl ass Cl i ent eEco {
publ i c st at i c voi d mai n( St r i ng
ar gs[ ] ) {
t r y {/ / Se cr ea y se
i ni ci al i za el ORB.
ORB or b = ORB. i ni t ( ar gs, nul l ) ;
(Los mtodos definidos en la
interfaz Eco se implementan
en esta clase)
extends
usa
usa
Miguel ngel Abin Julio 2004
Espacio
en blanco
Espacio
en blanco
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 300/313 -
ORBI ni t i al Por t numpuer t o.
Se arranca la aplicacin cliente en el anfitrin cliente mediante j ava
Cl i ent eEco ORBI ni t i al Host nombr emaqui na ORBI ni t i al Por t
numpuer t o.
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 ( EcoI mp) 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 i dl j (al usar f al l , considero que quiero generar los archivos para el
servidor y el cliente):
i dl j f al l i nt er f azI DL. i dl
i dl j f al l Ti e i nt er f azI DL. i dl
La segunda ejecucin de i dl j generar un archivo de tipo
i nt er f azI DLPOATi e. j ava.
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),
ser vi ci ochat . i dl debe compilarse as:
i dl j f al l ser vi ci ochat . i dl
i dl j f al l Ti e ser vi ci ochat . i dl
Espacio en blanco
[Link]
Miguel ngel Abin, Julio 2004 - 301/313 -
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
JERARQUA DE CLASES EN EL LADO DEL
SERVIDOR
Eco
EcoPOA
EcoOperations
EcoPOATie
EcoImpl EcoTieImpl
implements
delega
extends
implements
extends
extends
Modelo de delegacin o Tie
Modelo de herencia
Eco
Archivo IDL
escrito por
el usuario
Interfaces
generados
Clases Java
escritas por
el usuario
Clases
Java
generadas
Miguel ngel Abin Julio 2004
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 302/313 -
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:
t r y {
ser vi dor . r egi st r ar Usuar i o( t i e. _t hi s( ) ) ;
}
cat ch ( Except i on e) {
Syst em. out . pr i nt l n( " Er r or al i nt ent ar r egi st r ar el usuar i o" ) ;
e. pr i nt St ackTr ace( ) ;
}
La llamada del servidor al cliente se produce en
publ i c synchr oni zed voi d envi ar ATodos( Cl i ent eChat usuar i o,
St r i ng t ext o) {
/ / Nombr e por def ect o de l os usuar i os no r egi st r ados: " Anni mo"
St r i ng nombr eUsuar i o = " " ;
t r y {
nombr eUsuar i o = usuar i o. get I dent i f i cador ( ) ;
i f ( nombr eUsuar i o. equal s( " " ) )
nombr eUsuar i o = " Anoni mo" ;
I t er at or i t = usuar i os. i t er at or ( ) ;
Cl i ent eChat t mp =nul l ;
whi l e ( i t . hasNext ( ) ) {
t mp = ( Cl i ent eChat ) i t . next ( ) ;
t r y {
/ / No env a el mensaj e a aquel usuar i o que l o ha envi ado.
i f ( ! ( t mp. equal s( usuar i o) ) )
t mp. envi ar ( nombr eUsuar i o + " : " + t ext o) ;
}
cat ch ( Except i on e1) {
/ / Si hay pr obl emas al envi ar el t ext o a un
/ / usuar i o se l e bor r a de l a l i st a de
/ / usuar i os act i vos.
i t . r emove( ) ;
} / / f i n del t r y- cat ch i nt er no
}
}
cat ch ( Except i on e2) {
Syst em. out . pr i nt l n( " Er r or desconoci do. " ) ;
e2. pr i nt St ackTr ace( ) ;
}
}
Retrollamada
Envio al servidor de una referencia a
s mismo
[Link]
Miguel ngel Abin, Julio 2004 - 303/313 -
module serviciochat {
interface ClienteChat;
interface ServidorChat {
// El mtodo registrarUsuario registra a un usuario en el servicio de chat.
void registrarUsuario(in ClienteChat ch);
// El mtodo enviarATodos enva un texto a todos los usuarios en activo del chat.
void enviarATodos(in ClienteChat ch, in string texto);
};
interface ClienteChat {
// El mtodo getIdentificador devuelve el identificador del cliente.
string getIdentificador();
// El mtodo enviar enva un texto a un cliente (no a todos).
void enviar(in string texto);
};
};
import serviciochat.*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link];
import [Link].*;
// IMPORTANTE: SLO FUNCIONAR CON J2SE 1.4 O SUPERIOR
/*
*
* ServidorChatImpl es una implementacin Java de [Link].
* Debe ejecutarse tras activar tnameserv.
*/
public class ServidorChatImpl extends ServidorChatPOA {
private ORB orb;
private List usuarios = new ArrayList(); // Lista con los usuarios.
/*
* Crea un objeto ORB.
*/
Ejemplo 20a: [Link]
Ejemplo 20b: [Link]
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 304/313 -
public void setORB(ORB orb) {
[Link] = orb;
}
/*
* Registra un usuario en el chat. Es necesario que est sincronizado para
* evitar situaciones como que dos usuarios se registren a la vez.
*/
public synchronized void registrarUsuario(ClienteChat usuario) {
[Link]("Bienvenido: " + usuario);
[Link](usuario);
}
/*
* Enva el texto del argumento a todos los clientes en activo.
*
*/
public synchronized void enviarATodos(ClienteChat usuario, String texto) {
// Nombre por defecto de los usuarios no registrados: "Annimo"
String nombreUsuario = "";
try {
nombreUsuario = [Link]();
if ( [Link]("") )
nombreUsuario = "Anonimo";
Iterator it = [Link]();
ClienteChat tmp =null;
while ([Link]()) {
tmp = (ClienteChat) [Link]();
try { // No enva el mensaje a aquel usuario que lo ha enviado.
if ( !([Link](usuario)) )
[Link](nombreUsuario + ": " + texto);
}
catch (Exception e1) {
// Si hay problemas al enviar el texto a un usuario se le
// borra de la lista de usuarios activos.
[Link]();
} // fin del try-catch interno.
}
}
catch (Exception e2) {
[Link]("Error desconocido.");
[Link]();
}
}
// Se crea y arranca el servidor, registrndolo en el servicio de nombres de CORBA.
// El argumento del main es la URL del servidor CORBA. Si no se especifica ninguna,
// se asume que es localhost (el equipo local).
public static void main(String args[]) {
try {
ORB orb = [Link](args, null);
ServidorChatImpl sci = new ServidorChatImpl();
ServidorChat ref = sci._this(orb);
[Link](orb);
POA POAraiz = [Link](orb.resolve_initial_references("RootPOA"));
POAManager poaMgr = POAraiz.the_POAManager();
[Link]
Miguel ngel Abin, Julio 2004 - 305/313 -
NamingContextExt nc =
[Link](orb.resolve_initial_references("NameService"));
NameComponent [] nombreComponente = new NameComponent[1];
nombreComponente[0] = new NameComponent("miChat", "");
[Link](nombreComponente, ref);
[Link]();
[Link]("Se ha arrancado el servidor CORBA de chat.");
[Link]();
}
catch (Exception e) {
[Link]("Error al intentar arrancar el servidor.");
[Link]();
}
}
}
import serviciochat.*;
import [Link].*;
import [Link].*;
import [Link];
import [Link].*;
import [Link];
import [Link].*;
import [Link].*;
import [Link].*;
// IMPORTANTE: SLO FUNCIONAR CON J2SE 1.4 O SUPERIOR
/*
*
* Cliente del chat con interfaz grfica.
* Debe ejecutarse tras ejecutar ServidorChatImpl.
* ClienteChatOperations es generada automticamente por idlj -fall.
*/
public class ClienteGraficoChat extends JFrame implements ClienteChatOperations {
private ClienteChatPOATie tie = null;
private static ORB orb = null;
private ClienteChat cliente = null;
private ServidorChat servidor = null;
private String nombreUsuario = "Anonimo";
// Parte grfica.
private JPanel panel1 = new JPanel();
private JPanel panel2= new JPanel();
private JTextArea areaTexto = new JTextArea("", 25, 35);
private JTextField campoTexto = new JTextField(25);
Ejemplo 20c: [Link]
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 306/313 -
private JButton enviarTexto = new JButton("Enviar");
private JButton registrar = new JButton("Registrarse");
// Constructor
public ClienteGraficoChat() {
dibujar();
try {
tie = new ClienteChatPOATie(this);
cliente = tie._this(orb);
POA POAraiz = [Link](orb.resolve_initial_references("RootPOA"));
POAManager poaMgr = POAraiz.the_POAManager();
[Link]();
NamingContextExt nc =
[Link](orb.resolve_initial_references("NameService"));
servidor= [Link]([Link](nc.to_name("miChat")));
}
catch(Exception e) {
[Link]();
}
// Cdigo de manejo de eventos de la interfaz grfica. Se usan clases internas.
[Link](new ActionListener() {
public void actionPerformed(ActionEvent evento) {
setIdentificador([Link]());
[Link]("");
}
});
[Link](new ActionListener() {
public void actionPerformed(ActionEvent evento) {
try {
[Link](cliente, [Link]());
[Link]("");
}
catch(Exception e) {
[Link]("Problema fatal al enviar texto a los usuarios.");
[Link]();
}
}
});
// Salida del chat.
addWindowListener( new WindowAdapter() {
public void windowClosing(WindowEvent event) {
[Link](0);
}
});
try {
[Link](tie._this());
}
catch (Exception e) {
[Link]("Error al intentar registrar el usuario.");
[Link]();
}
}
[Link]
Miguel ngel Abin, Julio 2004 - 307/313 -
public synchronized void setIdentificador(String nombreUsuario) {
[Link] = nombreUsuario;
}
public String getIdentificador() {
return nombreUsuario;
}
public void enviar(String texto) {
[Link](texto + "\n");
}
public void dibujar() {
setTitle(" Un chat con CORBA. Miguel ngel Abin Julio 2004 ");
Container contenedor = getContentPane();
[Link](new BorderLayout());
[Link]("South", panel1);
[Link]("North", panel2);
[Link]("Center", areaTexto);
[Link](registrar);
[Link](campoTexto);
[Link](enviarTexto);
[Link](false);
[Link]();
show();
}
// Punto de entrada en el cliente grfico del chat.
public static void main(String args[]) {
orb = [Link](args, null);
ClienteGraficoChat cliente = new ClienteGraficoChat();
}
}
La compilacin IDL de la aplicacin del chat se muestra en la figura siguiente.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 308/313 -
Figura 138. Compilacin IDL del ejemplo 20. Distribucin de la aplicacin
CORBA del ejemplo 20. Tiene validez general para las aplicaciones CORBA
escritas en Java que usen POA y el modelo de delegacin. Si se desea generar
todos los archivos de una sola vez hay que ejecutar idlj fall [Link] y,
luego, idlj fallTie [Link]
COMPILACIN CON EL IDL DE JAVA
idlj
[Link]
_ClienteChatStub.java
[Link] [Link]
[Link] [Link]
Lado del
cliente
Lado del
servidor
Adaptadores del
cliente
Esqueletos de
implementacin
Con POA (JS2E 1.4
o superior) y el
modelo de delegacin
[Link]
[Link]
[Link]
Id
lj
f
c
lie
n
t
M
e
n
s
a
je
r
i
a
.id
l
Id
lj
f
s
e
r
v
e
r
s
e
r
v
ic
io
c
h
a
t
.id
l
M
i
g
u
e
l
n
g
e
l
A
b
i
n
J
u
l
i
o
2
0
0
4
Id
lj
f
s
e
r
v
e
r
T
ie
s
e
r
v
ic
i o
c
h
a
t
.
id
l
[Link]
[Link]
[Link]
[Link]
[Link]
_ServidorChatStub.java
[Link] [Link]
[Link]
Miguel ngel Abin, Julio 2004 - 309/313 -
Figura 139. El chat hecho con Java y CORBA
En este caso, como hay retrollamadas (callbacks), los papeles de servidor y
cliente cambian durante la ejecucin de la aplicacin de chat. Puede hacerse la
compilacin que muestra la figura 138 y luego mover los archivos que faltan para que el
cliente se comporte como servidor, y viceversa; pero es mucho ms cmodo compilar
con las opciones f al l y f al l Ti e. En este caso, el proceso de distribucin seguira
los siguientes pasos:
Se compila el archivo ser vi ci ochat . i dl con i dl j f al l ser vi ci ochat . i dl
y, luego, con i dl j f al l Ti e ser vi ci ochat . i dl . Dentro del directorio
ser vi ci ochat aparecern los archivos _Cl i ent eChat St ub. j ava,
_Ser vi dor Chat St ub. j ava, Cl i ent eChat Hol der . j ava,
Cl i ent eChat Hel per . j ava, Ser vi dor Chat Hol der . j ava,
Ser vi dor Chat Hel per . j ava, Cl i ent eChat . j ava, Cl i ent eChat POA. j ava,
Cl i ent eChat Oper at i ons. j ava, Cl i ent eChat POATi e. j ava,
Ser vi dor Chat . j ava, Ser vi dor Chat POA. j ava,
Ser vi dor Chat Oper at i ons. j ava y Ser vi dor Chat POATi e. j ava.
Se compilan todos los archivos anteriores.
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 310/313 -
Los archivos . cl ass generados en el paso anterior se copian en el
anfitrin del cliente y del servidor, dentro de sendos directorios llamados
Mensaj er i a.
Se compila el archivo Ser vi dor Chat I mpl . j ava en el anfitrin servidor.
Se compila el archivo Cl i ent eGr af i coChat . j ava en el anfitrin cliente.
Se ejecuta el servicio de nombres en un anfitrin (puede ser distinto a los
dos anteriores).
Se arranca la aplicacin servidor en el anfitrin servidor mediante java
Ser vi dor Chat I mpl ORBI ni t i al Host nombr emaqui na
ORBI ni t i al Por t numpuer t o.
Si el servicio de nombres se ejecuta en la misma mquina que
Ser vi dor Chat I mpl , no se necesita usar ORBI ni t i al Host . Asimismo,
si el puerto TCP usado para el servicio de nombres es el estndar (900),
tampoco se necesita usar ORBI ni t i al Por t .
Se arranca la aplicacin cliente en el anfitrin cliente mediante j ava
Cl i ent eGr af i coChat ORBI ni t i al Host nombr emaqui na
ORBI ni t i al Por t numpuer t o.
Si el servicio de nombres se ejecuta en la misma mquina que
Cl i ent eGr af i coChat , no se necesita usar ORBI ni t i al Host .
Asimismo, si el puerto TCP usado para el servicio de nombres es el
estndar (900), tampoco se necesita usar ORBI ni t i al Por t .
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.
Espacio en blanco
Espacio en blanco
[Link]
Miguel ngel Abin, Julio 2004 - 311/313 -
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.
DISTRIBUCIN DE UNA APLICACIN
CORBA CON CLIENTES DE TIPO APPLET
IIOP
ORB
Applet
Navegador web
MVJ
Servidor
web
Archivos
de clases
Java
Servidor de
aplicaciones
IIOP
ORB
IIOP
ORB
Anfitrin
Nota: el servidor web o HTTP podra estar en un segundo anfitrin
Miguel ngel Abin Julio 2004
P
u
e
r
t
o
Java y las redes. Introduccin a las redes, a [Link], [Link], [Link], [Link], a RMI y a CORBA
Miguel ngel Abin, Julio 2004 - 312/313 -
Figura 141. Cdigo para usar applets en el lado del cliente como medio de
distribucin de las aplicaciones CORBA escritas en Java
FIN DE LA PRIMERA PARTE
CDIGO PARA USAR APPLETS EN EL
LADO DEL CLIENTE
<APPLET CODE=[Link] ARCHIVE=[Link]
WIDHT=400 HEIGHT=300>
<PARAM NAME=referencia
VALUE=IOR:>
</APPLET>
<APPLET CODE=[Link] ARCHIVE=[Link]
WIDHT=400 HEIGHT=300>
<PARAM NAME=referencia
VALUE=IOR:>
</APPLET>
Cdigo para el applet en la pgina web
ORB orb = [Link](this, new [Link]());
String referencia = getParameter(referencia);
[Link] objeto = orb.string_to_object(referencia);
X x = [Link](objeto);
ORB orb = [Link](this, new [Link]());
String referencia = getParameter(referencia);
[Link] objeto = orb.string_to_object(referencia);
X x = [Link](objeto);
Cdigo para el cliente CORBA
Miguel ngel Abin Julio 2004
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 [Link]
[Link]
Miguel ngel Abin, Julio 2004 - 313/313 -
Nota biogrfica del Autor: Miguel ngel Abin es licenciado en Ciencias
Fsicas por la U. de Valencia y obtuvo la suficiencia investigadora dentro del Dpto.
Fsica Aplicada de la U.V con una tesina acerca de relatividad general y
electromagnetismo. Adems, ha realizado diversos cursos de postgrado sobre
bases de datos, lenguajes de programacin Web, sistemas Unix, comercio
electrnico, firma electrnica, UML y Java. Ha colaborado en diversos programas
de investigacin TIC relacionados con el estudio de fibras pticas y cristales
fotnicos, ha obtenido becas de investigacin del IMPIVA y de la Universidad
Politcnica de Valencia y ha publicado diversos artculos en el IEEE Transactions
on Microwave Theory and Techniques relacionados con el anlisis de guas de
onda inhomogneas y guas de onda elpticas.
En el mbito laboral ha trabajado como gestor de carteras y asesor fiscal para
una agencia de bolsa y actualmente trabaja en el Laboratorio del Mueble Acabado
de AIDIMA (Instituto Tecnolgico del Mueble y Afines), ubicado en Paterna
(Valencia), en tareas de normalizacin y certificacin, traduccin e interpretacin y
asesoramiento tcnico. En dicho centro se estn desarrollando proyectos europeos
de comercio electrnico B2B para la industria del mueble basados en Java y XML
(ms informacin en [Link]). Ha impartido formacin en calidad,
normalizacin y programacin para ELKEDE (Grecia), CETEBA (Brasil) y CETIBA
(Tnez), entre otros.
ltimamente, aparte de asesorar tcnica y financieramente a diversas
empresas de la Comunidad Valenciana, es investigador en los proyectos INTEROP
y ATHENA del Sexto Programa Marco de la Comisin Europea, que pretenden
marcar las pautas para tecnologas de la informacin en la prxima dcada y
asegurar el liderazgo de Europa en las tecnologas de la sociedad del
conocimiento. Ambos proyectos tienen como fin la interoperabilidad del software
(estudian tecnologas como J2EE, .Net y CORBA, servicios web, tecnologas
orientadas a aspectos, ontologas, etc.), y en ellos participan empresas como IBM
U.K., COMPUTAS, SIEMENS, FIAT, TXT, GRAISOFT, SAP, EADS, adems de
numerosas universidades europeas y centros de investigacin en ingeniera del
software.
Sus intereses actuales son el diseo asistido por ordenador de guas de
ondas y cristales fotnicos, la evolucin de la programacin orientada a objetos,
Java, UEML, el intercambio electrnico de datos, el surrealismo y Pars, siempre
Pars.