Comunicación entre procesos de igual a igual
(Fase 1).

Motivación

Queremos implementar un modelo de comunicación entre procesos de igual a igual (peer-to-peer, P2P). Seguramente recuerde el modo de trabajo de las aplicaciones al modo de N_a_p_ster. En ellas, un servidor central sirve como punto de contacto entre clientes particulares, que a la postre acaban poniéndose en contacto uno con otro para intercambiar datos.

P2P-1.jpg (15009 bytes)

La práctica se implementará en Perl y basándonos en el API de sockets básico. En consecuencia habrá que resolver ciertas cuestiones previas, derivadas del tipo de herramientas que estamos utilizando.

Modelos básicos y herramientas

P2P con sockets UDP

Cuando conectamos dos procesos al estilo P2P con sockets UDP las cosas son relativamente sencillas. Las operaciones básicas de envío y recepción (send, recv) son simétricas en cada uno de los procesos, y no hay una distinción clara entre el iniciador de la comunicación y el proceso que secunda la conversación. El la comunicación se sucede como una secuencia de mensajes que se envían de un socket a otro tanto por parte de un proceso como de otro.

Sin embargo, todos conocemos de algunos pequeños detalles de este tipo de comunicación, y que nos impulsan a utilizar sockets orientados a conexión (TCP) la mayoría de las veces.

P2P con sockets TCP

Al utilizar un mecanismo en el que, al menos al iniciar la conexión, uno de los procesos debe actuar como iniciador y otro como receptor de la conexión, debemos introducir ligeras modificaciones en la estructura de los proceso para poder plasmar el modelo P2P.

La aproximación más simple pasa por considerar que en el fondo cada proceso puede actuar como cliente y como servidor a la vez. En cada contingencia posible, el papel que juega cada uno dependerá de quién inicia el contacto con su proceso "par" (peer, parejo, o igual).

P2P-2.jpg (12463 bytes)

Si además tenemos en cuenta que el subproceso servidor de cada uno de ellos puede ser multi-hilo, la cosa se complica un poquitín, pero nada del otro mundo. Existen complicaciones, como no, aunque las estudiaremos más tarde:

Un detalle de interés es el procedimiento de desdoble del proceso "rojo" o "azul", parece razonable que el proceso padre sea el sub-proceso cliente, quizás porque resultaría más expresivo. En caso de que quisiere terminar el proceso "rojo", lo suyo es que la  indicación provenga desde el proceso padre, que en este caso sería la entidad activa (sub-proceso cliente).

Fase 1 del sistema

En esta fase tratamos de construir un programa que actue indistintamente como cliente o como servidor bajo un mecanismo de comunicación de sockets TCP. Este programa formará el esqueleto básico para construir cualquier otra práctica del estilo P2P con Perl.

A la hora de probar este esqueleto, lo habitual es que el proceso presente un "prompt" para que el programador pueda probar las diferentes funcionalidades del programa y poder depurar el código. Se suele implementar en forma de líneas que codifican listas de texto. Algunos mandatos que tenemos que implementar son, por ejemplo:

Proporcionamos un IP-destino y un Puerto-destino y un número (Apuntador1-local) con el que nos referiremos a la conexión en lo sucesivo.

Sirve para despedirnos.

Con el que enviamos una cadena de texto (Mensaje) (o lo que sea), mediante el Apuntador-local.

Implementación

La lectura de los mensajitos es un problema baladí, en Perl:

$linea = <SOCKET>;
chop $linea;
($Mandato, $Op1, $Op2, $Op3, $Op4) = split($linea, ':');

Cuidado: cuando escribimos en un socket una cadena de texto, ésta no se envía si no incluimos el caracter fin de línea '\n'; con que, cuidado.

Ojito: Hay que recordar que si queremos liberar el terminal y la conexión para que se puedan enviar y recibir asíncronamente mensajes, debemos desdoblar el proceso cliente en dos, uno que lea texto del terminal y lo envíe por el canal, y otro que reciba texto del canal y lo imprima al terminal.