RPC

42
1 RPC: Remote Procedure Call petición El Llamado de procedimientos remotos respuesta Dr. Roberto Gómez C. Diapo. No. 1 Principios teóricos y programación en Unix RPC: Remote Procedure Call cliente servidor (leer FA45 de arch1) Cliente/Servidor: envío/recepción mensajes cliente servidor (34759037F3247A) cliente servidor (ack) Dr. Roberto Gómez C. Diapo. No. 2 cliente servidor (ack) cliente servidor

Transcript of RPC

Page 1: RPC

1

RPC: Remote Procedure Call

petición

El Llamado de procedimientos remotos

respuesta

Dr. Roberto Gómez C. Diapo. No. 1

Principios teóricos y programación en Unix

RPC: Remote Procedure Call

cliente servidor(leer FA45 de arch1)

Cliente/Servidor: envío/recepción mensajes

cliente servidor(34759037F3247A)

cliente servidor(ack)

Dr. Roberto Gómez C. Diapo. No. 2

cliente servidor(ack)

cliente servidor

Page 2: RPC

2

RPC: Remote Procedure Call

Desventajas paradigma envio/recepción mensajes

• Paradigma envio/recepción es del tipo Entrada/Salida– procedimientos send(), receive() están dedicados a realizar

E/S• E/S no es un concepto clave para los sistemas

centralizados; pero si para la computación o cálculo distribuido

Dr. Roberto Gómez C. Diapo. No. 3

• Objetivo: hacer el cálculo distribuido como si fuera cálculo centralizado

• Cálculo centralizado: llamadas de procedimientos y/o funciones

RPC: Remote Procedure Call

Ejecución 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 localesal main

Variables localesal main

Variables localesal main

bytesbuffd

dirección regreso

SP SP

SP

:}

:} }

Dr. Roberto Gómez C. Diapo. No. 4

a) Stack antes llamada read b) Stack durante ejecución read c) Stack después llamada read

Page 3: RPC

3

RPC: Remote Procedure Call

Tipos de paso de parámetros

• Por valor– en el stack se copia el valor del parámetroen el stack se copia el valor del parámetro– valor de salida es igual al valor de entrada

• Por referencia– en el stack se almacena la dirección de la variable– es posible modificar el valor del parámetro

• call-by-copy/restorese copia el valor de la variable en el stack (como en paso por valor)

Dr. Roberto Gómez C. Diapo. No. 5

– se copia el valor de la variable en el stack, (como en paso por valor)– al final de la ejecución 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

RPC: Remote Procedure Call

El RPC

• Creado por Birrel & Nelson en 1984• Permiten a los programas llamar procedimientos localizados en• Permiten a los programas llamar procedimientos localizados en

otras máquinas• Un proceso x en una máquina A, puede llamar un procedimiento

localizado en una máquina B• Información puede llevarse del proceso invocador al invocado

dentro de los parámetros

Dr. Roberto Gómez C. Diapo. No. 6

• Ningún mensaje u operación de E/S es visible para el programador• Problemas a resolver:

– procedimientos invocador e invocado se ejecutan en diferentes máquinas, i.e. diferentes direcciones y posiblemente diferentes arquitecturas

– ambas máquinas pueden fallar

Page 4: RPC

4

RPC: Remote Procedure Call

Máquina Cliente Máquina Servidorstub delcliente

stub delservidor

Principio funcionamiento del RPC

cliente

call

return

Packparámetros

Unpackresultado

Unpackparámetros

Packresultado

servidor

call

return

Dr. Roberto Gómez C. Diapo. No. 7

kernel kernel

Mensaje transportado en la red

RPC: Remote Procedure Call

Proveniencia de los stubs

• Varios sistemas: generados automáticamente• Varios sistemas: generados automáticamente– rpcgen de Sun– generacion archivos esqueleto, para cliente y servidor, a

partir de un compilador y de la especificación del servicio

• Rutinas de especificación de stubs

Dr. Roberto Gómez C. Diapo. No. 8

– rutinas de alto y bajo nivel– posibilidad de definir más aspectos

• timeouts• protocolos

Page 5: RPC

5

RPC: Remote Procedure Call

Máquina Cliente Máquina Servidorstubs

El paso de parámetros

sum sum47

47

mensaje mensaje sum(i,j)int i,j;{

return(i+j);}

::

n=sum(4,7);::

Dr. Roberto Gómez C. Diapo. No. 9

kernel kernel

RPC: Remote Procedure Call

• Tipos de paso de parámetros– por valor

Aspectos a considerar en el paso de parámetros

por valor– por referencia– call-by-copy/restore

• Problemas a resolver– diferencias entre representación de datos– diferencias en formatos– paso de apuntadores, (estructuras complejas)

Dr. Roberto Gómez C. Diapo. No. 10

paso de apuntadores, (estructuras complejas)

• Optimización– especificación parámetros de entrada y salida– registros para paso de apuntadores

Page 6: RPC

6

RPC: Remote Procedure Call

#include <header.h>specification of file server, version 3.1

Binding dinámico: especificación formal servidor

specification of file_server, version 3.1long 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);

Dr. Roberto Gómez C. Diapo. No. 11

int delete(in char[MAX_PATH]);end.

RPC: Remote Procedure Call

Binder

Registro del servidor

SERVIDORBinder

Sistema DistribuidoNombreNum. versiónId único

Dr. Roberto Gómez C. Diapo. No. 12

Id.únicoManejador, (handler)

Otros (autentificación)

Page 7: RPC

7

RPC: Remote Procedure Call

servicio NOdisponible

error3

Petición cliente

procesosolicitante

stub

Binder

serviciodisponible

disponible

1

2 3’

Dr. Roberto Gómez C. Diapo. No. 13

stubcliente

disponible

Nombre, Num. versión,Id.único, Manejador

RPC: Remote Procedure Call

Parámetros entrada/salida de la interfaz binder

Acción Parámetros Entrada Salida

Registrar Nombre, versión, manejador, id único

Suprimir Nombre, versión, id único

Buscar Nombre versión Manejador id único

Dr. Roberto Gómez C. Diapo. No. 14

Buscar Nombre, versión Manejador, id único

Page 8: RPC

8

RPC: Remote Procedure Call

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

111

Registro y localización de un servidor RPC

Prog Vers PuertoPaso 2: ‘Dondeesta PRIMEPROGVersion 1?’

Puerto1061

Servidor Portmapper

Dr. Roberto Gómez C. Diapo. No. 15

Paso 4: ‘Llamaprocedimiento 1.Aquí están losdatos

Paso 3: ‘Esta en el puerto 1061’

Cliente

RPC: Remote Procedure Call

Binding y nombramiento servicios

Convención para números de programa de Sun

00000000 - 1FFFFFFF definido por y administrado por Sun20000000 3 d fi id l i20000000 - 3FFFFFFF definido por el usuario40000000 - 5FFFFFFF de tránsito, (aplicaciones con generación de

números)60000000 - FFFFFFFF reservado para un futuro uso

El comando rpcinfo

Realiza una llamada RPC a un servidor RPC y reporta lo que encuentra

Dr. Roberto Gómez C. Diapo. No. 16

Realiza una llamada RPC a un servidor RPC y reporta lo que encuentra.Dependiendo de los parámetros es posible:

- listar todos los servicios de un RPC en un host- listar todos los servicios RPC registrados con rpcbind versión 2- realizar una llamada RPC al procedimiento 0 de un determinado programay de una determinada versión en un host dado.

Page 9: RPC

9

RPC: Remote Procedure Call

Sintaxis y opciones rpcinfoSintaxis

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 versnumrpcinfo -d [-T transport ] prognum versnum

Algunas opciones-T especifica el transporte sobre el cual el servicio es requerido-a utiliza el parámetro como la dirección universal en el transporteb realiza un broadcast al procedimiento 0 de los prognum y versnum

Dr. Roberto Gómez C. Diapo. No. 17

-b realiza un broadcast al procedimiento 0 de los prognum y versnumespecificados 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 ningún host tomo el host local

RPC: Remote Procedure Call

Ejemplo rpcinfoarmagnac:45>rpcinfo -s totoprogram version(s) netid(s) service owner100000 2,3,4 udp, tcp, tictls, ticosord, ticots rpcbin superuser100029 2,1 ticots, ticotsord, ticlts keyserv superuser100029 2,1 ticots, ticotsord, ticlts keyserv superuser100078 4 ticots, ticotsord, ticlts kerbd superuser100087 10 udp admind superuser100011 1 ticlts, udp rquotad superuser100002 3,2 ticlts, udp rusersd superuser100099 1 ticots, ticotsord, ticlts - superuser100012 1 ticlts, udp sprayd superuser100008 1 ticlts, udp walld superuser100001 4 3 2 i l d d

Dr. Roberto Gómez C. Diapo. No. 18

100001 4,3,2 ticlts, udp rstad superuser100024 1 ticots, ticotsord, ticlts, tcp, udp status superuser100021 2,3,1 ticots, ticotsord, ticlts, tcp, udp nlockmgr superuser134177279 1,2 tcp - 5001armagnac:46>

Page 10: RPC

10

RPC: Remote Procedure Call

Máquina ServidoraPrograma Servidor

procedimientos servicio

función dispatchPortmapper

Pasos de una Llamada a un Procedimiento Remoto

función dispatchPortmapper

callrpc ()

Dr. Roberto Gómez C. Diapo. No. 19

host, programa, versión,procedimiento, argumentos

errores o resultados

Máquina Cliente

Programa Cliente

RPC: Remote Procedure Call

AplicaciónUsuario

4. TRANSPORTE

5-7. SESIÓN

Niveles del Protocolo TCP/IP

Interface

UDPTCP

IP

1-2.ENLACE / FÍSICO

3. RED

4. TRANSPORTE

Dr. Roberto Gómez C. Diapo. No. 20

InterfaceHardware

R E D

NIVELESOSI

Page 11: RPC

11

RPC: Remote Procedure Call

Pasos en la ejecución 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 envía el mensaje al kernel remoto.4. El kernel remoto pasa el mensaje al server-stub.5. El server-stub desempaca los parámetros 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.

Dr. Roberto Gómez C. Diapo. No. 21

8. El kernel remoto envía 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.

RPC: Remote Procedure Call

Máquina Cliente Máquina Servidor

Cliente Llamar procedimientos stub Realizar sevicio Servidor Servidor

Ruta crítica de cliente a servidor

StubCliente

Kernel

Preparar mensaje bufferMarshall los parámetros en el bufferPoner los encabezados a los mensajesPasar al kernel

Contexto switch al kernelCopiar mensaje en el kernelDeterminar direcciones destino

Llamar al servidorPoner los parametros en el stackUnmarshall parametros

Switch contexto a server stubCopiar mensaje en server stubVer si stub esta esperando

ServerStub

Kernelá i

Dr. Roberto Gómez C. Diapo. No. 22

KernelMáquina

Determinar direcciones destinoPoner dirección en encabezado mensajeEstablecer la interfaz de la redHechar a andar el timer

Ver si stub esta esperandoDecidir a que stub darseloChecar el paquete para validaciónInterrupción de proceso

Máquina

Page 12: RPC

12

RPC: Remote Procedure Call

EL RPC DE SUNEL RPC DE SUN

El rpcgen y el lenguaje de especificación RPCL

Ejemplos:

- Llamada procedimientos con un solo parámetro

Dr. Roberto Gómez C. Diapo. No. 23

- Llamada remota con múltiples parámetros

RPC: Remote Procedure Call

user developedEspecificación RPC

Desarrollo de una Aplicación de Red con un

Compilador de Protocolo RPC

Compilador RPC

stub del cliente stub del servidor

compilarcompilar

RPC and datarepresentation

libraries

filtros comunesy archivo

encabezado

Dr. Roberto Gómez C. Diapo. No. 24

código cliente código servidor

compilary

ligary

ligar

funcionescliente

funcionesservidor

librerías de RPC yde representación

de datos

Page 13: RPC

13

RPC: Remote Procedure Call

-ComentariosIgual que en lenguaje C

El lenguaje RPC (RPCL)

RPCL Equivalente en C

-Constantes simbólicasconst MAX_SIZE = 8192 #define MAX_SIZE 8192

- Enumeracionesenum colores{ROJO = 0, VERDE=1, enum colores { ROJO=0, VERDE=1,

AZUL=2}; AZUL=2};typedef enum colores colores;

Booleanos

Dr. Roberto Gómez C. Diapo. No. 25

-Booleanosbool termino; bool_t termino;

-Arreglos tamaño fijoint alumnos[10]; int alumnos[10];

RPC: Remote Procedure Call

-Arreglos tamaño variableint a <12> /* a los mas 12 elementos*/

struct {u_int a_len;int *a_val;

} a;

RPCL Equivalente en C

} a;int b<> /* cualquier numero de elementos */

struct {u_int b_len;int *b_val;

} b;Tamaño máximo = parámetro maxsize en xdr_array()No especificación máximo => máximo valor puede tomar u_int;Solo es posible trabajar con arreglos unidimensionales

Dr. Roberto Gómez C. Diapo. No. 26

-Estructurasstruct punto { struct punto {

int x; int x;int y; int y;

}; };typedef struct punto punto;

Page 14: RPC

14

RPC: Remote Procedure Call

-StringsNo existen en C, RPCL convención de terminación en NULLTamaño especifica máximo número caracteres permitidos en stringNo especificado => tamaño máximo = máximo valor u_int;

string nombre <32> char *nombre;string nombresote<> char *nombresote;

-UnionesMás cercanas al registro variante de Pascalunion resultado switch (int errno){ struct resultado {

case 0: int errno;opaque data[1024]; union {

1 h d t [1024]

Dr. Roberto Gómez C. Diapo. No. 27

case 1: char data[1024]int valor; int valor;

default: } resultado_u;void };

}; typedef struct resultado resultado;

RPC: Remote Procedure Call

-Datos opacosUsados para describir datos que no tienen tipoDato puede ser de tamaño fijo o variable

opaque diskblock[512]; char diskblock[512];opaque filedata<1024> struct {

RPCL Equivalente en C

u_int filedata_len;char *filedata_val;

} filedata

-Typedef RPCLMisma sintaxis que en CEjemplo define un fname_type usado para declarar strings de nombres de archivos que tienen una longitud máxima de 255 caracteres

Dr. Roberto Gómez C. Diapo. No. 28

typedef string fname_type <255> typedef char *fname_type;

- IdentificadoresCompuestos de letras, números y el underscoreDistinción entre mayusculas y minusculas

Page 15: RPC

15

RPC: Remote Procedure Call

- Diseñar programa usando llamadas locales.

Pasos para convertir llamadas locales en remotas

p g- Restructurar cada función de tal forma que sólo tenga un parámetro pasado por valor y asegurarse que trabaja bien localmente.- Crear un archivo de especificación con extensión .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 especificación.- Insertar programa que va a llamar a la función en el archivo _client.c generado por rpcgen.

Dr. Roberto Gómez C. Diapo. No. 29

- Insertar código función 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.

RPC: Remote Procedure Call

Ejemplo aplicación: perímetro y área de un cuadro

perimetro (a)area(a)

intdouble

:per = perimetro(20)

:

Dr. Roberto Gómez C. Diapo. No. 30

: sup = area(20

:

:4*a

:a*a

:

Page 16: RPC

16

RPC: Remote Procedure Call

Paso I

Diseño del i i l l

Dr. Roberto Gómez C. Diapo. No. 31

servicio local

RPC: Remote Procedure Call

#include <stdio.h>

main(int argc, char *argv[]){

Calculo perímetro y área de un cuadrado

int perimetro(int a){return 4*a;

}{int a;int per;double sup;if (argc !=2 ) {fprintf(stderr,"Error,uso: %s a \n",argv[0]);exit(1);

}

}double area (int a){

return a*a;}

Dr. Roberto Gómez C. Diapo. No. 32

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);

}

Page 17: RPC

17

RPC: Remote Procedure Call

Código del servidor local: servidor.c

#include “cuad.h”

int perimetro(int a){{int res;res = 4*a;return(res);

}

double area(int a){

Dr. Roberto Gómez C. Diapo. No. 33

double res;res = a*a;return(res);

}

RPC: Remote Procedure Call

Código del cliente local: cliente.c

#include <stdio.h>#include “cuad.h”main(int argc, char *argv[]){

int a;int a;int per;double sup;if (argc !=2 ) {fprintf(stderr,"Error, uso: %s a \n",argv[0]);exit(1);

}a = atoi(argv[1]);

Dr. Roberto Gómez C. Diapo. No. 34

per = perimetro(a);sup = area(a);

printf("El perimetro del cuadrado es %d \n",per); printf("El area del cuadrado es %d \n",sup);

}

Page 18: RPC

18

RPC: Remote Procedure Call

El archivo de encabezado cuad.h

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

Dr. Roberto Gómez C. Diapo. No. 35

RPC: Remote Procedure Call

Compilando y ejecutando

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

Dr. Roberto Gómez C. Diapo. No. 36

El area del cuadrado es 4rogomez@cuba:96>

Page 19: RPC

19

RPC: Remote Procedure Call

Paso II

Diseño del archivode configuración y

Dr. Roberto Gómez C. Diapo. No. 37

g yuso de rpcgen

RPC: Remote Procedure Call

El archivo de especificación cuadro.x

/*Nombre archivo: cuadro.x */

program CUADRO_PROG {version CUADRO_VERS{

int PERIMETRO(int) = 1;double AREA(int) = 2;

} = 1;

Dr. Roberto Gómez C. Diapo. No. 38

} = 1;} = 0x311445566;

Page 20: RPC

20

RPC: Remote Procedure Call

Números de programas remotos

00000000 - 1FFFFFFF Sun Permanente Pública20000000 - 3FFFFFFF Local Desconocido Local40000000 - 5FFFFFFF Desarrollador Temporal Local50000000 - 7FFFFFFF Reservado80000000 - 9FFFFFFF ReservadoA0000000 - BFFFFFFF Reservado

Rango (hexadecimal) Administrador Tiempo de vida Distribución

Dr. Roberto Gómez C. Diapo. No. 39

C0000000 - DFFFFFFF ReservadoE0000000 - FFFFFFFF Reservado

RPC: Remote Procedure Call

Sintáxis del rpcgen

rpcgen infilerpcgen [ -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 ][ tt ] [ tfil ] [ i fil ]

Dr. Roberto Gómez C. Diapo. No. 40

rpcgen [ -s nettype ] [ -o outfile ] [ infile]rpcgen [ -n netid ] [ -o outfile ] [ infile ]

Page 21: RPC

21

RPC: Remote Procedure Call

Opciones rpcgen

-Dnombre[=valor] Define un símbolo (igual que #define)-I Genera un código para soporte de inted en el servidor (SunOS 4.1)-K segundos Servidor existe después de segundos de inactividad-L Los errores del servidor serán impresos en el syslog-T Genera código para soportar tablas de atención de RPC-s transporte Genera el código del servidor que soporta el transporte-o archivo-salida Nombre del archivo de salida-c Sólo genera rutinas XDR-h Sólo genera el archivo de encabezado-l Sólo genera los stubs del cliente-m Sólo genera los stubs del servidor-t Genera la tabla de atención de RPC-a Genera todos los archivos b Modo backward de compatibilidad (genera código para SunOS4 1)

Dr. Roberto Gómez C. Diapo. No. 41

-b Modo backward de compatibilidad (genera código para SunOS4.1)-C Genera lenguaje C de ANSI-i tamaño Tamaño a partir del cual se empieza a generar código in-line-N Soporta varios argumentos y llamado por valor-Sc Genera esqueleto cliente que usa procedimientos remotos-Ss Genera esqueleto servidor que define los procedimientos remotos-Y path Nombre del directorio para encontrar pre-procesadores de C (cpp)

RPC: Remote Procedure Call

Archivos generados por rpcgen

Comando a ejecutar:

$ rpcgen -C -a cuadro.x

Archivos generados:

makefile.cuadromakefile para compilar el código del cliente y del servidor.

cuadro_clnt.ccontiene el stub del cliente el cual usualmente no es modificado

Dr. Roberto Gómez C. Diapo. No. 42

contiene el stub del cliente, el cual usualmente no es modificado.cuadro_svc.c

contiene stub servidorcuadro.h

contiene todos los tipos XDR generados a partir de la espcecificación.

Page 22: RPC

22

RPC: Remote Procedure Call

Archivos generados por rpcgen

cuadro client ccuadro_client.cprograma esqueleto del cliente con llamadas dummy al servicio remoto.Inserta código para asignar los valores de los argumentos para el servicioremoto.

cuadro_server.ccontiene stubs para servicios remotos. Inserta código para la versión localdentro de los stubs.

Dr. Roberto Gómez C. Diapo. No. 43

cuadro_xdr.ccontiene filtros XDR necesarios para los stubs del cliente y servidor.

RPC: Remote Procedure Call

Archivos generados por rpcgen del archivo cuadro.x

cuadro server.c

cuadro.x rpcgen

_

cuadro_svc.c

cuadro_xdr.c

cuadro.h

fi

archivos servidor

archivos comunes

Dr. Roberto Gómez C. Diapo. No. 44

makefile.cuadro

cuadro_clnt.c

cuadro_client.carchivos cliente

Page 23: RPC

23

RPC: Remote Procedure Call

Paso III

Insertar código enarchivos generados

Dr. Roberto Gómez C. Diapo. No. 45

gpor rpcgen

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* id li f d l i f ti* as a guideline for developing your own functions.*/

#include "cuadro.h"

voidcuadro_prog_1(char *host){

Dr. Roberto Gómez C. Diapo. No. 46

{CLIENT *clnt;int *result_1;int perimetro_1_arg;double *result_2;int area_1_arg;

Page 24: RPC

24

RPC: Remote Procedure Call

#ifndef DEBUGclnt = clnt_create (host, CUADRO_PROG, CUADRO_VERS, "udp");if (clnt == NULL) {

clnt_pcreateerror (host);exit (1);

}# dif /* */#endif /* 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");

Dr. Roberto Gómez C. Diapo. No. 47

clnt_perror (clnt, call failed );}

#ifndef DEBUGclnt_destroy (clnt);

#endif /* DEBUG */}

RPC: Remote Procedure Call

intmain (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 Gómez C. Diapo. No. 48

}

Page 25: RPC

25

RPC: Remote Procedure Call

Versión 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;

Dr. Roberto Gómez C. Diapo. No. 49

if (argc !=3 ) {fprintf(stderr,"Error, uso: %s a host \n",argv[0]);exit(1);

}a = atoi(argv[1]);host = argv[2];

RPC: Remote Procedure Call

clnt = clnt_create (host, CUADRO_PROG, CUADRO_VERS, "udp");if (clnt == NULL) {

clnt_pcreateerror (host);exit (1);

}

per = perimetro 1(&a, clnt);p p _ ( , );if (per == (int *) NULL) {clnt_perror (clnt, "call failed");

}

sup = area_1(&a, clnt);if (sup == (double *) NULL) {clnt_perror (clnt, "call failed");

}

Dr. Roberto Gómez C. Diapo. No. 50

printf("El perimetro del cuadrado es %d \n",*per); printf("El area del cuadrado es %d \n",*sup);

clnt_destroy(clnt);}

Page 26: RPC

26

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){

Dr. Roberto Gómez C. Diapo. No. 51

{static double result;/** insert server code here*/return &result;

}

RPC: Remote Procedure Call

Versión 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){

Dr. Roberto Gómez C. Diapo. No. 52

{static double result;result = (*argp) * (*argp);return &result;

}

Page 27: RPC

27

RPC: Remote Procedure Call

Paso IV

Compilando y ejecutando los

Dr. Roberto Gómez C. Diapo. No. 53

jprogramas

RPC: Remote Procedure Call

1. Usar makefile generado por rpcgen:

rogomez@costarica:281>make -f makefile.cuadrod l t d l tcc –g -c cuadro_clnt.c -o cuadro_clnt.o

cc -g -c cuadro_client.c -o cuadro_client.occ -g -o cuadro_client cuadro_clnt.o cuadro_client.o -lnsl cc -g -c cuadro_svc.c -o cuadro_svc.occ -g -c cuadro_server.c -o cuadro_server.occ -g -o cuadro_server cuadro_svc.o cuadro_server.o -lnslrogomez@costarica:282>

Dr. Roberto Gómez C. Diapo. No. 54

2. Se producen dos archivos:ejecutables:

cuadro_client y cuadro_server

Page 28: RPC

28

RPC: Remote Procedure Call

2. Registrando al servidor de generación de números aleatorios

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

3. Ejecutando el programa cliente:

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

Dr. Roberto Gómez C. Diapo. No. 55

rogomez@cuba:27>cuadro_client costarica 2El perimetro del cuadrado es 8El area del cuadrado es 4rogomez@cuba:28>

RPC: Remote Procedure Call

Ejemplosde

códigosde stub

Dr. Roberto Gómez C. Diapo. No. 56

Page 29: RPC

29

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"

Dr. Roberto Gómez C. Diapo. No. 57

/* Default timeout can be changed using clnt_control() */static struct timeval TIMEOUT = { 25, 0 };

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);

}

Dr. Roberto Gómez C. Diapo. No. 58

}return (&clnt_res);

}

Page 30: RPC

30

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);

}

Dr. Roberto Gómez C. Diapo. No. 59

}return (&clnt_res);

}

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 voidcuadro_prog_1(struct svc_req *rqstp, register SVCXPRT *transp){

Dr. Roberto Gómez C. Diapo. No. 60

union {int perimetro_1_arg;int area_1_arg;

} argument;char *result;xdrproc_t _xdr_argument, _xdr_result;char *(*local)(char *, struct svc_req *);

Page 31: RPC

31

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:

Dr. Roberto Gómez C. Diapo. No. 61

case AREA:_xdr_argument = (xdrproc_t) xdr_int;_xdr_result = (xdrproc_t) xdr_double;local = (char *(*)(char *, struct svc_req *))

area_1_svc;break;

RPC: Remote Procedure Call

int main (int argc, char **argv){register SVCXPRT *transp;

:

if (!svc register(transp CUADRO PROG CUADRO VERSif (!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);}

:

Dr. Roberto Gómez C. Diapo. No. 62

svc_run ();fprintf (stderr, "%s", "svc_run returned");exit (1);/* NOTREACHED */

}

Page 32: RPC

32

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 __cplusplusextern "C" {

Dr. Roberto Gómez C. Diapo. No. 63

#endif

#define CUADRO_PROG 0x31111111#define CUADRO_VERS 1

RPC: Remote Procedure Call

Ejemplo archivo encabezado: cuadro.h

#if defined(__STDC__) || defined(__cplusplus)#define PERIMETRO 1extern int * perimetro_1(int *, CLIENT *);extern int * perimetro_1_svc(int *, struct svc_req *);#d fi AREA 2#define AREA 2extern 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 1extern int * perimetro_1();extern int * perimetro 1 svc();

Dr. Roberto Gómez C. Diapo. No. 64

extern int perimetro_1_svc();#define AREA 2extern double * area_1();extern double * area_1_svc();extern int cuadro_prog_1_freeresult ();#endif /* K&R C */

::

Page 33: RPC

33

RPC: Remote Procedure Call

Llamadas con más de un parámetro

problemas y soluciones

Dr. Roberto Gómez C. Diapo. No. 65

RPC: Remote Procedure Call

Ejemplo aplicación: solución ecuaciones 2do. grado

a,b,c

r1, r2real, imag

:res1 = raiz(a,b,c)

:res b b a c

a= − ± −2 4

2

Dr. Roberto Gómez C. Diapo. No. 66

: res2 = complejo(a,b,c)

:co m p lex b

ab a c

aj=

−±

−2

24

2( )

Page 34: RPC

34

RPC: Remote Procedure Call

Diseño del servicio a nivel local

Código del servidorCódigo del clienteContenido del archivo encabezado

Dr. Roberto Gómez C. Diapo. No. 67

Compilación y ejecución

RPC: Remote Procedure Call

Servidor Local#include "encabeza.h"

struct raiz resuelve(a,b,c)float a,b,c;

{struct complex complejo(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;

float a,b,c; {

float temp;struct complex res;

temp = (b*b) - (4*a*c);res.real = (-b)/(2*a);res.imag = (temp)/(2*a);

Dr. Roberto Gómez C. Diapo. No. 68

;else {res.r1 = (-b + sqrt((double)temp)) / (2*a); res.r2 = (-b - sqrt((double)temp)) / (2*a);

}return res;

}

g ( p) ( );

return(res);

}

Page 35: RPC

35

RPC: Remote Procedure Call

Cliente Local

#include "encabeza.h"

main(argc, argv) int argc;

result=resuelve(a,b,c);if ( ! result.error ) {printf("La solucion de (% 1f % 1f % 1f)\n" a b c);char *argv[];

struct complex rescom;struct raiz result;float a,b,c;

if (argc != 4) {fprintf(stderr,"Error, uso: %s a b c\n",

[0])

printf("La solucion de (%.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);

Dr. Roberto Gómez C. Diapo. No. 69

argv[0]);exit(1);

}

a=(float)atoi(argv[1]);b=(float)atoi(argv[2]);c=(float)atoi(argv[3]);

rescom.real, ( 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 {fl t l

Dr. Roberto Gómez C. Diapo. No. 70

float real;float imag;

};

Page 36: RPC

36

RPC: Remote Procedure Call

Compilando y ejecutando

rogomez@armagnac:156>cc cliente.c servicio.c -lm -o toto@ 157>t t 1 1 1rogomez@armagnac:157>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:158>toto 1 9 14La solucion de (1.0 9.0 14.0)es -2.00000 y -7.00000rogomez@armagnac:159>toto 1 1 1La solucion de (1.0 1.0 1.0)

Dr. Roberto Gómez C. Diapo. No. 71

( )es (-0.50000 -1.50000j) y (-0.50000 1.50000j)rogomez@armagnac:160>toto 1 2 2La solucion de (1.0 2.0 2.0)es (-1.00000 -2.00000j) y (-1.00000 2.00000j)rogomez@armagnac:161>

RPC: Remote Procedure Call

Diseño del sistema a nivel remoto

• Especificación del archivo raiz.x• Compilación con rpcgen• Reescritura del archivo servidor remoto

R it d l hi li t t

Dr. Roberto Gómez C. Diapo. No. 72

• Reescritura del archivo cliente remoto• Compilación y ejecución

Page 37: RPC

37

RPC: Remote Procedure Call

Archivo especificación raiz.x

struct datos{float a;float b; RAIZ PROG {float b;float c;

};

struct raiz {float r1;float r2;int error;

};

program RAIZ_PROG {version RAIZ_VERS{

struct raiz RESUELVE(datos) = 1;struct complex COMPLEJO(datos) = 2;

} = 1;} = 0x31112345;

Dr. Roberto Gómez C. Diapo. No. 73

}

struct complex {float real;float imag;

};

RPC: Remote Procedure Call

Esqueleto del servidor

#include "raiz.h"#include <stdio.h>#include <stdlib.h> /* getenv, exit */ struct complex *

l j 1 (d t *#include <signal.h>

struct raiz *resuelve_1_svc(datos *argp,

struct svc_req *rqstp){

static struct raiz result;

complejo_1_svc(datos *argp, struct svc_req *rqstp)

{static struct complex result;

/** insert server code here*/

Dr. Roberto Gómez C. Diapo. No. 74

/** insert server code here*/

return (&result);}

return (&result);}

Page 38: RPC

38

RPC: Remote Procedure Call

Servidor remoto

#include "raiz.h"

struct raiz *struct complex *

l j 1 (d t * t t * t )struct raiz resuelve_1_svc(datos *argp, struct svc_req *rqstp){

static struct raiz res;int temp;

res.error=0;temp = (argp->b*argp->b) - (4*argp->a*argp->c);if (temp < 0)

res.error=1;

complejo_1_svc(datos *argp, struct svc_req *rqstp){

static struct complex res;float temp;

temp = (argp->b*argp->b) - (4*argp->a*argp->c);res.real = (-argp->b)/(2*argp->a);res.imag = (temp)/(2*argp->a);

return (&res);

Dr. Roberto Gómez C. Diapo. No. 75

else {res.r1=(-argp->b + sqrt((double)temp))/ (2*argp->a); res.r2=(-argp->b - sqrt((double)temp))/(2*argp->a);

}return (&res);

}

return (&res); }

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

Dr. Roberto Gómez C. Diapo. No. 76

#ifndef DEBUGclnt = clnt_create(host, RAIZ_PROG, RAIZ_VERS, "netpath");if (clnt == (CLIENT *) NULL) {

clnt_pcreateerror(host);exit(1);

}#endif /* DEBUG */

Page 39: RPC

39

RPC: Remote Procedure Call

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");}

#ifndef DEBUGclnt_destroy(clnt);

#endif /* DEBUG */} main(int argc, char *argv[])

{char *host;if (argc < 2) {

Dr. Roberto Gómez C. Diapo. No. 77

if (argc < 2) {printf("usage: %s server_host\n", argv[0]);exit(1);

}host = argv[1];raiz_prog_1(host);

}

RPC: Remote Procedure Call

Cliente remoto

#include "raiz h"

if (argc !=5) {printf("uso: %s host a b c \n", argv[0]);exit(1);

}#include raiz.h

CLIENT *clnt;struct raiz *raices;datos data;struct complex *rescom;

main(argc, argv)int argc;

}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);

Dr. Roberto Gómez C. Diapo. No. 78

g ;char *argv[];

{

char *host;

exit(1);}

raices = resuelve_1(&data, clnt);if (raices == (struct raiz *) NULL) {

clnt_perror(clnt, "call failed");}

Page 40: RPC

40

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));}

Dr. Roberto Gómez C. Diapo. No. 79

clnt_destroy(clnt);

}

RPC: Remote Procedure Call

Compilación

rogomez@costarica:81> make -f makefile.raizcc -g -c raiz_clnt.c -o raiz_clnt.occ -g -c raiz client c -o raiz client occ -g -c raiz_client.c -o raiz_client.occ -g -c raiz_xdr.c -o raiz_xdr.occ -g -o raiz_client raiz_clnt.o raiz_client.o raiz_xdr.o -lnsl cc -g -c raiz_svc.c -o raiz_svc.occ -g -c raiz_server.c -o raiz_server.oraiz_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 -lnslUndefined first referenced

Dr. Roberto Gómez C. Diapo. No. 80

symbol in filesqrt raiz_server.old: fatal: Symbol referencing errors. No output written to raiz_servermake: *** [raiz_server] Error 1[1] - Done /usr/4local/bin/xvile raiz.xrogomez@costarica:82>

Page 41: RPC

41

RPC: Remote Procedure Call

Makefile generado por rpcgen

# This is a template makefile generated by rpcgen # Parameters CLIENT = raiz_clientSERVER = 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

Dr. Roberto Gómez C. Diapo. No. 81

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 -lmRPCGENFLAGS =

RPC: Remote Procedure Call

Compilando de nuevo

rogomez@costarica:82> !mag @make -f makefile.raizcc -g -o raiz_server raiz_svc.o raiz_server.o raiz_xdr.o -lnsl -lmrogomez@costarica:83>

Dr. Roberto Gómez C. Diapo. No. 82

Page 42: RPC

42

RPC: Remote Procedure Call

rogomez@costarica:84>raiz_client cuba 1 -1 1La 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 14La solucion de (1.0 9.0 14.0)es -2.00000 y -7.00000

@ i 86 i li b 1 1 1

rogomez@cuba:28>raiz_serverrogomez@cuba:29>

Ejecución máquina servidor Ejecución máquina cliente

rogomez@costarica:86>raiz_client cuba 1 1 1La 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 2La 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 40La solucion de (1.0 -3.0 40.0)es (1.50000 -75.50000j) y (1.50000 75.50000j)rogomez@costarica:89>raiz client cuba 1 -3 -40

Dr. Roberto Gómez C. Diapo. No. 83

rogomez@costarica:89>raiz_client cuba 1 -3 -40La solucion de (1.0 -3.0 -40.0)es 8.00000 y -5.00000rogomez@costarica:90>raiz_client cuba 4 2 -1La solucion de (4.0 2.0 -1.0)es 0.30902 y -0.80902