You are on page 1of 21

Subsecciones

Qu es RPC Cmo funciona RPC RPC Desarrollo de Aplicaciones o Definicin del Protocolo o Definicin de cliente y servidor de aplicaciones Code o Compliling y ejecutar la aplicacin Visin general de las rutinas de interfaz o Simplificado Funcin Rutina Nivel o Top Rutinas Nivel Rutinas Nivel Intermedio o Rutinas Nivel Experto o Rutinas Nivel Inferior Interfaz de programacin para RPC o Interfaz simplificada o Pasar tipos de datos arbitrarios o El desarrollo de alto nivel de las aplicaciones RPC Definicin del protocolo o Compartir los datos El lado del servidor La Parte Cliente Ejercer

Llamadas a procedimiento remoto (RPC)


Este captulo proporciona una visin general de llamadas a procedimiento remoto (RPC) de RPC.

Qu es RPC
RPC es una poderosa tcnica para la construccin de aplicaciones distribuidas, basadas en cliente-servidor. Se basa en la ampliacin de la nocin de convencional, o local llamado procedimiento, por lo que el procedimiento de llamada no necesita existir en el mismo espacio de direcciones como el procedimiento de llamada. Los dos procesos pueden ser en el mismo sistema, o pueden estar en diferentes sistemas con una red que los conecta. Mediante el uso

de RPC, los programadores de aplicaciones distribuidas evitar los detalles de la interfaz con la red. La independencia transporte de RPC asla la aplicacin de los elementos fsicos y lgicos del mecanismo de comunicacin de datos y permite que la aplicacin utilice una variedad de medios de transporte. RPC hace que el modelo de computacin ms potente y ms fcil de programa cliente / servidor. Cuando se combina con la ONC RPCGEN protocolo compilador (Captulo 33 ) los clientes de forma transparente realizar llamadas remotas a travs de una interfaz de procedimiento local.

Cmo funciona RPC


Una RPC es anlogo a una llamada de funcin. Al igual que una llamada a la funcin, cuando se realiza una llamada RPC, se pasan los argumentos de llamada a procedimiento remoto y la persona que llama espera a una respuesta que se devuelve desde el procedimiento remoto. La figura 32.1 muestra el flujo de la actividad que tiene lugar durante una llamada RPC entre dos sistemas en red. El cliente hace una llamada de procedimiento que enva una peticin al servidor y espera. El hilo est bloqueado desde el procesamiento hasta que se reciba sea una respuesta, o tiempo de espera. Cuando llega la peticin, el servidor llama a una rutina de atencin que realiza el servicio solicitado, y enva la respuesta al cliente. Despus de que se complete la llamada RPC, el programa cliente contina. RPC apoya especficamente las aplicaciones de red.

La figura. 32.1 Mecanismo de llamada a procedimiento remoto Un procedimiento remoto se identifica de forma nica por el triple de: (nmero de programa, nmero de versin, nmero de procedimiento) El nmero de programa identifica un grupo de procedimientos remotos relacionados, cada uno de los cuales tiene un nmero de procedimiento nico. Un programa puede consistir en una o ms versiones. Cada versin consta de una coleccin de procedimientos que estn disponibles para ser llamados a distancia. Los nmeros de versin permite mltiples versiones de un protocolo RPC a estar disponibles al mismo tiempo. Cada versin contiene el nmero de AA de los procedimientos que pueden ser llamados de forma remota. Cada procedimiento tiene un nmero de procedimiento.

RPC Desarrollo de Aplicaciones


Veamos un ejemplo: Una bsqueda de cliente / servidor en una base de datos personal en una mquina remota. Suponiendo que no se puede acceder a la base de datos desde la mquina local (a travs de NFS). Utilizamos UNIX para ejecutar una shell remota y ejecutar el comando de esta manera. Hay algunos problemas con este mtodo:

la orden puede tardar en ejecutarse. Usted necesita una cuenta de inicio de sesin en el equipo remoto.

La alternativa RPC es a establecer un servidor en el equipo remoto que se reponde a las preguntas. Recuperar informacin llamando a una consulta que ser ms rpido que el mtodo anterior.

Para desarrollar una aplicacin RPC son necesarios los siguientes pasos:

Especifique el protocolo de comunicacin cliente-servidor Desarrollar el programa cliente Desarrollar el programa de servidor

Los programas se compilan por separado. El protocolo de comunicacin se consigue mediante mdulos de programa generados y estos trozos y RPC (y otras bibliotecas) tendr que ser vinculado pulg
Definicin del Protocolo

La manera ms fcil para definir y generar el protocolo es el uso de un compilador protocolo tal como rpcgen que se discuten es el Captulo 33 . Para el protocolo debe identificar el nombre de los procedimientos de servicio y tipos de datos de parmetros y argumentos de retorno. El compilador lee un protocolo definitio y genera automticamente el cliente y talones de servidor. utiliza su propio lenguaje (lenguaje RPC o RPCL), que es muy similar a las directivas de preprocesador.
rpcgen

existe como un compilador ejecutable independiente que lee archivos especiales indicados por un . x prefijo.
rpcgen

As que para compilar un archivo RPCL slo tiene que hacer


rpcgen rpcprog.x

Esto generar posiblemente cuatro archivos:

- el taln de cliente rpcprog_svc.c - el resguardo del servidor rpcprog_xdr.c - Si los filtros XDR necesarios (representacin de datos externos) rpcprog.h - el archivo de cabecera necesarios para cualquier filtro XDR.
rpcprog_clnt.c

La representacin externa de datos (XDR) es un resumen de los datos necesarios para la mquina de la comunicacin independiente. El cliente y el servidor no necesitan ser mquinas del mismo tipo.
Definicin de cliente y servidor de aplicaciones Code

Ahora tenemos que escribir el cliente y el cdigo de la aplicacin. Deben comunicarse a travs de los procedimientos y los tipos de datos especificados en el Protocolo. La parte de servicios tendr que registrar los procedimientos que pueden ser llamados por el cliente y recibir y devolver los datos necesarios para su procesamiento. La aplicacin cliente llama al procedimiento remoto pasar los datos requeridos y recibir los datos retruned. Hay varios niveles de interfaces de aplicaciones que se pueden utilizar para desarrollar aplicaciones RPC. Vamos a disuss brevemente estos a continuacin antes exapnading thhe ms comunes en los captulos posteriores.
Compliling y ejecutar la aplicacin

Consideremos el modelo de compilacin completo necesario para ejecutar una aplicacin RPC. Makefiles son tiles para aliviar la carga de la compilacin de las aplicaciones RPC, pero es necesario entender el modelo completo antes de poder montar un makefile conveniente. Suponga que el el programa de cliente se llama rpcprog.c , el programa de servicio es rpcsvc.c y que el protocolo ha sido definido en rpcprog.x y que rpcgen se ha usado para producir los archivos de cdigo auxiliar y el filtro: rpcprog_clnt.c, rpcprog_svc.c , rpcprog_xdr.c, rpcprog.h . El programa cliente y el servidor debe incluir ( #
include "rpcprog.h"

A continuacin, debe:
compilar el cdigo cc-c rpcprog.c

de cliente:

compilar el stub del cliente: cc-c rpcprog_clnt.c compilar el filtro XDR: cc-c rpcprog_xdr.c construir el ejecutable del cliente: cc-o rpcprog rpcprog.o rpcprog_clnt.o rpcprog_xdr.c compilar los cc-c rpcsvc.c

procedimientos de servicio: del servidor:

compilar el resguardo cc-c rpcprog_svc.c

construir el ejecutable del servidor: cc-o rpcsvc rpcsvc.o rpcprog_svc.o rpcprog_xdr.c

Ahora slo tiene que ejecutar los programas rpcprog y rpcsvc en el cliente y el servidor, respectivamente. Los procedimientos de servidores deben estar registrados ante el cliente puede llamar a ellos.

Visin general de las rutinas de interfaz


RPC tiene mltiples niveles de interfaz de la aplicacin a sus servicios. Estos niveles proporcionan diferentes grados de control equilibrada con diferentes cantidades de cdigo de la interfaz para poner en prctica. Con el fin de aumentar el control y la complejidad. En esta seccin se ofrece un resumen de las rutinas disponibles en cada nivel. Rutinas interfaz simplificada Las interfaces simplificados se utilizan para realizar llamadas a procedimientos remotos rutinas en otras mquinas, y especificar slo el tipo de transporte a utilizar. Las rutinas de este nivel se utilizan para la mayora de aplicaciones. Descripciones y ejemplos de cdigo se pueden encontrar en la seccin, simplificada interfaz @ 3-2.
Simplificado Funcin Rutina Nivel

- Registra un procedimiento como un programa RPC en todos los medios de transporte del tipo especificado.
rpc_reg ()

- Remote llama al procedimiento especificado en el host remoto especificado.


rpc_call ()

- difunde un mensaje de llamada en todos los medios de transporte del tipo especificado. Las rutinas de interfaz estndar Las interfaces estndar se dividen en nivel superior, nivel intermedio, nivel de expertos, y el nivel inferior. Estas interfaces dan un desarrollador mucho mayor control sobre los parmetros de comunicacin, tales como el transporte que se utilice, el tiempo de espera beforeresponding a errores y retransmisin de solicitudes, y as sucesivamente.
rpc_broadcast ()

Top Rutinas Nivel

En el nivel superior, la interfaz sigue siendo simple, pero el programa tiene que crear un identificador de cliente antes de realizar una llamada o crear un identificador del servidor antes de recibir llamadas.Si desea que la aplicacin se ejecute en todos los transportes, utilice esta interfaz. El uso de estas rutinas y ejemplos de cdigo se puede encontrar en la interfaz de nivel superior - Creacin cliente genrico. El programa cuenta clnt_create () donde se encuentra el servidor y el tipo de transporte a utilizar.
clnt_create ()

Al igual que clnt_create () , pero le permite al programador especificar el tiempo mximo permitido para cada tipo de transporte tratado durante el intento de creacin.
clnt_create_timed ()

- Crea servidor maneja para todos los transportes del tipo especificado. El programa cuenta svc_create () de la expedicin funcin de su uso.
svc_create () clnt_call ()

- El cliente llama a un procedimiento para enviar una peticin al

servidor.

Rutinas Nivel Intermedio


La interfaz de nivel intermedio de RPC permite detalles de control. Los programas escritos en estos niveles inferiores son ms complicadas, pero funcionan de manera ms eficiente. El nivel intermedio permite especificar el transporte a utilizar.
clnt_tp_create ()

- Crea un identificador de cliente para el transporte

especificado.

- Al igual que clnt_tp_create () , pero le permite al programador especificar el tiempo mximo permitido. svc_tp_create () Crea un handle de servidor para el transporte especificado.
clnt_tp_create_timed () clnt_call ()

- El cliente llama a un procedimiento para enviar una peticin al

servidor.
Rutinas Nivel Experto

El nivel de expertos, contiene un conjunto ms amplio de las rutinas con las que especifican los parmetros relacionados con el transporte. El uso de estas rutinas
clnt_tli_create ()

- Crea un identificador de cliente para el transporte

especificado.
svc_tli_create () rpcb_set ()

- Crea un handle de servidor para el transporte especificado.

- Llamadas rpcbind establecer un mapa entre un servicio RPC y una direccin de red.
rpcb_unset ()

- Elimina una asignacin fijada por rpcb_set

()

- Llamadas RPCBIND para obtener las direcciones de transporte de servicios RPC especificados.
rpcb_getaddr ()

- Asocia el programa especificado y par de nmeros de versin con la rutina de envo especificado.
svc_reg () svc_unreg () clnt_call ()

- Elimina una asociacin establecida por svc_reg

()

- El cliente llama a un procedimiento para enviar una peticin al

servidor.
Rutinas Nivel Inferior

El nivel inferior contiene rutinas utilizadas para el control total de las opciones de transporte. - Crea un identificador de cliente RPC para el programa remoto indicado, utilizando un transporte sin conexin.
clnt_dg_create () svc_dg_create ()

- Crea un handle de servidor RPC, utilizando un transporte sin

conexin.

- Crea un identificador de cliente RPC para el programa remoto indicado, utilizando un transporte orientado a la conexin.
clnt_vc_create ()

- Crea un handle de servidor RPC, utilizando un transporte orientado a la conexin.


svc_vc_create () clnt_call ()

- El cliente llama a un procedimiento para enviar una peticin al

servidor.

Interfaz de programacin para RPC


Esta seccin se ocupa de la interfaz RPC para C y se describe cmo escribir aplicaciones de red que utilizan RPC. Para obtener una descripcin completa de las rutinas de la biblioteca RPC, consulte losrpc y afines hombre pginas.
Interfaz simplificada

La interfaz simplificada es el nivel ms fcil de usar, ya que no requiere el uso de cualquier otro rutinas RPC. Tambin limita el control de los mecanismos de comunicacin subyacentes. El desarrollo del programa en este nivel puede ser rpida, y es apoyado directamente por el rpcgen compilador. Para la mayora de las aplicaciones, rpcgen y sus instalaciones son suficientes. Algunos servicios RPC no estn disponibles como funciones de C, pero estn disponibles como programas de RPC. Las rutinas de la biblioteca de interfaz simplificada proporcionan acceso directo a las instalaciones de RPC para los programas que no requieren niveles finos de control. Rutinas como rusers estn en el servicio RPC biblioteca librpcsvc . rusers.c , a continuacin, es un programa que muestra el nmero de usuarios en un host remoto. Se llama a la rutina de biblioteca RPC, rusers . El program.c listado del programa:
# Include <rpc/rpc.h> # Include <rpcsvc/rusers.h> # Include <stdio.h> / * * * * Un programa que llama a la Rusers () Servicio /

main (int argc, char ** argv)

{ int num; if (argc! = 2) { fprintf (stderr, "uso:% s host \ n", argv [0]); exit (1); } if ((num = rnusers (argv [1])) <0) { fprintf (stderr, "Error: rusers \ n"); exit (1); } fprintf (stderr, "% d usuarios en% s \ n", num, argv [1]); exit (0); }

Compile el programa con:


cc program.c-lrpcsvc-lnsl

La Parte Cliente Slo hay una funcin en el cliente de la interfaz simplificada rpc_call Tiene nueve parmetros:
int rpc_call (char * host / * Nombre de host del servidor * /, u_long prognum / * nmero de programa del servidor * /, u_long versnum / * nmero de versin del servidor * /, xdrproc_t inproc / * Filtro XDR para codificar arg * /, char * en / * puntero al argumento * /, xdr_proc_t outproc / * Filtro para decodificar resultado * /, char * out / * Direccin de almacenar resultado * /, char * nettype / * Para la seleccin de transporte * /); ()

Esta funcin llama al procedimiento especificado por prognum, VERSUM, y procnum en el host. El argumento que se pasa al procedimiento remoto es apuntado por el de parmetro y inproc es el filtro XDR para codificar este argumento. El cabo parmetro es una direccin en donde el resultado del procedimiento remoto se va a colocar. outproc es un filtro de XDR que decodificar el resultado y colocarlo en esta direccin. Los bloques de cliente en rpc_call () hasta que se recibe una respuesta del servidor. Si el servidor acepta, devuelve RPC_SUCCESS con el valor de cero. Se devuelve un valor distinto de cero si la llamada no tuvo xito. Este valor se puede convertir en el tipo clnt_stat , un tipo enumerado se define en los archivos de inclusin de RPC (<rpc/rpc.h>) e interpretada por el clnt_sperrno

()funcin.

Esta funcin devuelve un puntero a un mensaje de error RPC estndar correspondiente al cdigo de error. En el ejemplo, todos los transportes "visibles" que figuran en el / etc / netconfigson juzgados. Ajuste del nmero de reintentos requiere el uso de los niveles ms bajos de la biblioteca de RPC. Varios argumentos y los resultados estn a cargo de su recogida en las estructuras. El ejemplo modificado para utilizar la interfaz simplificada, parece
# # # # Include Include Include Include <stdio.h> <utmp.h> <rpc/rpc.h> <rpcsvc/rusers.h>

/ * Un programa que llama a la RUSERSPROG * Programa de RPC * / main (int argc, char ** argv) { nusers largo sin firmar; enumeracin clnt_stat cs; if (argc! = 2) { fprintf (stderr, "uso: rusers nombre de host \ n"); exit (1); } if (cs = rpc_call (argv [1], RUSERSPROG, RUSERSVERS, RUSERSPROC_NUM, xdr_void, (Char *) 0, xdr_u_long, (char *) y nusers, "Visible")! = RPC_SUCCESS) { clnt_perrno (cs); exit (1); } fprintf (stderr, "% d usuarios en% s \ n", nusers, argv [1]); exit (0); }

Dado que los tipos de datos pueden ser representados de manera diferente en diferentes mquinas, rpc_call () necesita tanto el tipo de, y un puntero, el argumento RPC (de manera similar para el resultado). Para RUSERSPROC_NUM , el valor de retorno es un entero largo sin signo, por lo que el primer parmetro de retorno de rpc_call () es xdr_u_long (que es para un largo sin signo) y el segundo es y nusers (que apunta a un almacenamiento largo sin signo). Debido RUSERSPROC_NUM no tiene argumento, la funcin de codificacin XDR de rpc_call () es xdr_void () y su argumento es NULL . El lado del servidor

El programa servidor utilizando la interfaz simplificada es muy sencillo. Simplemente llama rpc_reg () para registrar el procedimiento que se ha llamado, y luego se llama a svc_run () , despachador de procedimiento remoto de la biblioteca RPC, que esperar a que las peticiones para venir pulg
rpc_reg ()

tiene el siguiente prototipo:

rpc_reg (u_long prognum / * nmero de programa del servidor * /, u_long versnum / * nmero de versin del servidor * /, u_long procnum / * nmero de procedimiento del servidor * /, char * nombreproc / * Nombre de la funcin de control remoto * /, xdrproc_t inproc / * Filtro para codificar arg * /, xdrproc_t outproc / * Filtro para decodificar resultado * /, char * nettype / * Para la seleccin de transporte * /);

invoca a los procedimientos de servicio en respuesta a los mensajes de llamadas RPC. El despachador de rpc_reg () se encarga de decodificar los argumentos a procedimientos remotos y los resultados de codificacin, utilizando los filtros XDR especificados al registrar el procedimiento remoto. Algunas notas sobre el programa de servidor:
svc_run ()

Mayora de las aplicaciones RPC siguen la convencin de nombres de aadir una _1 al nombre de la funcin. La secuencia _n se aade a los nombres de procedimiento para indicar el nmero de versin n del servicio. El argumento y el resultado se pasan como direcciones. Esto es cierto para todas las funciones que son llamados de forma remota. Si pasa NULL como resultado de una funcin, entonces no hay respuesta se enva al cliente. Se supone que no hay respuesta a enviar. El resultado debe existir en el espacio de datos estticos, ya que su valor se accede despus de que el procedimiento en s ha salido. La funcin de biblioteca de RPC que se basa el mensaje de respuesta RPC accede el resultado y enva el valor de vuelta al cliente. Slo se permite un solo argumento. Si hay varios elementos de datos, que deben ser envueltos dentro de una estructura que luego se puede pasar como una sola entidad. El procedimiento se registr para cada transporte del tipo especificado. Si el parmetro de tipo es (char *) NULL , el procedimiento se ha registrado para todos los transportes mencionados enNetPath .

A veces se puede implementar rpidamente o cdigo ms compacto que puede RPCGEN . rpcgen maneja los casos de generacin de cdigo genrico. El

programa siguiente es un ejemplo de una rutina de registro codificado a mano. Se registra un solo procedimiento y entra svc_run () a las solicitudes de servicio.
# Include <stdio.h> # Include <rpc/rpc.h> # Include <rpcsvc/rusers.h> void * rusers (); main () { if (rpc_reg (RUSERSPROG, RUSERSVERS, RUSERSPROC_NUM, rusers, xdr_void, xdr_u_long, "Visible") == -1) { fprintf (stderr, "No se pudo registrar \ n"); exit (1); } svc_run (); / * nunca vuelve * / fprintf (stderr, "Error: svc_run regres \ n"); exit (1); }

se puede llamar tantas veces como sea necesario para registrar los diferentes programas, versiones y procedimientos.
rpc_reg ()

Pasar tipos de datos arbitrarios

Los tipos de datos pasados y recibidos de procedimientos remotos puede ser cualquiera de un conjunto de tipos predefinidos, o puede ser programador tipos definidos. RPC se encarga de las estructuras de datos arbitrarias, independientemente de las rdenes de bytes diferentes mquinas o convenciones de diseo de la estructura, por siempre convirtindolos a un formato estndar de transferencia de llamada representacin externa de datos (XDR) antes de enviarlos a travs del transporte. La conversin de una representacin de la mquina de XDR se llama serializar, y el proceso inverso se denomina deserializacin. Los argumentos traductor de rpc_call () y rpc_reg () puede especificar un procedimiento XDR primitiva, como xdr_u_long () , o una rutina programador suministrador que procesa una estructura argumental completa. Rutinas de procesamiento de argumentos deben tomar slo dos argumentos: un puntero al resultado y un puntero al mango XDR. Las siguientes rutinas primitivas XDR estn disponibles:
xdr_int () xdr_netobj () xdr_u_long () xdr_enum () xdr_long () xdr_float () xdr_u_int () xdr_bool () xdr_short () xdr_double () xdr_u_short () xdr_wrapstring () xdr_char () xdr_quadruple () xdr_u_char () xdr_void ()

El no primitiva xdr_string desde xdr_wrapstring () .

()

, que lleva ms de dos parmetros, se llama

Para un ejemplo de una rutina de programador con suministro, la estructura:


struct {sencilla int a; corta b; } Sencilla;

contiene los argumentos de llamada de un procedimiento. La rutina XDR xdr_simple () traduce la estructura argumental, como se muestra a continuacin:
# Include <rpc/rpc.h> # Include "simple.h" bool_t xdr_simple (XDR * xdrsp, estructura sencilla * simplep) { if (! xdr_int (xdrsp, y simplep-> a)) volver (false); if (! xdr_short (xdrsp, y simplep-> b)) volver (false); volver (TRUE); }

Una rutina equivalente puede ser generado automticamente por rpcgen (Consulte el Captulo 33 ). Una rutina XDR devuelve no-cero (un C TRUE) si se completa con xito, y cero en caso contrario. Para datos ms complejas estructuras utilizan el prefabricado rutinas XDR:
xdr_array () xdr_bytes () xdr_reference () xdr_vector () xdr_union () xdr_pointer () xdr_string () xdr_opaque ()

Por ejemplo, para enviar una matriz de tamao variable de los nmeros enteros, que se envasa en una estructura que contiene la matriz y su longitud:
struct {varintarr int * datos; int arrlnth; } Arr;

Traducir la matriz con xdr_array

()

, como se muestra a continuacin:

bool_t xdr_varintarr (XDR * xdrsp, estructura varintarr * arrp) { volver (xdr_array (xdrsp, (caddr_t) y ARRP-> data, (U_int *) y arrp-> arrlnth, MAXLEN, sizeof (int), xdr_int)); }

Los argumentos de xdr_array () son el mango XDR, un puntero a la matriz, un puntero para el tamao de la matriz, el tamao mximo de la matriz, el tamao de cada elemento de la matriz, y un puntero a la rutina XDR para traducir cada elemento de la matriz . Si el tamao de la matriz se conoce de antemano, utilizar xdr_vector () instread como es ms eficiente:
int intArr [TAMAO]; bool_t xdr_intarr (XDR * xdrsp, intArr int []) { volver (xdr_vector (xdrsp, intArr, TAMAO, sizeof (int), xdr_int)); }

XDR convierte cantidades mltiplos de 4 bytes al serializar. En las matrices de caracteres, cada carcter ocupa 32 bits. xdr_bytes () paquetes caracteres. Tiene cuatro parmetros similares a los cuatro primeros parmetros de xdr_array () . Series terminadas en nulo se traducen por xdr_string () . Es como xdr_bytes () sin ningn parmetro de longitud. En la serializacin se pone la longitud de la cadena de strlen () , y deserializar que crea una cadena terminada en nulo. llama a las funciones integradas xdr_string () y xdr_reference () , lo que se traduce punteros para pasar una cadena y struct sencillo de los ejemplos anteriores. Un ejemplo de uso de xdr_reference () es la siguiente:
xdr_reference () struct {finalexample char * cadena; estructura sencilla * simplep; } Finalexample; bool_t xdr_finalexample (XDR * xdrsp, estructura finalexample * Finalp) {If (! Xdr_string (xdrsp, y Finalp-> string, MAXSTRLEN)) volver (false); if (! xdr_reference (xdrsp, y Finalp-> simplep, sizeof (struct sencilla), xdr_simple)) volver (false); volver (TRUE); }

Tenga en cuenta que xdr_simple de xdr_reference () .

()

podra haber sido llamado aqu en vez

El desarrollo de alto nivel de las aplicaciones RPC

Ahora vamos a introducir algunas funciones nuevas y ver cmo se desarrolla una aplicacin utilizando rutinas de alto nivel RPC. Lo haremos mediante el estudio de un ejemplo. Vamos a desarrollar una utilidad de lectura de directorio remoto. Consideremos en primer lugar la forma en que escribiramos un lector de directorio local. Hemos parecer cmo hacer esto ya en el captulo 19 . Considere el programa que consta de dos archivos:
lls.c

- el programa principal que llama a una rutina en un mdulo

local read_dir.c
/ * * Ls.c: lista de directorios locales principal - antes de RPC * / # Include <stdio.h> # Include <strings.h> # Include "rls.h" main (int argc, char ** argv) { caracteres dir [DIR_SIZE]; / * Llamar al procedimiento local * / strcpy (dir, argv [1]); / char * dir [DIR_SIZE] est yendo y viniendo ... * / read_dir (dir); / * Salida arrojan los resultados y la libertad bajo fianza de aqu! * / printf ("% s \ n", dir); exit (0); } read_dir.c - el archivo que contiene el local de rutina read_dir () . / * Nota - RPC llamadas a procedimientos compatibles toma una entrada y devolver una salida. Todo se hace pasar por el puntero. Volver Los valores deben apuntar a datos estticos, ya que podra tener que sobrevivir algn tiempo. * / # Include <stdio.h> # Include <sys/types.h>

# Include <sys/dir.h> / * Uso <xpg2include/sys/dirent.h> (SunOS4.1) o <sys/dirent.h> de X / Open Portability Guide, nmero 2 conformidad * / # Include "rls.h" read_dir (char * dir) / Char * dir [DIR_SIZE] * / { DIR * dirp; struct directa * d; printf ("principio"); / * Directorio abierto * / dirp = opendir (dir); if (dirp == NULL) volver (NULL); / * Nombres cosas en tampn dir * / dir [0] = NULL; while (d = readdir (dirp)) sprintf (dir, "% s% s \ n", dir, d-> d_name); / * Devolver el resultado * / printf ("devolucin"); closedir (dirp); return ((int) dir); / * esta es la nica lnea nueva del Ejemplo 4-3 * / }

el archivo de encabezado rls.h incluye solamente la siguiente (al menos por ahora)
# Define DIR_SIZE 8192

Es evidente que tenemos que compartir el tamao entre los archivos. Ms tarde, cuando desarrollamos versiones RPC ser necesario aadir a este archivo de ms informacin. Este programa local se recopil la siguiente manera:
cc lls.c read_dir.c-o lls

Ahora queremos modificar este programa para trabajar en una red: Lo que nos permite inspeccionar directorios de un servidor remoto al otro lado de la red. Sern necesarios los siguientes pasos:

Habr que convertir el read_dir.c , para ejecutar en el servidor.

Vamos a tener que registrar el servidor y la rutina read_dir () en el servidor /. El cliente lls.c tendr que llamar a la rutina como un procedimiento remoto. Habr que definir el protocolo de comunicacin entre el los programas de cliente y servidor.
o

Definicin del protocolo Podemos podemos utilizar simples NULL cadenas terminadas para pasar y receivong el nombre del directorio y el contenido del directorio. Adems, podemos integrar el paso de estos parmetros directamente en el cdigo de cliente y servidor. Por tanto, necesitamos especificar los nmeros del programa, el procedimiento y la versin para el cliente y los servidores. Esto puede hacerse automticamente utilizando rpcgen o confiar en las macros prdefined en la interfaz simlified. Aqu vamos a especificar de forma manual. El servidor y el cliente deben acordar de antemano qu direcciones lgicas thney usar (Las direcciones fsicas no importan estn ocultos a los desarrolladores de aplicaciones) Los nmeros de programa se definen de una manera estndar:

0 x 00000000-0 x 1 FFFFFFF : definido por Sun 0 x 20000000-0 x 3 FFFFFFF : Definido por el usuario 0 x 40000000-0 x 5 FFFFFFF : Transient 0 x 60000000-0 xFFFFFFFF : Reservado

Nosotros simplemente elegir un valor deifnined usuario para obtener el nmero de programa. La versin y el nmero de procedimientos se establecen de acuerdo con la prctica estndar. Todava tenemos la DIR_SIZE definicin requiere de la versin local como el tamao del bfer de directorio se rewquired mediante programas de servidor y cliente bith. Nuestro nuevo rls.h archivo contiene:
# Define DIR_SIZE 8192 # Define DIRPROG ((u_long) 0x20000001) / * nmero de programa servidor (suite) * /

# Define Dirvers ((u_long) 1) / * nmero de versin del programa * / # Define READDIR ((u_long) 1) / * Nmero de procedimiento de consulta * /

Compartir los datos

Hemos mencionado anteriormente que podemos pasar los datos de una simple cuerda. Tenemos que definir una rutina de filtro XDR xdr_dir () que comparte los datos. Recordemos que slo una codificacin y decodificacin de argumento pueden ser manejados. Esto es fcil y definida a travs del estndar xdr_string () de rutina. El archivo de XDR, rls_xrd.c , es como sigue:
# Include <rpc/rpc.h> # Include "rls.h" bool_t xdr_dir (XDR * xdrs, char * objp) {Return (xdr_string (xdrs, y objp, DIR_SIZE));}

El lado del servidor Podemos utilizar el original read_dir.c archivo. Todo lo que necesitamos hacer es registrar el procedimiento e iniciar el servidor. El procedimiento se ha registrado en registerrpc por:
()

funcin. Esta es prototipos

registerrpc (u_long prognum / * nmero de programa del servidor * /, u_long versnum / * nmero de versin del servidor * /, u_long procnum / * nmero de procedimiento del servidor * /, char * nombreproc / * Nombre de la funcin de control remoto * /, xdrproc_t inproc / * Filtro para codificar arg * /, xdrproc_t outproc / * Filtro para decodificar resultado * /);

Los parmetros de una manera similar como se definen en el rpc_reg funcin de interfaz simplificado. Ya hemos hablado de la puesta del parametere con el protocolo rls.h archivos de cabecera y larls_xrd.c archivo filtro XDR. El svc_run
()

de rutina tambin se ha discutido previamente.

La plena rls_svc.c cdigo es el siguiente:


# Include <rpc/rpc.h> # Include "rls.h" main ()

{ extern bool_t xdr_dir (); extern char * read_dir (); registerrpc (DIRPROG, Dirvers, READDIR, read_dir, xdr_dir, xdr_dir); svc_run (); }

La Parte Cliente En el lado del cliente simplemente tenemos que llamar al procedimiento remoto. La funcin callrpc () hace esto. Se siguiente prototipo:
callrpc (char * host / * Nombre de host del servidor * /, u_long prognum / * nmero de programa del servidor * /, u_long versnum / * nmero de versin del servidor * /, char * en / * puntero al argumento * /, xdrproc_t inproc / * Filtro XDR para codificar arg * /, char * out / * Direccin de almacenar resultado * / xdr_proc_t outproc / * Filtro para decodificar resultado * /);

Pedimos un local de la funcin read_dir () que utiliza callrpc () para llamar al procedimiento remoto que se ha registrado READDIR en el servidor. La plena rls.c programa es el siguiente:
/ * * Rls.c: * / # Include # Include # Include # Include client listado del directorio remoto <stdio.h> <strings.h> <rpc/rpc.h> "rls.h"

principal (argc, argv) int argc, char * argv []; { caracteres dir [DIR_SIZE]; / * Llamada de procedimiento remoto si registrado * / strcpy (dir, argv [2]); read_dir (argv [1], dir); / * read_dir (host, directory) * / / * Salida arrojan los resultados y la libertad bajo fianza de aqu! * / printf ("% s \ n", dir); exit (0); } read_dir (host, dir)

char * dir, * de acogida; { extern bool_t xdr_dir (); enumeracin clnt_stat clnt_stat; clnt_stat = callrpc (host, DIRPROG, Dirvers, READDIR, xdr_dir, dir, xdr_dir, dir); if (clnt_stat = 0!) clnt_perrno (clnt_stat); }

Ejercer
Ejercicio 12,833 Compilar y ejecutar el directorio remoto ejemplo rls.c etc . Ejecutar el cliente ande srever localmente y si es posible ms de una red.

You might also like