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 [Link] 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, [Link], 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
[Link] / 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: [Link] 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 [Link] 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 [Link] 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; [Link]=0; temp = (b*b) - (4*a*c); if (temp < 0) [Link]=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); [Link] = (-b)/(2*a); g ( p) ( ); [Link] = (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 ( ! [Link] ) { 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", [Link], [Link], [Link], (-1)*[Link]); ( 1) [Link]); } }
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); [Link]=0; [Link] = (-argp->b)/(2*argp->a); temp = (argp->b*argp->b) - (4*argp->a*argp->c); [Link] = (temp)/(2*argp->a); if (temp < 0) [Link]=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 [Link] 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 [Link] 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