rpc linux

6
RPC (Remote Procedure Call) Concepto de RPC En unix es posible tener en ejecución un programa en C con varias funciones que pueden ser llamadas desde otro programas. Estos otros programas pueden estar corriendo en otros ordenadores conectados en red. Supongamos, por ejemplo, que tenemos un ordenador muy potente en cálculo matemático y otro con un buen display para gráficos. Queremos hacer un programa con mucho cálculo y con unos gráficos "maravillosos". Ninguno de los dos ordenadores cumple con ambos requisitos. Una solución, utilizando RPC (Llamada a procedimientos remotos), consiste en programar las funciones matemáticas en el ordenador de cálculo y publicar dichas funciones. Estas funciones podrán ser llamadas por el ordenador gráfico, pero se ejecutarán en el ordenador de cálculo. Por otro lado, hacemos nuestros gráficos en el ordenador gráfico y cuando necesitemos algún cálculo, llamamos a las funciones del ordenador de cálculo. Al programa con las funciones se le llama "servidor". Al programa que llama a esas funciones se le llama "cliente". Normalmente el servidor está siempre corriendo y a la espera de que algún cliente llame a alguna de sus funciones.. Cuando el cliente llama a una función del servidor, la función se ejecuta en el servidor y el cliente detiene su ejecución hasta que el servidor termina. En el código del programa servidor básicamente hay que seguir los siguientes pasos: Codificar las funciones que van a ser llamadas siguiendo un determinado mecanismo. Informar al sistema operativo (unix) de un nombre, una versión y funciones que publica. Meterse en un bucle infinito esperando que alguien llame a alguna de sus funciones. Mientras que el programa cliente debe:

Upload: marijose-uz

Post on 29-Sep-2015

216 views

Category:

Documents


0 download

DESCRIPTION

Definición y características

TRANSCRIPT

RPC (Remote Procedure Call)Concepto de RPCEn unix es posible tener en ejecucin un programa en C con varias funciones que pueden ser llamadas desde otro programas. Estos otros programas pueden estar corriendo en otros ordenadores conectados en red.Supongamos, por ejemplo, que tenemos un ordenador muy potente en clculo matemtico y otro con un buen display para grficos. Queremos hacer un programa con mucho clculo y con unos grficos "maravillosos". Ninguno de los dos ordenadores cumple con ambos requisitos. Una solucin, utilizando RPC (Llamada a procedimientos remotos), consiste en programar las funciones matemticas en el ordenador de clculo y publicar dichas funciones. Estas funciones podrn ser llamadas por el ordenador grfico, pero se ejecutarn en el ordenador de clculo. Por otro lado, hacemos nuestros grficos en el ordenador grfico y cuando necesitemos algn clculo, llamamos a las funciones del ordenador de clculo.Al programa con las funciones se le llama "servidor". Al programa que llama a esas funciones se le llama "cliente". Normalmente el servidor est siempre corriendo y a la espera de que algn cliente llame a alguna de sus funciones.. Cuando el cliente llama a una funcin del servidor, la funcin se ejecuta en el servidor y el cliente detiene su ejecucin hasta que el servidor termina.En el cdigo del programa servidor bsicamente hay que seguir los siguientes pasos:Codificar las funciones que van a ser llamadas siguiendo un determinado mecanismo.Informar al sistema operativo (unix) de un nombre, una versin y funciones que publica.Meterse en un bucle infinito esperando que alguien llame a alguna de sus funciones.Mientras que el programa cliente debe:Establecer una conexin con el servidor.Llamar a las funciones.Cerrar la conexin con el servidor.

EL PROGRAMA RPCGENAfortunadamente en unix existe una utilidad llamadarpcgenque nos ayuda en todo el proceso de codificacin. En un lenguaje similar a C (pero no igual) definimos los prototipos de las funciones que queremos que se publiquen. Habitualmente dicho fichero suele tener la extensin ".x". Luego, con el comando de unixrpcgen -a fichero.xse generan varios ficheros (7 en concreto) con todo el cdigo hecho, excepto, naturalmente, el cdigo de las funciones que queremos publicar.Si no ponemos la opcin -a, se generarn menos ficheros, dejndonos a nosotros el trabajo de generar los siguientes. El motivo es que sin la opcin -a se generan nicamente los ficheros con las funciones (vacias, para que las rellenemos). Con la opcin -a se generan adems unos ejemplos de uso, que pueden ser tiles siempre y cuando estemos dispuestos a modificarlos. En el resto del texto suponemos siempre que se ha usado la opcin -a.El servidor que genera rpcgen tiene todo prcticamente hecho, con la excepcin de que nuestras funciones estn casi vacias (devuelven un valor por defecto). Tenemos que editar y rellenar el cdigo de nuestras funciones.El cliente que genera rpcgen tiene tambin todo hecho. Se conecta al servidor, llama a todas las funciones una por una y cierra la conexin. Obviamente aprovechamos el principio (la conexin) y el final (la desconexin). Las llamadas a las funciones deberamos borrarlas y hacer que el cliente haga lo que nosostros queramos.Veamos un pequeo ejemplo de un fichero.xprogram NOMBRE_PROGRAMA { version VERSION_PROGRAMA { int incrementa (int) = 1; } = 1;} = 0x20000001;El fichero comienza con la palabra "program" y el nombre que queramos dar a nuestro programa. Despus, entre llaves va el resto. Al final todo se iguala a un nmero (= 0x20000001; ). Este nmero debe ser nico para cada programa. De esta forma podemos tener varios servidores corriendo a la vez en el mismo ordenador y los clientes tendrn una forma de referenciarlos.Dentro de las llaves del programa va "version" con el nombre de la version y, despus de la estructura de llaves, igualado a un nmero de versin ( = 1; ). Esto permite tener corriendo varias versiones del mismo programa (y de las mismas funciones) a la vez. Los clientes pueden indicar a qu versin quieren llamar.Finalmente, dentro de las llaves de versin, van los prototipos de nuestras funciones. Cada funcin se iguala a un nmero ( = 1; ) distinto, de forma que el cliente referenciar a la funcin por su nmero. Todas las funciones deben admitir un nico parmetro. Si queremos pasar ms de un parmetro, deberemos hacernos una estructura con los campos necesarios. Lo mismo pasa con el retorno de la funcin, puede ser un tipo simple o una estructura.El lenguaje admite la declaracin de estructuras para pasar parmetros complejos. Si queremos una funcin que admita varios parmetros, debemos hacer una estructura con todos esos parmetros. La funcin admitir como nico parmetro una estructura de este tipo.Por ejemplo, si nuestra funcin es "int suma (int sumando1, int sumando2);", el fichero suma.x debera contener algo parecido a lo siguiente:struct sumandos{ int sumando1; int sumando2;};

program PROGRAMA_SUMA { version VERSION_SUMA { int suma (sumandos) = 1; } = 1;} = 0x20000001;Ficheros generados por rpcgenUna vez escrito nuestro ficherosuma.x, hacemos una llamada al comando de unix "rpcgen -a suma.x". Esto generar 7 ficheros distintos (Puedes "pinchar" el nombre del fichero para verlo. Si lo descargas, qutale la extensin ".txt").Makefile.suma. Es el fichero Makefile necesario para compilar todos los dems ficheros de cdigo generados por rpcgen. El comando de unix "make -f Makefile.suma" nos generar los ejecutables de cliente y servidor.suma_xdr.c. Como RPC permite llamadas de clientes a servidores que estn en mquinas distintas y, por tanto, puedan tener una arquitectura distinta, es necesario traducir los parmetros y resultados a un "cdigo" universal, independiente de las mquinas. Si los parmetros son tipos bsicos (int, float, char, etc), el sistema unix ya tiene unas funciones de conversin (xdr_int(), xdr_float(), etc). Si los parmetros, como en este caso, son estructuras definidas por nosotros, las funciones de conversin hay que hacerlas. rpcgen genera automticamente dichas funciones y en nuestro caso, las ha metido en el fichero suma_xdr.csuma.h. Aqu estn los prototipos de nuestras funciones. Cualquier cliente que quiera usarlas, deber hacer un include de este fichero. El prototipo no es exactamente como esperaramos. A cada funcin le aade en el nombre unas "coletillas" para indicar el nmero de versin. Define tambin otras constantes como nombre de programa, nmero de versin, etc, que son tiles a la hora de hacer la conexin con el servidor.suma_server.c. En este fichero estn nuestras funciones, vacas, por supuesto. Debemos editarlo y escribir aqu nuestro cdigo. Veamos el fichero con un poco de detalle:int * suma_1_svc(sumandos *argp, struct svc_req *rqstp){ static int result;/** insert server code here*/result = argp->sumando1 + argp->sumando2; /* Esta lnea debe hacerla el programador */

return &result;}Al nombre de la funcin suma le ha aadido _1_svc. Indica que es la parte del servidor, versin 1. Declara un "result" esttico del tipo que le hayamos indicado como retorno en el fichero .x. Debemos dejar en esa variable nuestro resultado. Pone un comentario para indicarnos que escribamos ah nuestro cdigo. El programador escribe el cdigo. Recibe en argp un puntero a una estructura con los datos que le pasa el cliente. Con ella echa las cuentas y las guarda en "result". rpcgen pone la lnea "return &result"suma_svc.c. Este es un ejemplo concreto de servidor. Normalmente nos vale tal cual. Bsicamente registra al servidor en el sistema unix para indicarle que atienda a las llamadas y proporciona un "switch-case" para llamar a cada una de las funciones al recibir una peticin de un cliente.suma_client.c. Este es el main de un cliente concreto. Establece la conexin con el servidor de rpc, llama a todas las funciones una a una y cierra la conexin. Normalmente este cliente no nos sirve para nada. Lo habitual es hacerse un cliente a medida, copiando las funciones de establecimiento de conexin "clnt_create()" y las de desconexin "clnt_destroy()". El resto del cliente es nuestro programa y usaremos llamadas a "suma_1()" o la funcin que sea cuando lo necesitemos. "clnt_create()" nos devuelve un "identificador" de cliente. Deberemos usar este valor en todas las dems llamadas a funciones y "clnt_destroy()".suma_clnt.c. Las llamadas a funciones de rpc desde un cliente son ms o menos complejas. Se hacen a travs de la funcin "clnt_call()" que lleva la friolera de 7 parmetros. En "suma_clnt.c" rpcgen mete unas funciones de "traduccin" para hacernos ms sencillas las llamadas desde nuestro cliente. As, bastar con llamar a "suma_1()" con un par de parmetros simples (nuestros datos y el identificador obtenido con "clnt_create()"), en vez de usar "clnt_call()" con 7 parmetros distintos (identificador de cliente, identificador de la funcin a llamar, funcin de conversin del parmetro de entrada, parmetro de entarada, etc, etc).Para ejecutar el ejemplo...El ejemplo crea un servidor que publica una funcin de sumar dos enteros. Luego un cliente se conecta, pide una suma al servidor pasndole dos enteros y escribe el resultado en pantalla.Debes descargar todos los ficheros mencionados en un directorio. Luego compilas con "make -f Makefile.suma", con lo que se generan dos ejecutables:suma_serverysuma_client. Ejecutas el servidor desde una shell con "suma_server". Luego ejecutas el cliente con "suma_client " y ves el resultado.es el nombre de la mquina donde has ejecutado elsuma_server. Si es en la misma mquina, puedes poner de nombre de mquina "localhost".En este video puedes ver todo el proceso: