Programando con RPC: Definiendo el servidor

Esta es la tercera parte de la serie de post sobre la programación con RPC, en este se implementará el funcionamiento del servidor, aunque parezca sencillo, y la verdad lo es, puede ser un poco complicado hacerlo debidamente ya que se debe tomar en cuenta aspectos como: uso adecuado de memoria, manejo de punteros y, en algunos casos, concurrencia. Como se comentaba en el post anterior el objetivo es hacer un servicio que retorne su información como proceso del sistema (nombre, usuario, id de proceso, etc).

Primero, no es obligatorio pero si recomendable, ejecutar el comando rpcgen con el parámetro -Ss:

$ rpcgen -Ss process.x

Esta orden hacé que el generador de código RPC cree una plantilla para empezar a implementar la función que hará el servidor, es decir, el procedimiento que sera llamado cuando sea requerido por el cliente. Algo como esto sera generado:

/*
 * This is sample code generated by rpcgen.
 * These are only templates and you can use them
 * as a guideline for developing your own functions.
 */

#include "process.h"

process_info *
get_process_info_1_svc(void *argp, struct svc_req *rqstp)
{
	static process_info  result;

	/*
	 * insert server code here
	 */

	return &result;
}

La función get_process_info_1_svc() define las acciones que serán tomadas del servidor, argp es el argumento de entrada, siempre en esta implementar de RPC la función toma solo un argumento de entrada por lo cual es necesario crear diferentes tipos de estructuras si se desea pasar mas de un argumento, también puede definirse mas de un solo parámetro o cambiar la forma de representar los datos pero estos son extensiones fuera del antiguo estándar pero mas intuitivos a la hora de implementar el cliente como el servidor. En este caso la función no toma argumentos pero aun así da el parámetro pero sin información útil. Para entregar la respuesta al cliente se usa el valor de retorno de la función. En este caso retornara una estructura process_info con los datos del proceso servidor.

Ahora se implementará la función de esta manera:

#include 
#include "process.h"

process_info *
get_process_info_1_svc(void *argp, struct svc_req *rqstp)
{
	static process_info  result;

	result.name = "process_server";
	result.pid = getpid();
	result.ppid = getppid();
	result.uid = getuid();
	result.gid = getgid();

	return &result;
}

Se muestra la función haciendo uso de las llamadas estándares de los sistemas UNIX para obtener la información del proceso. Ahora guardamos el código de implementación como process_server.c y ejecutamos el compilador para generar el ejecutable:

$ cc -o process_server process_server.c process_svc.c process_xdr.c

Una vez compilado podemos ejecutar el programa, pero no trabajara hasta que el cliente mande solicitudes, para ello en el siguiente post se implementara el programa cliente, el cual llamara al procedimiento del servidor y mostrara el resultado de esa información por la consola.

Anuncios

Programación con RPC (Remote Procedure Calls)

RPC (Remote Procedure Calls), o también conocido en español como Llamadas a Procedimiento Remoto es una tecnología de intercomunicación de procesos, que se diferencia de algunos otros como memoria compartida, manejo de hilos (threads) o sistemas multi-proceso (fork), ya que ejecuta código de una maquina remota y obtiene el resultado de esta y esta capacitado para funcionar sobre red, es decir, sirve para intercambiar información entre procesos de una misma o diferentes maquinas con procedimientos definidos para llevar a cabo una tarea en particular, como intercambio de archivos (NFS) o monitoreo de servidores.

RPC Diagram

Actualmente existen varias implementaciones o modelos de RPC los cuales cumplen con ciertas tareas o funciones especificas, las mas conocidas son:

  • ONC/RPC: Uno de los primeros protocolos RPC, creado por Sun Microsystems para sistemas basados en UNIX.
  • DCE/RPC: Protocolo RPC de Open Software Foundation.
  • RMI: Sistema de invocación de procedimientos para Java.
  • XML-RPC: Llamadas a procedimiento remoto usando XML vía HTTP.
  • JSON/HTTP: Llamadas a procedimientos por lenguaje de marcas JSON vía HTTP.
  • DCOM: Modelo de Objetos de Componentes Distribuidos de Microsoft.

Aparte de otras variantes privativas o de uso menor.

En este caso utilizaremos la implementación de Sun: ONC/RPC. Es uno de los mas usados en entornos basados en UNIX, a causa de su diseño simple pero potente, ya que el crear un servidor RPC es sencillo sin tomar en cuenta a la complejidad del trabajo que realizara. Aunque a causa de su simpleza de trabajo, no puede ser utilizados fácilmente en redes WAN o sistemas heterogéneos. Pero ello no lo hace malo para aprender los fundamentos de la ejecución de código remoto.

Antes de empezar el tutorial se tienen que descargar los programas y librerías necesarias para la compilación de los ejemplos. Se recomienda que sea sobre un sistema GNU/Linux o Mac OS X, si necesita usar Windows instalar el entorno Cygwin. Los requerimientos son:

  • Compilador de C, preferentemente GCC.
  • Generador de código RPC: rpcgen, Se incluye por defecto en los entornos de desarrollo UNIX. En Cygwin se instala como onc-rpc-devel.
  • Las librerías de desarrollo libtirpc (solo es necesario si el sistema no lo incluye por defecto como Cygwin).
  • Preferentemente dos maquinas para ejecutar el programa cliente y el servidor aparte.

En la siguiente parte se mostrara el archivo de interfaz de RPC para empezar a implementar un servicio de prueba: Obtener información del proceso servidor.