Mecanismos de comunicación

Índice
- Introducción
- Objetivos
- 1.Paradigmas de comunicación
- 2.Mecanismos de comunicación
- 2.1.Codificación de datos
- 2.2.Formatos de codificación de datos
- 2.3.Mecanismos de invocación remota
- 2.3.1.Servicios de nombres
- 2.3.2.Conectores (sockets)
- 2.3.3.Protocolos RPC
- 2.3.4.Localización de servicios
- 2.3.5.REST
- Resumen
- Bibliografía
Introducción
Objetivos
-
Conocer los diferentes paradigmas de comunicación entre procesos, aplicaciones u objetos.
-
Conocer la problemática de la transmisión de información de datos y las diferentes formas de codificar la información. Diferenciar la codificación binaria de la textual.
-
Conocer el funcionamiento de los mecanismos de comunicación con conectores (sockets).
-
Conocer la invocación remota de procesos y objetos. Saber los principales protocolos que la implementan así como las características principales de los servicios web.
1.Paradigmas de comunicación
-
Comunicación síncrona (o sincrónica): es el intercambio de información entre procesos en tiempo real y requiere simultaneidad de los procesos.
-
Comunicación asíncrona (o asincrónica): es aquella comunicación que se establece entre dos o más procesos de manera diferida en el tiempo, es decir, cuando no existe simultaneidad.

1.1.Paso de mensajes
-
Primitivas de paso de mensajes punto a punto. Desde las típicas operaciones de transmisión y recepción (2) , hasta variaciones especializadas de estas.
-
Primitivas de sincronización. La más habitual es la primitiva de barrera, que implementa un bloqueo en todas (o parte de) las tareas de la aplicación paralela.
-
Primitivas de comunicaciones colectivas. Varias tareas participan en un intercambio de mensajes entre ellas.
-
Creación estática (y/o dinámica) de grupos de tareas dentro de la aplicación, para restringir el ámbito de aplicación de algunas primitivas. Permite separar conceptualmente unas interacciones de las otras dentro de la aplicación.
-
Si el envío será fiable.
-
Si el envío garantizará el orden de la información transmitida.
-
Si los mensajes se envían uno a uno (unicast o de igual a igual), uno a muchos (multicasting o broadcasting ) o muchos a uno (cliente-servidor).
-
Si la comunicación es síncrona o asíncrona.

1.2.Memoria compartida

1.3.Invocación remota
-
que el método no se haya ejecutado remotamente porque ha fallado la llamada antes de invocar al método.
-
que haya fallado la ejecución del método.
-
que haya fallado la respuesta con los resultados de la ejecución del método.

-
El proceso u objeto cliente.
-
La interfaz del método remoto que es local al cliente y que contiene la firma de los métodos que ofrece el objeto remoto. Este componente se denomina generalmente stub.
-
El proceso u objeto remoto.
-
La interfaz e implementación del método remoto que es contactada por el stub y que después, ya de forma local, invoca el método del objeto remoto. Generalmente, se le denomina skeleton.

1.4.Publicación suscripción

1.5.Modelo de programación por eventos

2.Mecanismos de comunicación
2.1.Codificación de datos
2.1.1.La problemática de la codificación de datos
-
Tipo base: entero, real, carácter, enumerado.
-
Tipos planos: agregaciones, estructuras, vectores (relleno).
-
Tipos complejos: con punteros, por ejemplo, árbol (que se ha “de allanar”, etc.).
-
Little-endian: el octeto menos significativo se guarda en la dirección de memoria menor, que será la dirección del dato.
-
Big-endian: el octeto más significativo se guarda en la dirección de memoria menor, que será la dirección del dato.

-
Delimitación de elementos: cómo marcar el final o el inicio de un elemento en una secuencia.
-
Tipo de información (e interpretación): cómo expresar qué dato es cada componente de una colección: sobre todo si omitimos alguno al enviarlos o si su orden es variable.
-
Estructuración (pertenencia a un conjunto): cómo indicar que cierto dato pertenece a una agrupación.
-
“Longitud fija”: compacta pero inflexible. Sólo parece recomendable para datos de longitud siempre fija, puesto que en datos de longitud variable, o se desaprovecha mucho espacio o se corre el riesgo de no poder expresar algún dato, y no habría manera de arreglarlo al omitir la longitud; es un convenio entre los participantes en una comunicación: todos tendrían que acordar el cambio para hacer ajustes.
-
“Por longitud”: mejora el anterior, pero se tiene que conocer la longitud desde el principio. Esto puede ser un inconveniente para el productor de la información, puesto que podría ser necesario tener que generar todos los datos para poder calcular la longitud y enviar este primer dato. En cambio, el receptor sabe primero cuánto le ocupará el dato y después puede leer exactamente los octetos indicados sin dificultad.
-
“Por longitud a fragmentos”: se usa cuando la longitud total del dato se ignora desde el comienzo. Se pueden ir enviando trozos de datos tal como se van produciendo, hecho que permite que los datos se empiecen a emitir antes, y que el productor pueda ahorrar memoria dedicada a mantener datos preparados para la remisión.
-
“Delimitada”: en lugar de calcular la longitud, se reserva un símbolo para separar datos. Si el delimitador aparece entre los datos, se tiene que definir una manera de “ignorarlo”.
2.2.Formatos de codificación de datos
-
XML: se usa en el XML-RPC, el SOAP.
-
JSON: se usa en aplicaciones AJAX.
-
External data representation (XDR): se usa en el RPC (v2; ONC-RPC).
-
Abstract syntax notation (ASN.1): se usa en varios protocolos, como por ejemplo: X.509, el SNMP.
-
Network data representation (NDR): se usa en el DCOM, el DCE-RPC.
-
Common data representation (CDR): se usa en el CORBA (GIOP, IIOP).
-
Java remote messaging protocol (JRMP): se usa para comunicar máquinas virtuales Java (Java-RMI).
2.2.1.Codificación textual con XML
<?xml version="1.0"?> <methodCall> <methodName>buscar</methodName> <params> <param> <value> <struct> <member> <name>nombre</name> <value>Juan</value> </member> <member> <name>edad</name> <value><i4>42</i4></value> </member> </struct> </value> </param> </params> </methodCall> </methodCall>
-
Control sobre los datos: longitud –length– (número de caracteres de la cadena, binario), maxlength (máxima longitud de la cadena, binario), lexical representation (representaciones posibles, por ejemplo, DD-MM-AAAA), enumeration, maxInclusive (máximo posible), maxExclusive (máximo exclusivo), minInclusive (mínimo posible), minExclusive (mínimo exclusivo), precision (número de dígitos), scale (dígitos con parte decimal), encoding (binario).
-
Control sobre el refinamiento: mecanismos de herencia y extensión.
-
Control sobre la extensibilidad: abierta, refinable, cerrada.
2.2.2.Codificación textual con JSON
--> {"method": "postMessage", "params": ["Hello all!"], "id": 99} <-- {"result": 1, "error": null, "id": 99}]]]
2.2.3.Codificación binaria con XDR

2.2.4.Codificación binaria con ASN.1
-
Formato: {etiqueta, longitud, valor}.
-
Usa etiquetas de tipos, 8 bits, multiocteto.
-
Longitud en octetos del valor: si < 127 ocupa 1 octeto.
-
Valor: por ejemplo, entero (integer) complemento a 2, big-endian.
-
BER: basic ...; no muy eficientes, mucha redundancia, admite extensión.
-
DER: distinguished ...; no tiene opciones (por seguridad); longitud codificación definida.
-
CER: canonical ...; no tiene opciones (por seguridad); longitud codificación no definida.
-
PER: packet ...; muy compactos, poco extensible.
-
LWER: light weight; casi estructura interna, codificación/descodificación rápida.


Nombre |
Binario |
Legible |
---|---|---|
ASN.1 |
Sí (BER, CER, DER, PER, ECN) |
Sí (XER, vía ECN) |
BSON |
Sí |
No |
Comma-separated values (CSV) |
No |
Sí |
JSON |
No, pero véase BSON |
Sí |
Netstrings |
Sí |
Sí |
OGDL |
Si (Esquema 1.0 binario) |
Sí |
Property list |
Sí |
Sí |
Protocol buffers |
Sí |
Parcial |
S-expressions |
No |
Sí |
Structured data eXchange Formats |
Sí |
No |
Thrift |
Sí |
Parcial |
eXternal Data Representation |
Sí |
No |
XML |
Parcial (XML binario) |
Sí |
YAML |
No |
Sí |
2.3.Mecanismos de invocación remota
-
Arquitectura (formato: medida y organización de datos).
-
Lenguaje de programación (afecta a la forma de invocar y trasladar argumentos).
-
Entorno a ejecución (sistema operativo).
2.3.1.Servicios de nombres

(2) El cliente busca el objeto remoto en el registro.
(3) El cliente invoca el método en el objeto remoto.
2.3.2.Conectores (sockets)
-
socket(): crea un conector de un cierto tipo.
-
bind(): usado en el lado del servidor para asociar el conector a una dirección y un puerto.
-
listen(): utilizado en la banda servidor para poner el conector en estado de LISTEN.
-
connect(): usado en el cliente para conectarse a una dirección y puerto del servidor. Al finalizar la llamada, se establece la conexión.
-
accept(): utilizado en el servidor para aceptar una conexión.
-
send() y recv(), o write() y read(), o recvfrom() y sendto(): se usan para recibir y leer datos de un conector.
-
close(): se cierra la conexión (en caso de ser TCP). Se liberan los recursos.
-
gethostbyname() y gethostbyaddr(): se usan para resolver nombres y direcciones.
-
select(): se usa para seleccionar los conectores que están preparados para lectura/escritura o con errores.
-
piojo(): se usa para verificar el estado del conector.


2.3.3.Protocolos RPC
RMI
-
Proporcionar invocación remota de objetos que se encuentran en VM diferentes.
-
Permitir llamadas a los servidores desde los applets.
-
Integrar el modelo de objetos distribuidos en el lenguaje Java de una manera natural, conservando en la medida de lo posible la semántica de los objetos Java.
-
Hacer tan simple como sea posible la escritura de aplicaciones distribuidas.
-
Preservar la seguridad proporcionada por el entorno Java.
-
Proporcionar varias semánticas para las referencias de los objetos remotos (persistentes, no persistentes y de “activación retrasada”).
public class HelloImpl extends UnicastRemoteObject implements Hello { public HelloImpl() throws RemoteException { super(); } public String sayHello() { return "Hola amigos!"; } public static void main(String args[]) { if (System.getSecurityManager() == null) { // Crear e instalar un gestor de seguridad System.setSecurityManager(new RMISecurityManager()); } try { HelloImpl obj = new HelloImpl(); // Asociar esta instancia al nombre "HelloServer" Naming.rebind("//myhost/HelloServer", obj); System.out.println("HelloServer asociado al registro"); } catch (Exception y) {}{ System.out.println("Error" + e.getMessage()); } } }
try { obj = (Hello)Naming.lookup("/server/HelloServer"); message = obj.sayHello(); } catch (Exception y) { System.out.println("Excepción:" + e.getMessage()); }
try { obj = (Hello)Naming.lookup("/server/HelloServer"); message = obj.sayHello(); } catch (Exception y) { System.out.println("Excepción:" + e.getMessage()); }
SUN-RPC
/* File: C.c - cliente del FileReadWrite service. */ #include <stdio.h> #include <rpc/rpc.h> #include "FileReadWrite .h" main(int argc, char ** argv) { CLIENT *clientHandle; char *serverName = "coffee"; readargs a; Data *data; /* crea el socket y obtiene un apuntador al servicio*/ clientHandle= clnt_create(serverName, FILEREADWRITE, VERSION, "udp"); if (clientHandle==NULL){ clnt_pcreateerror(serverName); /* no podemos contactar servidor */ exit(1); } a.f = 10; a.position = 100; a.length = 1000; data = read_2(&a, clientHandle);/* llamamos al read remoto */ ... clnt_destroy(clientHandle); /* cierra el socket */ }
/* File S.c - servidor del FileReadWrite service */ #include <stdio.h> #include <rpc/rpc.h> #include"FileReadWrite.h" void * write_2(writeargs *a) { /* do the writing to the file */ } Data * read_2(readargs * a) { static Data result; /* tiene que ser static */ result.buffer = ... /* leemos el fichero */ result.length = ... /* cantidad leída del fichero */ return &result; }
-
Utiliza el XDR como lenguaje de codificación.
-
No garantiza la semántica “como máximo una vez”.
-
Funciona sobre el UDP, permite la difusión (32) .
-
Selección: el UDP selecciona el proceso, el RPC, el procedimiento.
-
Port mapper (puerto 111): núm. de programa→puerto.
-
Mensajes limitados a un tamaño de como máximo IP (32 kb).
-
Autenticación en cada petición.
-
Servidor sin estado.
-
Si la retransmisión llega al servidor mientras la respuesta viaja hacia el cliente, no nota el duplicado; sí que lo nota “durante proceso”, y lo elimina. Esta memoria de corto plazo no es problema en una red local.
XML-RPC o invocación sobre web (HTTP)
-> x.buscar({'nombre':'juan','edad':42}) <- {'id': 123456}
<?xml version="1.0"?> <methodCall> <methodName>buscar</methodName> <params> <param> <value> <struct> <member> <name>nombre</name> <value>juan</value> </member> <member> <name>edad</name> <value><i4>42</i4><value> </member> </struct> </value> </param> </params> </methodCall> </html>
-
Un protocolo de petición/respuesta que se pueda comunicar con un proceso en un servidor: el HTTP.
-
Un formato de representación de los datos que se intercambian en una invocación: el XML puede ser la base para construirlo, aunque otros como el JSON también se pueden utilizar.
-
Una interfaz de programación para invocar servicios de las aplicaciones web. El XML-RPC define un conjunto de tipo limitado al hecho de que cada lenguaje tendrá que mapear sus tipos propios. Además, los tipos son etiquetas XML y no tipos predefinidos en el XML Schema. Es una aproximación muy sencilla para favorecer que su implementación también sea muy sencilla. Como consecuencia de esto, se han implementado bibliotecas XML-RPC en gran cantidad de los lenguajes de programación existentes.
<?xml version='1.0'?> <methodResponse> <params> <param> <value> <struct> <member> <name>id</name> <value><int>123456</int></value> </member> <member> <name>nombre_completo</name> <value>juan perez</value> </member> </struct> </value> </param> </params> </methodResponse>
SOAP
-
Un elemento envelope, que identifica el documento XML como mensaje SOAP.
-
Un elemento header, que contiene información de cabecera del mensaje.
-
Un elemento body, que contiene información sobre la llamada y la respuesta.
-
Un elemento fault, que contiene información de error y de estado.
<?xmlv version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Header> ... </soap:Header> <soap:Body> ... <soap:Fault> ... </soap:Fault> </soap:Body> </soap:Envelope>
soap:encodingStyle="URI"
<?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Header> <m:Trans xmlns:m="http://www.uoc.edu/transaction/" soap:mustUnderstand="1"> 234 </m:Trans> </soap:Header> ... ... </soap:Envelope>
<?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Header> <m:Trans xmlns:m="http://www.uoc.edu/transaction/" soap:actor="http://www.uoc.edu/appml/"> 234 </m:Trans> </soap:Header> ... ... </soap:Envelope>
soap:actor="URI"
<?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Body> <m:GetNotes xmlns:m="http://www.uoc.edu/notes"> <m:Item>Redes</m:Item> </m:GetNotes> </soap:Body> </soap:Envelope>
<?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Body> <m:GetNotesResponse xmlns:m="http://www.uoc.edu/notes"> <m:Nota>Notable</m:Nota> </m:GetNotesResponse> </soap:Body> </soap:Envelope>
Subelemento |
Descripción |
---|---|
<faultcode> |
Código para identificar el error. |
<faultstring> |
La explicación del error. |
<faultactor> |
Información sobre quién ha causado el error. |
<detail> |
Información específica de la aplicación. |
Error |
Descripción |
---|---|
VersionMismatch |
Se ha encontrado un namespace inválido en el elemento envelope. |
MustUnderstand |
No ha sido entendido un hijo del elemento header con el atributo mustUnderstand con valor 1. |
Cliente |
El mensaje está mal formado o el contenido es incorrecto. |
Server |
Ha habido algún error en el servidor, o el mensaje no ha podido ser procesado. |
public class Calculator { public int add(int y1, int y2) { return y1 + y2; } public int subtract(int y1, int y2) { return y1 - y2; } }
<wsdl:definitions targetNamespace="http://localhost:8080/axis/Calculator.jws"> <!-- WSDL created by Apache Axis version: 1.2RC3 Built on Feb 28, 2005 (10:15:14 EST) --> <wsdl:message name="subtractRequest"> <wsdl:part name="i1" type="xsd:int"/> <wsdl:part name="i2" type="xsd:int"/> </wsdl:message> <wsdl:message name="subtractResponse"> <wsdl:part name="subtractReturn" type="xsd:int"/> </wsdl:message> <wsdl:message name="addResponse"> <wsdl:part name="addReturn" type="xsd:int"/> </wsdl:message> <wsdl:message name="addRequest"> <wsdl:part name="i1" type="xsd:int"/> <wsdl:part name="i2" type="xsd:int"/> </wsdl:message> <wsdl:portType name="Calculator"> <wsdl:operation name="add" parameterOrder="i1 i2"> <wsdl:input message="impl:addRequest" name="addRequest"/> <wsdl:output message="impl:addResponse" name="addResponse"/> </wsdl:operation> <wsdl:operation name="subtract" parameterOrder="i1 i2"> <wsdl:input message="impl:subtractRequest" name="subtractRequest"/> <wsdl:output message="impl:subtractResponse" name="subtractResponse"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="CalculatorSoapBinding" type="impl:Calculator"> <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="add"> <wsdlsoap:operation soapAction=""/> <wsdl:input name="addRequest"> <wsdlsoap:body encodingStyle=http://schemas.xmlsoap.org/soap/encoding/ namespace="http://DefaultNamespace" use="encoded"/> </wsdl:input> <wsdl:output name="addResponse"> <wsdlsoap:body encodingStyle=http://schemas.xmlsoap.org/soap/encoding/ namespace="http://localhost:8080/axis/Calculator.jws" use="encoded"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="subtract"> <wsdlsoap:operation soapAction=""/> <wsdl:input name="subtractRequest"> <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://DefaultNamespace" use="encoded"/> </wsdl:input> <wsdl:output name="subtractResponse"> <wsdlsoap:body encodingStyle=http://schemas.xmlsoap.org/soap/encoding/ namespace="http://localhost:8080/axis/Calculator.jws" use="encoded"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="CalculatorService"> <wsdl:port binding="impl:CalculatorSoapBinding" name="Calculator"> <wsdlsoap:address location="http://localhost:8080/axis/Calculator.jws"/> </wsdl:port> </wsdl:service> </wsdl:definitions>

xsd:base64Binary byte[] xsd:boolean boolean xsd:byte byte xsd:dateTime java.util.Calendar xsd:decimal java.math.BigDecimal xsd:double double xsd:float float xsd:hexBinary byte[] xsd:int int xsd:integer java.math.BigInteger xsd:long long xsd:QName javax.xml.namespace.QName xsd:short short xsd:string java.lang.String
2.3.4.Localización de servicios
-
Un proveedor de servicio que publica su oferta de servicio en un registro de servicios.
-
Un registro de servicios que recoge ofertas y puede ser examinado por un consumidor de servicios.
-
Un consumidor de servicios que busca cierto servicio en un registro de servicios y, cuando lo encuentra, conecta (38) con el proveedor de servicio seleccionado para invocarle operaciones con SOAP.
2.3.5.REST
-
En la web los agentes de usuario interactúan con los recursos, y los recursos son todo aquello que puede ser denominado y representado. Cada recurso se puede resolver a través de una única interfaz (URI).
-
La interacción con los recursos (ubicados a través de su URI único) se realiza mediante una interfaz uniforme usando los “verbos” estándar de HTTP (GET, POST, PUT y DELETE). También es importante en la interacción la declaración del tipo del recurso, que es designado mediante el encabezamiento HTTP Content-Type (XHTML, XML, JPG, PNG y JSON son algunos tipos de medios conocidos).
-
Los recursos se describen a ellos mismos. Toda la información necesaria para procesar una solicitud de un recurso está dentro de la misma solicitud (que permite que los servicios sean sin estado).
-
Los recursos contienen vínculos a otros recursos (enlaces multimedia).

-
Almacenable en memorias caché (cacheable). Como una petición REST no deja de ser una petición HTTP sin estado, es fácilmente almacenable en las memorias caché que hay en la Red. Esto hace que el mecanismo favorezca la escalabilidad del sistema, dado que peticiones consecutivas sólo consultan una vez el servidor, para reducir así la carga del sistema.
-
Escalable. El hecho de que los mecanismos REST estén basados en HTTP, permite que hereden las propiedades de HTTP. Por lo tanto, REST es ampliamente escalable, y esta característica se ve favorecida por el hecho de que los recursos son autodescritos y, en consecuencia, no establecen dependencias ni requerimiento del mantenimiento de un estado.
-
Inalterable. Como REST utiliza los verbos de HTTP (GET, POST, PUT y DELETE), el protocolo no se puede alterar y mantiene así la simplicidad de su utilización.
-
Interoperable. El hecho de que los recursos se definan en un lenguaje independiente del código de las máquinas cliente y servidor, y que la comunicación se haga usando un protocolo estándar como es HTTP permite a diferentes tecnologías y arquitecturas de hardware utilizar este mecanismo de comunicación sin la necesidad de conocer las particularidades de cada extremo.
-
Simple. REST ofrece cuatro primitivas básicas que permiten interactuar con recursos descritos con URI. Cualquier conjunto de funcionalidades se puede desarrollar con estas herramientas, y convierte REST en un protocolo extremadamente sencillo.