You are on page 1of 42

RPC: Remote Procedure Call

peticin respuesta

El Llamado de procedimientos remotos


Principios tericos y programacin en Unix
Dr. Roberto Gmez C. Diapo. No. 1

RPC: Remote Procedure Call

Cliente/Servidor: envo/recepcin mensajes

cliente

(leer FA45 de arch1)

servidor

cliente

(ack)

servidor

cliente

(34759037F3247A)

servidor

cliente

(ack)

servidor

Dr. Roberto Gmez C.

Diapo. No. 2

RPC: Remote Procedure Call

Desventajas paradigma envio/recepcin mensajes Paradigma envio/recepcin es del tipo Entrada/Salida


procedimientos send(), receive() estn dedicados a realizar E/S

E/S no es un concepto clave para los sistemas centralizados; pero si para la computacin o clculo distribuido Objetivo: hacer el clculo distribuido como si fuera clculo centralizado Clculo centralizado: llamadas de procedimientos y/o funciones
Dr. Roberto Gmez C. Diapo. No. 3

RPC: Remote Procedure Call

Ejecucin de una llamada de procedimiento local


main() { : count = read(fd, bytes, buf) : } main() { : count = read(fd, bytes, buf) : } main() { : count = read(fd, bytes, buf) : }

Variables locales al main

SP

Variables locales al main bytes buf fd direccin regreso

Variables locales al main

SP

SP

a) Stack antes llamada read

b) Stack durante ejecucin read

c) Stack despus llamada read

Dr. Roberto Gmez C.

Diapo. No. 4

RPC: Remote Procedure Call

Tipos de paso de parmetros


Por valor
en el stack se copia el valor del parmetro valor de salida es igual al valor de entrada

Por referencia
en el stack se almacena la direccin de la variable es posible modificar el valor del parmetro

call-by-copy/restore
se copia el valor de la variable en el stack, (como en paso por valor) stack al final de la ejecucin local se copia el valor que tiene la variable dentro del procedimiento, en el stack el procedimiento que mand llamar al procedimiento copia el valor final en condiciones normales tiene el mismo efecto que el paso por referencia
Dr. Roberto Gmez C. Diapo. No. 5

RPC: Remote Procedure Call

El RPC
Creado por Birrel & Nelson en 1984 Permiten a los programas llamar procedimientos localizados en otras mquinas Un proceso x en una mquina A, puede llamar un procedimiento localizado en una mquina B Informacin puede llevarse del proceso invocador al invocado dentro de los parmetros Ningn mensaje u operacin de E/S es visible para el programador Problemas a resolver:
procedimientos invocador e invocado se ejecutan en diferentes mquinas, i.e. diferentes direcciones y posiblemente diferentes arquitecturas ambas mquinas pueden fallar
Dr. Roberto Gmez C. Diapo. No. 6

RPC: Remote Procedure Call

Principio funcionamiento del RPC Mquina Cliente


stub del cliente
call cliente return Pack parmetros Unpack resultado

Mquina Servidor
stub del servidor
Unpack parmetros Pack resultado call servidor return

kernel

kernel

Mensaje transportado en la red


Dr. Roberto Gmez C. Diapo. No. 7

RPC: Remote Procedure Call

Proveniencia de los stubs

Varios sistemas: generados automticamente


rpcgen de Sun generacion archivos esqueleto, para cliente y servidor, a partir de un compilador y de la especificacin del servicio

Rutinas de especificacin de stubs


rutinas de alto y bajo nivel posibilidad de definir ms aspectos
timeouts protocolos
Dr. Roberto Gmez C. Diapo. No. 8

RPC: Remote Procedure Call

El paso de parmetros stubs Mquina Cliente Mquina Servidor

mensaje : sum : 4 n=sum(4,7); : 7 :

mensaje sum(i,j)
sum

4
7

int i,j; { return(i+j); }

kernel

kernel

Dr. Roberto Gmez C.

Diapo. No. 9

RPC: Remote Procedure Call

Aspectos a considerar en el paso de parmetros Tipos de paso de parmetros


por valor por referencia call-by-copy/restore

Problemas a resolver
diferencias entre representacin de datos diferencias en formatos paso de apuntadores, (estructuras complejas)

Optimizacin
especificacin parmetros de entrada y salida registros para paso de apuntadores

Dr. Roberto Gmez C.

Diapo. No. 10

RPC: Remote Procedure Call

Binding dinmico: especificacin formal servidor

#include <header.h> specification of file_server, version 3.1 file server, long read(in char name[MAX_PATH], out char buf[BUF_SIZE], in long bytes, in long position); long write(in char name[MAX_PATH], in char buf[BUF_SIZE], in long bytes, in long position); int create(in char[MAX_PATH], in int mode); int delete(in char[MAX_PATH]); end.

Dr. Roberto Gmez C.

Diapo. No. 11

RPC: Remote Procedure Call

Registro del servidor

SERVIDOR

Binder

Nombre Num. versin Id.nico Id nico Manejador, (handler) Otros (autentificacin)

Sistema Distribuido

Dr. Roberto Gmez C.

Diapo. No. 12

RPC: Remote Procedure Call

Peticin cliente 3
error

servicio NO disponible

Binder
proceso 1 solicitante

2
stub cliente

servicio disponible
Nombre, Num. versin, Id.nico, Manejador

Dr. Roberto Gmez C.

Diapo. No. 13

RPC: Remote Procedure Call

Parmetros entrada/salida de la interfaz binder

Accin
Registrar Suprimir Buscar

Parmetros Entrada
Nombre, versin, manejador, id nico Nombre, versin, id nico Nombre, Nombre versin

Salida

Manejador, Manejador id nico

Dr. Roberto Gmez C.

Diapo. No. 14

RPC: Remote Procedure Call

Registro y localizacin de un servidor RPC


Paso 1: Este es PRIMEPROG Version 1, Estoy usando el puerto 1061

Puerto 111

Servidor

Portmapper

Puerto 1061

Paso 2: Donde esta PRIMEPROG Version 1?

Prog Vers Puerto

Paso 4: Llama procedimiento 1. Aqu estn los datos

Paso 3: Esta en el puerto 1061

Cliente

Dr. Roberto Gmez C.

Diapo. No. 15

RPC: Remote Procedure Call

Binding y nombramiento servicios


Convencin para nmeros de programa de Sun 00000000 - 1FFFFFFF 20000000 - 3 3FFFFFFF 40000000 - 5FFFFFFF 60000000 - FFFFFFFF El comando rpcinfo Realiza una llamada RPC a un servidor RPC y reporta lo que encuentra. encuentra Dependiendo de los parmetros es posible: - listar todos los servicios de un RPC en un host - listar todos los servicios RPC registrados con rpcbind versin 2 - realizar una llamada RPC al procedimiento 0 de un determinado programa y de una determinada versin en un host dado.
Dr. Roberto Gmez C. Diapo. No. 16

definido por y administrado por Sun definido d fi id por el usuario l i de trnsito, (aplicaciones con generacin de nmeros) reservado para un futuro uso

RPC: Remote Procedure Call

Sintaxis y opciones rpcinfo


Sintaxis rpcinfo [ -m -s ] [ host ] rpcinfo -p [ host ] rpcinfo -T transport host prognum [ versnum ] rpcinfo -l [ -T transport ] host prognum [ versnum ] rpcinfo -b [-T transport ] prognum versnum rpcinfo -d [-T transport ] prognum versnum Algunas opciones -T especifica el transporte sobre el cual el servicio es requerido -a utiliza el parmetro como la direccin universal en el transporte -b realiza un broadcast al procedimiento 0 de los prognum y versnum b especificados y reporta todos los hosts que respondieron -d borra el regsitro correpondiente al prognum y versnum especificados -l despliega una lista de entradas que contienen un prognum y un versnum en el host especificado -s despliega una lista consisa de todos los programas RPC registrados en host. Si no se especifica ningn host tomo el host local
Dr. Roberto Gmez C. Diapo. No. 17

RPC: Remote Procedure Call

Ejemplo rpcinfo
armagnac:45>rpcinfo -s toto program version(s) netid(s) 100000 2,3,4 udp, tcp, tictls, ticosord, ticots 100029 2,1 ticots, ticotsord, ticlts 100078 4 ticots, ticotsord, ticlts 100087 10 udp 100011 1 ticlts, udp 100002 3,2 ticlts, udp 100099 1 ticots, ticotsord, ticlts 100012 1 ticlts, udp 100008 1 ticlts, udp 100001 4,3,2 432 ticlts, udp i l d 100024 1 ticots, ticotsord, ticlts, tcp, udp 100021 2,3,1 ticots, ticotsord, ticlts, tcp, udp 134177279 1,2 tcp armagnac:46> service rpcbin keyserv kerbd admind rquotad rusersd sprayd walld rstad d status nlockmgr owner superuser superuser superuser superuser superuser superuser superuser superuser superuser superuser superuser superuser 5001

Dr. Roberto Gmez C.

Diapo. No. 18

RPC: Remote Procedure Call

Pasos de una Llamada a un Procedimiento Remoto


Mquina Servidora Programa Servidor procedimientos servicio Portmapper funcin dispatch

callrpc () host, programa, versin, procedimiento, argumentos Mquina Cliente errores o resultados Programa Cliente

Dr. Roberto Gmez C.

Diapo. No. 19

RPC: Remote Procedure Call

Niveles del Protocolo TCP/IP


5-7. SESIN

Aplicacin Usuario

4. TRANSPORTE

TCP

UDP

3. RED

IP

1-2.ENLACE / FSICO

NIVELES OSI

Interface Hardware

RED
Dr. Roberto Gmez C. Diapo. No. 20

10

RPC: Remote Procedure Call

Pasos en la ejecucin de un RPC

1. El procedimiento del cliente llama al client-stub normalmente. 2. El client-stub construye un mensaje y lo pasa al kernel. 3. El kernel enva el mensaje al kernel remoto. 4. El kernel remoto pasa el mensaje al server-stub. 5. El server-stub desempaca los parmetros y llama al servidor. 6. El servidor realiza el trabajo y regresa el resultado al stub. 7. El server-stub lo empaqueta en un mensaje y lo pasa al kernel. 8. El kernel remoto enva un mensaje al cliente. 9. El kernel del cliente le da el mensaje al client-stub. 10. El stub desempaca el resultado y lo regresa al cliente.

Dr. Roberto Gmez C.

Diapo. No. 21

RPC: Remote Procedure Call

Ruta crtica de cliente a servidor Mquina Cliente Cliente


Llamar procedimientos stub
Preparar mensaje buffer Marshall los parmetros en el buffer Poner los encabezados a los mensajes Pasar al kernel

Mquina Servidor
Realizar sevicio Servidor

Servidor Server Stub

Stub Cliente

Llamar al servidor Poner los parametros en el stack Unmarshall parametros

Kernel
Mquina

Contexto switch al kernel Copiar mensaje en el kernel Determinar direcciones destino Poner direccin en encabezado mensaje Establecer la interfaz de la red Hechar a andar el timer

Switch contexto a server stub Copiar mensaje en server stub Ver si stub esta esperando Decidir a que stub darselo Checar el paquete para validacin Interrupcin de proceso

Kernel Mquina i

Dr. Roberto Gmez C.

Diapo. No. 22

11

RPC: Remote Procedure Call

EL RPC DE SUN

El rpcgen y el lenguaje de especificacin RPCL Ejemplos: - Llamada procedimientos con un solo parmetro - Llamada remota con mltiples parmetros

Dr. Roberto Gmez C.

Diapo. No. 23

RPC: Remote Procedure Call

user developed

Desarrollo de una Aplicacin de Red con un Compilador de Protocolo RPC


Especificacin RPC

RPC and data representation libraries stub del cliente

Compilador RPC

filtros comunes y archivo encabezado

stub del servidor

compilar y ligar

compilar y ligar

funciones cliente

libreras de RPC y de representacin de datos

funciones servidor

cdigo cliente
Dr. Roberto Gmez C.

cdigo servidor
Diapo. No. 24

12

RPC: Remote Procedure Call

El lenguaje RPC (RPCL) RPCL


-Comentarios Igual que en lenguaje C -Constantes simblicas const MAX_SIZE = 8192

Equivalente en C

#define MAX_SIZE 8192

- Enumeraciones enum colores{ROJO = 0, VERDE=1, enum colores { ROJO=0, VERDE=1, AZUL=2}; AZUL=2}; typedef enum colores colores; -Booleanos Booleanos bool termino; bool_t termino; -Arreglos tamao fijo int alumnos[10];

int alumnos[10];

Dr. Roberto Gmez C.

Diapo. No. 25

RPC: Remote Procedure Call

RPCL

Equivalente en C

-Arreglos tamao variable int a <12> /* a los mas 12 elementos*/ struct { u_int a_len; int *a_val; } a; int b<> /* cualquier numero de elementos */ struct { u_int b_len; int *b_val; } b; Tamao mximo = parmetro maxsize en xdr_array() No especificacin mximo => mximo valor puede tomar u_int; Solo es posible trabajar con arreglos unidimensionales -Estructuras struct punto { int x; int y; };
Dr. Roberto Gmez C.

struct punto { int x; int y; }; typedef struct punto punto;


Diapo. No. 26

13

RPC: Remote Procedure Call

-Strings No existen en C, RPCL convencin de terminacin en NULL Tamao especifica mximo nmero caracteres permitidos en string No especificado => tamao mximo = mximo valor u_int; string nombre <32> string nombresote<> -Uniones Ms cercanas al registro variante de Pascal union resultado switch (int errno){ case 0: opaque data[1024]; case 1 1: int valor; default: void }; char *nombre; char *nombresote;

struct resultado { int errno; union { char data[1024] h d t [1024] int valor; } resultado_u; }; typedef struct resultado resultado;

Dr. Roberto Gmez C.

Diapo. No. 27

RPC: Remote Procedure Call

-Datos opacos Usados para describir datos que no tienen tipo Dato puede ser de tamao fijo o variable opaque diskblock[512]; opaque filedata<1024>

RPCL

Equivalente en C

char diskblock[512]; struct { u_int filedata_len; char *filedata_val; } filedata

-Typedef RPCL Misma sintaxis que en C Ejemplo define un fname_type usado para declarar strings de nombres de archivos que tienen una longitud mxima de 255 caracteres typedef string fname_type <255> - Identificadores Compuestos de letras, nmeros y el underscore Distincin entre mayusculas y minusculas typedef char *fname_type;

Dr. Roberto Gmez C.

Diapo. No. 28

14

RPC: Remote Procedure Call

Pasos para convertir llamadas locales en remotas

- Disear programa usando llamadas locales. p g - Restructurar cada funcin de tal forma que slo tenga un parmetro pasado por valor y asegurarse que trabaja bien localmente. - Crear un archivo de especificacin con extensin .x. - Ejecutar rpcgen con opciones -a y -C para generar archivos necesarios. - Usar el makefile generado para compilar los archivos. Es posible detectar errores en las definiciones de tipos en el archivo de especificacin. - Insertar programa que va a llamar a la funcin en el archivo _client.c generado por rpcgen. - Insertar cdigo funcin local en el archivo _server.c generado por rpcgen. - Intentar compilar los programas usando el makefile generado. - Jugar, (fiddle), con el _server.c y el _client.c hasta que trabajen. Este juego puede no ser necesario si solo se utilizan tipos simples de datos.

Dr. Roberto Gmez C.

Diapo. No. 29

RPC: Remote Procedure Call

Ejemplo aplicacin: permetro y rea de un cuadro

perimetro (a) area(a)

: per = perimetro(20) : sup = area(20 :

int double : 4*a : a*a :

Dr. Roberto Gmez C.

Diapo. No. 30

15

RPC: Remote Procedure Call

Paso I Diseo del servicio local i i l l

Dr. Roberto Gmez C.

Diapo. No. 31

RPC: Remote Procedure Call

Calculo permetro y rea de un cuadrado #include <stdio.h>


int perimetro(int a) { return 4*a; } double area (int a) { return a*a; }

main(int argc, char *argv[]) { int a; int per; double sup; if (argc !=2 ) { fprintf(stderr,"Error,uso: %s a \n",argv[0]); exit(1); } a = atoi(argv[1]); per = perimetro(a); sup = area(a); printf("El perimetro del cuadrado es %d \n",per); printf("El area del cuadrado es %d \n",sup); }
Dr. Roberto Gmez C.

Diapo. No. 32

16

RPC: Remote Procedure Call

Cdigo del servidor local: servidor.c #include cuad.h int perimetro(int a) { int res; res = 4*a; return(res); } double area(int a) { double res; res = a*a; return(res); }

Dr. Roberto Gmez C.

Diapo. No. 33

RPC: Remote Procedure Call

Cdigo del cliente local: cliente.c


#include <stdio.h> #include cuad.h main(int argc, char *argv[]) { int a; int per; double sup; if (argc !=2 ) { fprintf(stderr,"Error, uso: %s a \n",argv[0]); exit(1); } a = atoi(argv[1]); per = perimetro(a); sup = area(a); printf("El perimetro del cuadrado es %d \n",per); printf("El area del cuadrado es %d \n",sup); }
Dr. Roberto Gmez C. Diapo. No. 34

17

RPC: Remote Procedure Call

El archivo de encabezado cuad.h

int perimetro(int); double area(int);

Dr. Roberto Gmez C.

Diapo. No. 35

RPC: Remote Procedure Call

Compilando y ejecutando

rogomez@cuba:93>gcc cliente.c servidor.c -o cuadro rogomez@cuba:94>cuadro 5 El perimetro del cuadrado es 20 El area del cuadrado es 25 rogomez@cuba:95>cuadro 2 El perimetro del cuadrado es 8 El area del cuadrado es 4 rogomez@cuba:96>

Dr. Roberto Gmez C.

Diapo. No. 36

18

RPC: Remote Procedure Call

Paso II Diseo del archivo de configuracin y g uso de rpcgen

Dr. Roberto Gmez C.

Diapo. No. 37

RPC: Remote Procedure Call

El archivo de especificacin cuadro.x

/*Nombre archivo: cuadro.x */ program CUADRO_PROG { version CUADRO_VERS{ int PERIMETRO(int) = 1; double AREA(int) = 2; } = 1; } = 0x311445566;

Dr. Roberto Gmez C.

Diapo. No. 38

19

RPC: Remote Procedure Call

Nmeros de programas remotos

Rango (hexadecimal) 00000000 - 1FFFFFFF 20000000 - 3FFFFFFF 40000000 - 5FFFFFFF 50000000 - 7FFFFFFF 80000000 - 9FFFFFFF A0000000 - BFFFFFFF C0000000 - DFFFFFFF E0000000 - FFFFFFFF

Administrador Sun Local Desarrollador Reservado Reservado Reservado Reservado Reservado

Tiempo de vida Permanente Desconocido Temporal

Distribucin Pblica Local Local

Dr. Roberto Gmez C.

Diapo. No. 39

RPC: Remote Procedure Call

Sintxis del rpcgen

rpcgen infile rpcgen [ -a ] [ -A ] [ -b ] [ -C ] [-D name [ = value] ] [ -i size ] [ -I [ -K seconds ] ] [ -L ] [ -M ] [ -N ] [ -T ] [ -Y pathname ] infile rpcgen [ -c | -h | -m | -t | -Sc | - Ss | -Sm ] [ -o outfile ] [ infile ] rpcgen [ -s nettype ] [ -o outfile ] [ i fil ] tt tfil infile] rpcgen [ -n netid ] [ -o outfile ] [ infile ]

Dr. Roberto Gmez C.

Diapo. No. 40

20

RPC: Remote Procedure Call

Opciones rpcgen
-Dnombre[=valor] -I -K segundos -L -T -s transporte -o archivo-salida -c -h -l -m -t -a -b b -C -i tamao -N -Sc -Ss -Y path
Dr. Roberto Gmez C.

Define un smbolo (igual que #define) Genera un cdigo para soporte de inted en el servidor (SunOS 4.1) Servidor existe despus de segundos de inactividad Los errores del servidor sern impresos en el syslog Genera cdigo para soportar tablas de atencin de RPC Genera el cdigo del servidor que soporta el transporte Nombre del archivo de salida Slo genera rutinas XDR Slo genera el archivo de encabezado Slo genera los stubs del cliente Slo genera los stubs del servidor Genera la tabla de atencin de RPC Genera todos los archivos Modo backward de compatibilidad (genera cdigo para SunOS4 1) SunOS4.1) Genera lenguaje C de ANSI Tamao a partir del cual se empieza a generar cdigo in-line Soporta varios argumentos y llamado por valor Genera esqueleto cliente que usa procedimientos remotos Genera esqueleto servidor que define los procedimientos remotos Nombre del directorio para encontrar pre-procesadores de C (cpp)
Diapo. No. 41

RPC: Remote Procedure Call

Archivos generados por rpcgen

Comando a ejecutar:

$ rpcgen -C -a cuadro.x
Archivos generados: makefile.cuadro makefile para compilar el cdigo del cliente y del servidor. cuadro_clnt.c contiene el stub del cliente, el cual usualmente no es modificado. cliente modificado cuadro_svc.c contiene stub servidor cuadro.h contiene todos los tipos XDR generados a partir de la espcecificacin.

Dr. Roberto Gmez C.

Diapo. No. 42

21

RPC: Remote Procedure Call

Archivos generados por rpcgen

cuadro_client.c cuadro client c programa esqueleto del cliente con llamadas dummy al servicio remoto. Inserta cdigo para asignar los valores de los argumentos para el servicio remoto. cuadro_server.c contiene stubs para servicios remotos. Inserta cdigo para la versin local dentro de los stubs. cuadro_xdr.c contiene filtros XDR necesarios para los stubs del cliente y servidor.

Dr. Roberto Gmez C.

Diapo. No. 43

RPC: Remote Procedure Call

Archivos generados por rpcgen del archivo cuadro.x

cuadro_server.c archivos servidor cuadro_svc.c cuadro_xdr.c cuadro.x rpcgen cuadro.h makefile.cuadro fi cuadro_clnt.c cuadro_client.c archivos comunes

archivos cliente

Dr. Roberto Gmez C.

Diapo. No. 44

22

RPC: Remote Procedure Call

Paso III Insertar cdigo en archivos generados g por rpcgen

Dr. Roberto Gmez C.

Diapo. No. 45

RPC: Remote Procedure Call

Programa cuadro_client.c generado por rpcgen /* * This is sample code generated by rpcgen. * These are only templates and you can use them * as a guideline f id li for d developing your own f l i functions. ti */ #include "cuadro.h" void cuadro_prog_1(char *host) { CLIENT *clnt; int *result_1; int perimetro_1_arg; double *result_2; int area_1_arg;
Dr. Roberto Gmez C. Diapo. No. 46

23

RPC: Remote Procedure Call

#ifndef DEBUG clnt = clnt_create (host, CUADRO_PROG, CUADRO_VERS, "udp"); if (clnt == NULL) { clnt_pcreateerror (host); exit (1); } #endif # dif /* DEBUG */ result_1 = perimetro_1(&perimetro_1_arg, clnt); if (result_1 == (int *) NULL) { clnt_perror (clnt, "call failed"); } result_2 = area_1(&area_1_arg, clnt); if (result_2 == (double *) NULL) { clnt_perror (clnt, call failed ); clnt perror (clnt "call failed"); } #ifndef DEBUG clnt_destroy (clnt); #endif /* DEBUG */ }

Dr. Roberto Gmez C.

Diapo. No. 47

RPC: Remote Procedure Call

int main (int argc, char *argv[]) { char *host; if (argc < 2) { printf ("usage: %s server_host\n", argv[0]); exit (1); } host = argv[1]; cuadro_prog_1 (host); exit (0); }

Dr. Roberto Gmez C.

Diapo. No. 48

24

RPC: Remote Procedure Call

Versin final del programa cuadro_client.c #include "cuadro.h" int main (int argc, char *argv[]) { CLIENT *clnt; char *host; int a; int *per; double *sup; if (argc !=3 ) { fprintf(stderr,"Error, uso: %s a host \n",argv[0]); exit(1); } a = atoi(argv[1]); host = argv[2];
Dr. Roberto Gmez C. Diapo. No. 49

RPC: Remote Procedure Call

clnt = clnt_create (host, CUADRO_PROG, CUADRO_VERS, "udp"); if (clnt == NULL) { clnt_pcreateerror (host); exit (1); } p per = p perimetro_1(&a, clnt); ( , ); if (per == (int *) NULL) { clnt_perror (clnt, "call failed"); } sup = area_1(&a, clnt); if (sup == (double *) NULL) { clnt_perror (clnt, "call failed"); } printf("El perimetro del cuadrado es %d \n",*per); printf("El area del cuadrado es %d \n",*sup); clnt_destroy(clnt); }
Dr. Roberto Gmez C. Diapo. No. 50

25

RPC: Remote Procedure Call

Archivo esqueleto de cuadro_server.c generado por rpcgen


#include "cuadro.h" int * perimetro_1_svc(int *argp, struct svc_req *rqstp) { static int result; /* * insert server code here */ return &result; } double * area_1_svc(int *argp, struct svc_req *rqstp) { static double result; /* * insert server code here */ return &result; }
Dr. Roberto Gmez C. Diapo. No. 51

RPC: Remote Procedure Call

Versin final del programa servidor #include "cuadro.h" int * perimetro_1_svc(int *argp, struct svc_req *rqstp) { static int result; result = 4* (*argp); return &result; } double * area_1_svc(int *argp, struct svc_req *rqstp) { static double result; result = (*argp) * (*argp); return &result; }

Dr. Roberto Gmez C.

Diapo. No. 52

26

RPC: Remote Procedure Call

Paso IV Compilando y ejecutando los j programas

Dr. Roberto Gmez C.

Diapo. No. 53

RPC: Remote Procedure Call

1. Usar makefile generado por rpcgen: rogomez@costarica:281>make -f makefile.cuadro cc g -c cuadro_clnt.c -o cuadro_clnt.o d l t d l t cc -g -c cuadro_client.c -o cuadro_client.o cc -g -o cuadro_client cuadro_clnt.o cuadro_client.o -lnsl cc -g -c cuadro_svc.c -o cuadro_svc.o cc -g -c cuadro_server.c -o cuadro_server.o cc -g -o cuadro_server cuadro_svc.o cuadro_server.o -lnsl rogomez@costarica:282> 2. Se producen dos archivos:ejecutables: cuadro_client y cuadro_server

Dr. Roberto Gmez C.

Diapo. No. 54

27

RPC: Remote Procedure Call

2. Registrando al servidor de generacin de nmeros aleatorios


rogomez@costarica:282>cuadro_server rogomez@costarica:283>ps -aux | grep cuadro rogomez 8600 1.0 732 308 pts/4 R 23:10:13 0:00 grep cuadro rogomez 8068 3 4 1564 1012 3.4 ? S 23:10:27 0:00 cuadro server cuadro_server rogomez@costarica:284>

3. Ejecutando el programa cliente:


rogomez@cuba:26>cuadro_client costarica 5 El perimetro del cuadrado es 20 El area del cuadrado es 25 rogomez@cuba:27>cuadro_client rogomez@cuba:27>cuadro client costarica 2 El perimetro del cuadrado es 8 El area del cuadrado es 4 rogomez@cuba:28>

Dr. Roberto Gmez C.

Diapo. No. 55

RPC: Remote Procedure Call

Ejemplos de cdigos de stub

Dr. Roberto Gmez C.

Diapo. No. 56

28

RPC: Remote Procedure Call

Ejemplo de archivo stub-cliente: cuadro-clnt.c

/ /* * Please do not edit this file. * It was generated using rpcgen. */ #include <memory.h> /* for memset */ #include "cuadro.h" /* Default timeout can be changed using clnt_control() */ static struct timeval TIMEOUT = { 25, 0 };

Dr. Roberto Gmez C.

Diapo. No. 57

RPC: Remote Procedure Call

int * perimetro_1(int *argp, CLIENT *clnt) { static int clnt_res; memset((char *)&clnt_res, 0, sizeof(clnt_res)); if (clnt_call (clnt, PERIMETRO, (xdrproc_t) xdr_int, (caddr_t) argp, (xdrproc_t) xdr_int, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return (&clnt_res); }

Dr. Roberto Gmez C.

Diapo. No. 58

29

RPC: Remote Procedure Call

double * area_1(int *argp, CLIENT *clnt) { static double clnt_res; memset((char *)&clnt_res, 0, sizeof(clnt_res)); if (clnt_call (clnt, AREA, (xdrproc_t) xdr_int, (caddr_t) argp, (xdrproc_t) xdr_double, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return (&clnt_res); }

Dr. Roberto Gmez C.

Diapo. No. 59

RPC: Remote Procedure Call

Ejemplo archivo stub-servidor: cuadro_svc.c


/* * Please do not edit this file. * It was generated using rpcgen. */ #include "cuadro.h" #include <stdio.h> #include <stdlib.h> : : static void cuadro_prog_1(struct svc_req *rqstp, register SVCXPRT *transp) { union { int perimetro_1_arg; int area_1_arg; } argument; char *result; xdrproc_t _xdr_argument, _xdr_result; char *(*local)(char *, struct svc_req *);
Dr. Roberto Gmez C. Diapo. No. 60

30

RPC: Remote Procedure Call

switch (rqstp->rq_proc) { case NULLPROC: (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL); return; case PERIMETRO: _xdr_argument = (xdrproc_t) xdr_int; _xdr_result = (xdrproc_t) xdr_int; local = (char *(*)(char *, struct svc_req *)) perimetro_1_svc; break; case AREA: _xdr_argument = (xdrproc_t) xdr_int; _xdr_result = (xdrproc_t) xdr_double; local = (char *(*)(char *, struct svc_req *)) area_1_svc; break;
Dr. Roberto Gmez C. Diapo. No. 61

RPC: Remote Procedure Call

int main (int argc, char **argv) { register SVCXPRT *transp; : if (!svc register(transp CUADRO PROG CUADRO VERS (!svc_register(transp, CUADRO_PROG, CUADRO_VERS, cuadro_prog_1, IPPROTO_UDP)) { fprintf (stderr, "%s", "unable to register (CUADRO_PROG, CUADRO_VERS, udp)."); exit(1); } : svc_run (); fprintf (stderr, "%s", "svc_run returned"); exit (1); /* NOTREACHED */ }

Dr. Roberto Gmez C.

Diapo. No. 62

31

RPC: Remote Procedure Call

Ejemplo archivo encabezado: cuadro.h


/* * Please do not edit this file. * It was generated using rpcgen. */ #ifndef _CUADRO_H_RPCGEN #define _CUADRO_H_RPCGEN #include <rpc/rpc.h>

#ifdef __cplusplus extern "C" { #endif

#define CUADRO_PROG 0x31111111 #define CUADRO_VERS 1

Dr. Roberto Gmez C.

Diapo. No. 63

RPC: Remote Procedure Call

Ejemplo archivo encabezado: cuadro.h


#if defined(__STDC__) || defined(__cplusplus) #define PERIMETRO 1 extern int * perimetro_1(int *, CLIENT *); extern int * perimetro_1_svc(int *, struct svc_req *); #define AREA 2 #d fi extern double * area_1(int *, CLIENT *); extern double * area_1_svc(int *, struct svc_req *); extern int cuadro_prog_1_freeresult (SVCXPRT *,xdrproc_t,caddr_t); #else /* K&R C */ #define PERIMETRO 1 extern int * perimetro_1(); extern int * perimetro 1 svc(); perimetro_1_svc(); #define AREA 2 extern double * area_1(); extern double * area_1_svc(); extern int cuadro_prog_1_freeresult (); #endif /* K&R C */ : :
Dr. Roberto Gmez C. Diapo. No. 64

32

RPC: Remote Procedure Call

Llamadas con ms de un parmetro


problemas y soluciones

Dr. Roberto Gmez C.

Diapo. No. 65

RPC: Remote Procedure Call

Ejemplo aplicacin: solucin ecuaciones 2do. grado

a,b,c

: res1 = raiz(a,b,c) : res2 = complejo(a,b,c) :

r1, r2 real, imag

b 2 4ac 2a b (b 2 4 a c ) c o m p le x = j 2a 2a res =

Dr. Roberto Gmez C.

Diapo. No. 66

33

RPC: Remote Procedure Call

Diseo del servicio a nivel local


Cdigo del servidor Cdigo del cliente Contenido del archivo encabezado Compilacin y ejecucin

Dr. Roberto Gmez C.

Diapo. No. 67

RPC: Remote Procedure Call

Servidor Local
#include "encabeza.h" struct raiz resuelve(a,b,c) float a,b,c; { int temp; struct raiz res; res.error=0; temp = (b*b) - (4*a*c); if (temp < 0) res.error=1; ; else { res.r1 = (-b + sqrt((double)temp)) / (2*a); res.r2 = (-b - sqrt((double)temp)) / (2*a); } return res; }
Dr. Roberto Gmez C. Diapo. No. 68

struct complex complejo(a,b,c) float a,b,c; a b c; { float temp; struct complex res; temp = (b*b) - (4*a*c); res.real = (-b)/(2*a); g ( p) ( ); res.imag = (temp)/(2*a); return(res); }

34

RPC: Remote Procedure Call

Cliente Local
#include "encabeza.h" main(argc, argv) int argc; char *argv[]; struct complex rescom; struct raiz result; float a,b,c; if (argc != 4) { fprintf(stderr,"Error, uso: %s a b c\n", argv[0]); [0]) exit(1); } a=(float)atoi(argv[1]); b=(float)atoi(argv[2]); c=(float)atoi(argv[3]);
Dr. Roberto Gmez C. Diapo. No. 69

result=resuelve(a,b,c); if ( ! result.error ) { printf("La solucion de (%.1f %.1f %.1f)\n",a,b,c); (% 1f % 1f % 1f)\n" a b c); printf("es %.5f y %.5f\n",result.r1, result.r2); } else { rescom=complejo(a,b,c); printf("La solucion de (%.1f %.1f %.1f)\n",a,b,c); printf("es (%.5f %.5fj) y (%.5f %.5fj)\n", rescom.real, rescom.imag, rescom.real, (-1)*rescom.imag); ( 1) rescom.imag); } }

RPC: Remote Procedure Call

Archivo de encabezado local

#include <stdio.h> #include <math.h> struct raiz { float r1; float r2; int error; }; struct complex { float l fl t real; float imag; };

Dr. Roberto Gmez C.

Diapo. No. 70

35

RPC: Remote Procedure Call

Compilando y ejecutando

rogomez@armagnac:156>cc cliente.c servicio.c -lm -o toto rogomez@armagnac:157>toto 1 -1 1 @ 157>t t 1 La solucion de (1.0 -1.0 1.0) es (0.50000 -1.50000j) y (0.50000 1.50000j) rogomez@armagnac:158>toto 1 9 14 La solucion de (1.0 9.0 14.0) es -2.00000 y -7.00000 rogomez@armagnac:159>toto 1 1 1 La solucion de (1.0 1.0 1.0) ( ) es (-0.50000 -1.50000j) y (-0.50000 1.50000j) rogomez@armagnac:160>toto 1 2 2 La solucion de (1.0 2.0 2.0) es (-1.00000 -2.00000j) y (-1.00000 2.00000j) rogomez@armagnac:161>
Dr. Roberto Gmez C. Diapo. No. 71

RPC: Remote Procedure Call

Diseo del sistema a nivel remoto


Especificacin del archivo raiz.x Compilacin con rpcgen Reescritura del archivo servidor remoto Reescritura del archivo cliente remoto R it d l hi li t t Compilacin y ejecucin

Dr. Roberto Gmez C.

Diapo. No. 72

36

RPC: Remote Procedure Call

Archivo especificacin raiz.x


struct datos{ float a; float b; float c; }; struct raiz { float r1; float r2; int error; } }; struct complex { float real; float imag; };

program RAIZ PROG { RAIZ_PROG version RAIZ_VERS{ struct raiz RESUELVE(datos) = 1; struct complex COMPLEJO(datos) = 2; } = 1; } = 0x31112345;

Dr. Roberto Gmez C.

Diapo. No. 73

RPC: Remote Procedure Call

Esqueleto del servidor


#include "raiz.h" #include <stdio.h> #include <stdlib.h> /* getenv, exit */ #include <signal.h> struct raiz * resuelve_1_svc(datos *argp, struct svc_req *rqstp) { static struct raiz result; /* * insert server code here */ return (&result); }
Dr. Roberto Gmez C. Diapo. No. 74

struct complex * l j 1 (d t * complejo_1_svc(datos *argp, struct svc_req *rqstp) { static struct complex result; /* * insert server code here */ return (&result); }

37

RPC: Remote Procedure Call

Servidor remoto
#include "raiz.h" struct raiz * resuelve_1_svc(datos *argp, struct svc_req *rqstp) { static struct raiz res; int temp; struct complex * complejo_1_svc(datos *argp, struct svc_req *rqstp) l j 1 (d t * t t * t ) { static struct complex res; float temp;

temp = (argp->b*argp->b) - (4*argp->a*argp->c); res.error=0; res.real = (-argp->b)/(2*argp->a); temp = (argp->b*argp->b) - (4*argp->a*argp->c); res.imag = (temp)/(2*argp->a); if (temp < 0) res.error=1; return (&res); else { } res.r1=(-argp->b + sqrt((double)temp))/ (2*argp->a); res.r2=(-argp->b - sqrt((double)temp))/(2*argp->a); } return (&res); }

Dr. Roberto Gmez C.

Diapo. No. 75

RPC: Remote Procedure Call

Esqueleto del cliente


#include "raiz.h" #include <stdio.h> #include <stdlib.h> /* getenv, exit */ void raiz_prog_1(char *host) { CLIENT *clnt; struct raiz *result_1; datos resuelve_1_arg; struct complex *result_2; datos complejo_1_arg; #ifndef DEBUG clnt = clnt_create(host, RAIZ_PROG, RAIZ_VERS, "netpath"); if (clnt == (CLIENT *) NULL) { clnt_pcreateerror(host); exit(1); } #endif /* DEBUG */
Dr. Roberto Gmez C. Diapo. No. 76

38

RPC: Remote Procedure Call

#ifndef #endif }

result_1 = resuelve_1(&resuelve_1_arg, clnt); if (result_1 == (struct raiz *) NULL) { clnt_perror(clnt, "call failed"); } result_2 = complejo_1(&complejo_1_arg, clnt); if (result_2 == (struct complex *) NULL) { ( ( p ) ) clnt_perror(clnt, "call failed"); } DEBUG clnt_destroy(clnt); /* DEBUG */ main(int argc, char *argv[]) { char *host; if (argc < 2) { printf("usage: %s server_host\n", argv[0]); exit(1); } host = argv[1]; raiz_prog_1(host); }
Diapo. No. 77

Dr. Roberto Gmez C.

RPC: Remote Procedure Call

Cliente remoto
if (argc !=5) { printf("uso: %s host a b c \n", argv[0]); exit(1); } host = argv[1]; data.a =(float)atoi(argv[2]); data.b =(float)atoi(argv[3]); data.c =(float)atoi(argv[4]); clnt = clnt_create(host, RAIZ_PROG, RAIZ_VERS, "netpath"); if (clnt == (CLIENT *) NULL) { clnt_pcreateerror(host); exit(1); } raices = resuelve_1(&data, clnt); if (raices == (struct raiz *) NULL) { clnt_perror(clnt, "call failed"); }

#include "raiz h" raiz.h

CLIENT *clnt; struct raiz *raices; datos data; struct complex *rescom; main(argc, argv) int argc; g ; char *argv[]; { char *host;

Dr. Roberto Gmez C.

Diapo. No. 78

39

RPC: Remote Procedure Call

if ( ! raices->error ) { printf("La solucion de (%.1f %.1f %.1f)\n",data.a,data.b,data.c); printf("es %.5f y %.5f\n",raices->r1, raices->r2); } else { rescom = complejo_1(&data, clnt); if (rescom == (struct complex *) NULL) { clnt_perror(clnt, "call failed"); } printf("La solucion de (%.1f %.1f %.1f)\n",data.a,data.b,data.c); printf("es (%.5f %.5fj) y (%.5f %.5fj)\n",rescom->real, rescom->imag, rescom->real, (-1)*(rescom->imag)); } clnt_destroy(clnt); }

Dr. Roberto Gmez C.

Diapo. No. 79

RPC: Remote Procedure Call

Compilacin
rogomez@costarica:81> make -f makefile.raiz cc -g -c raiz_clnt.c -o raiz_clnt.o cc -g -c raiz client c -o raiz client o raiz_client.c raiz_client.o cc -g -c raiz_xdr.c -o raiz_xdr.o cc -g -o raiz_client raiz_clnt.o raiz_client.o raiz_xdr.o -lnsl cc -g -c raiz_svc.c -o raiz_svc.o cc -g -c raiz_server.c -o raiz_server.o raiz_server.c: In function `resuelve_1_svc': raiz_server.c:20: warning: type mismatch in implicit declaration for built-in function `sqrt' cc -g -o raiz_server raiz_svc.o raiz_server.o raiz_xdr.o -lnsl Undefined first referenced symbol in file sqrt raiz_server.o ld: fatal: Symbol referencing errors. No output written to raiz_server make: *** [raiz_server] Error 1 [1] - Done /usr/4local/bin/xvile raiz.x rogomez@costarica:82>
Dr. Roberto Gmez C. Diapo. No. 80

40

RPC: Remote Procedure Call

Makefile generado por rpcgen


# This is a template makefile generated # Parameters CLIENT = raiz_client SERVER = raiz_server SOURCES_CLNT.c = SOURCES_CLNT.h = SOURCES_SVC.c = SOURCES_SVC.h = SOURCES.x = raiz.x TARGETS_SVC.c = raiz_svc.c raiz_server.c raiz_xdr.c TARGETS_CLNT.c = raiz_clnt.c raiz_client.c raiz_xdr.c TARGETS = raiz.h raiz_xdr.c raiz_clnt.c raiz_svc.c raiz_client.c raiz_server.c OBJECTS_CLNT = $(SOURCES_CLNT.c:%.c=%.o) $(TARGETS_CLNT.c:%.c=%.o) OBJECTS_SVC = $(SOURCES_SVC.c:%.c=%.o) $(TARGETS_SVC.c:%.c=%.o) # Compiler flags CFLAGS += -g LDLIBS += -lnsl -lm RPCGENFLAGS =
Dr. Roberto Gmez C. Diapo. No. 81

by rpcgen

RPC: Remote Procedure Call

Compilando de nuevo

rogomez@costarica:82> !ma g @ make -f makefile.raiz cc -g -o raiz_server raiz_svc.o raiz_server.o raiz_xdr.o -lnsl -lm rogomez@costarica:83>

Dr. Roberto Gmez C.

Diapo. No. 82

41

RPC: Remote Procedure Call

Ejecucin mquina servidor


rogomez@cuba:28>raiz_server rogomez@cuba:29>

Ejecucin mquina cliente


rogomez@costarica:84>raiz_client cuba 1 -1 1 La solucion de (1.0 -1.0 1.0) es (0.50000 -1.50000j) y (0.50000 1.50000j) rogomez@costarica:85>raiz_client cuba 1 9 14 La solucion de (1.0 9.0 14.0) es -2.00000 y -7.00000 rogomez@costarica:86>raiz_client cuba 1 1 1 @ i 86 i li b La solucion de (1.0 1.0 1.0) es (-0.50000 -1.50000j) y (-0.50000 1.50000j) rogomez@costarica:87>raiz_client cuba 1 2 2 La solucion de (1.0 2.0 2.0) es (-1.00000 -2.00000j) y (-1.00000 2.00000j) rogomez@costarica:88>raiz_client cuba 1 -3 40 La solucion de (1.0 -3.0 40.0) es (1.50000 -75.50000j) y (1.50000 75.50000j) rogomez@costarica:89>raiz_client rogomez@costarica:89>raiz client cuba 1 -3 -40 La solucion de (1.0 -3.0 -40.0) es 8.00000 y -5.00000 rogomez@costarica:90>raiz_client cuba 4 2 -1 La solucion de (4.0 2.0 -1.0) es 0.30902 y -0.80902

Dr. Roberto Gmez C.

Diapo. No. 83

42