• No se han encontrado resultados

El Llamado de procedimientos remotos

N/A
N/A
Protected

Academic year: 2021

Share "El Llamado de procedimientos remotos"

Copied!
42
0
0

Texto completo

(1)

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

(leer FA45 de arch1)

servidor

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

cliente

(34759037F3247A)

servidor

cliente

(ack)

servidor

cliente

(ack)

servidor

(2)

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 locales al main Variables locales al main Variables locales al main bytes buf fd dirección regreso SP SP SP : } : } }

(3)

Tipos de paso de parámetros

• Por valor

– en el stack se copia el valor del parámetro

en 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/restore

se 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

• 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

(4)

Máquina Cliente

Máquina Servidor

stub del cliente

stub del servidor

Principio funcionamiento del RPC

cliente call return Pack parámetros Unpack resultado Unpack parámetros Pack resultado 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

– rutinas de alto y bajo nivel

– posibilidad de definir más aspectos

• timeouts

• protocolos

(5)

Máquina Cliente

Máquina Servidor

stubs

El paso de parámetros

sum sum

4

7

4

7

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)

paso de apuntadores, (estructuras complejas)

• Optimización

– especificación parámetros de entrada y salida

– registros para paso de apuntadores

(6)

#include <header.h>

specification of file server, version 3.1

Binding dinámico: especificación formal servidor

specification of file_server, version 3.1

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

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

int delete(in char[MAX_PATH]);

end.

RPC: Remote Procedure Call

Binder

Registro del servidor

SERVIDOR

Binder

Sistema Distribuido

Nombre Num. versión Id único Id.único Manejador, (handler) Otros (autentificación)

(7)

servicio NO disponible error

3

Petición cliente

proceso solicitante stub

Binder

servicio disponible disponible

1

2

3’

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

stub cliente

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

(8)

Paso 1: ‘Este es PRIMEPROG Version 1,

Estoy usando el puerto 1061’’ Puerto 111

Registro y localización de un servidor RPC

Prog Vers Puerto Paso 2: ‘Donde esta PRIMEPROG Version 1?’ Puerto 1061

Servidor

Portmapper

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

Paso 4: ‘Llama procedimiento 1. Aquí están los datos

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 Sun

20000000 3

d fi id

l

i

20000000 - 3FFFFFFF

definido por el usuario

40000000 - 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

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 programa

y de una determinada versión en un host dado.

(9)

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 parámetro como la dirección universal en el transporte

b 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 versnum

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 ningún host tomo el host local

RPC: Remote Procedure Call

Ejemplo rpcinfo

armagnac:45>rpcinfo -s toto

program version(s)

netid(s)

service

owner

100000 2,3,4 udp, tcp, tictls, ticosord, ticots

rpcbin

superuser

100029

2,1

ticots, ticotsord, ticlts

keyserv

superuser

100029

2,1 ticots, ticotsord, ticlts

keyserv

superuser

100078 4

ticots, ticotsord, ticlts

kerbd

superuser

100087 10 udp

admind

superuser

100011 1 ticlts, udp

rquotad

superuser

100002 3,2 ticlts, udp

rusersd

superuser

100099 1 ticots, ticotsord, ticlts

-

superuser

100012 1 ticlts, udp

sprayd

superuser

100008 1 ticlts, udp

walld

superuser

100001

4 3 2

i l

d

d

100001 4,3,2 ticlts, udp

rstad

superuser

100024 1 ticots, ticotsord, ticlts, tcp, udp

status

superuser

100021 2,3,1 ticots, ticotsord, ticlts, tcp, udp

nlockmgr superuser

134177279 1,2 tcp

-

5001

(10)

Máquina Servidora

Programa Servidor procedimientos servicio

función dispatch Portmapper

Pasos de una Llamada a un Procedimiento Remoto

función dispatch Portmapper

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ón Usuario 4. TRANSPORTE

5-7. SESIÓN

Niveles del Protocolo TCP/IP

Interface UDP TCP IP 1-2.ENLACE / FÍSICO 3. RED 4. TRANSPORTE Interface Hardware

R E D

NIVELES

OSI

(11)

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

Stub

Cliente

Kernel

Preparar mensaje buffer

Marshall los parámetros en el buffer Poner los encabezados a los mensajes Pasar al kernel

Contexto switch al kernel Copiar mensaje en el kernel Determinar direcciones destino

Llamar al servidor

Poner los parametros en el stack Unmarshall parametros

Switch contexto a server stub Copiar mensaje en server stub Ver si stub esta esperando

Server

Stub

Kernel

á

i

Kernel

Máquina

Determinar direcciones destino Poner dirección en encabezado mensaje Establecer la interfaz de la red Hechar a andar el timer

Ver si stub esta esperando Decidir a que stub darselo Checar el paquete para validación Interrupción de proceso

(12)

EL RPC DE SUN

EL 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 developed

Especificación RPC

Desarrollo de una Aplicación

de Red con un

Compilador de Protocolo RPC

Compilador RPC

stub del cliente stub del servidor

compilar compilar RPC and data representation libraries filtros comunes y archivo encabezado

código cliente código servidor

compilar y ligar y ligar funciones cliente funciones servidor librerías de RPC y de representación de datos

(13)

-Comentarios

Igual que en lenguaje C

El lenguaje RPC (RPCL)

RPCL

Equivalente en C

-Constantes simbólicas

const MAX_SIZE = 8192 #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

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

-Booleanos

bool termino; bool_t termino;

-Arreglos tamaño fijo

int alumnos[10]; int alumnos[10];

RPC: Remote Procedure Call

-Arreglos tamaño variable

int 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

-Estructuras

struct punto { struct punto {

int x; int x;

int y; int y;

}; };

(14)

-Strings

No existen en C, RPCL convención de terminación en NULL Tamaño especifica máximo número caracteres permitidos en string No especificado => tamaño máximo = máximo valor u_int; string nombre <32> char *nombre;

string nombresote<> char *nombresote;

-Uniones

Más cercanas al registro variante de Pascal

union 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 opacos

Usados para describir datos que no tienen tipo Dato 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 RPCL

Misma sintaxis que en C

Ejemplo define un fname_type usado para declarar strings de nombres de archivos que tienen una longitud máxima de 255 caracteres

typedef string fname_type <255> typedef char *fname_type;

- Identificadores

Compuestos de letras, números y el underscore Distinción entre mayusculas y minusculas

(15)

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

int

double

:

per = perimetro(20)

:

:

sup = area(20

:

:

4*a

:

a*a

:

(16)

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

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

(17)

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]); per = perimetro(a);

sup = area(a);

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

(18)

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

El area del cuadrado es 4

(19)

Paso II

Diseño del archivo

de configuración y

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

g

y

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

} = 1;

} = 0x311445566

;

(20)

Números de programas remotos

00000000 - 1FFFFFFF Sun Permanente Pública 20000000 - 3FFFFFFF Local Desconocido Local 40000000 - 5FFFFFFF Desarrollador Temporal Local 50000000 - 7FFFFFFF Reservado

80000000 - 9FFFFFFF Reservado A0000000 - BFFFFFFF Reservado

Rango (hexadecimal) Administrador Tiempo de vida Distribución

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

C0000000 - DFFFFFFF Reservado E0000000 - FFFFFFFF Reservado

RPC: Remote Procedure Call

Sintáxis 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 ]

[

tt

] [

tfil

] [ i fil ]

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

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

(21)

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.cuadro

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

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

contiene stub servidor cuadro.h

(22)

Archivos generados por rpcgen

cuadro client c cuadro_client.c

programa esqueleto del cliente con llamadas dummy al servicio remoto. Inserta código para asignar los valores de los argumentos para el servicio

remoto. cuadro_server.c

contiene stubs para servicios remotos. Inserta código para la versión local dentro de los stubs.

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

cuadro_xdr.c

contiene 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

makefile.cuadro

cuadro_clnt.c

cuadro_client.c

archivos cliente

(23)

Paso III

Insertar código en

archivos generados

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

g

por 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"

void

cuadro_prog_1(char *host)

{

{

CLIENT *clnt;

int *result_1;

int perimetro_1_arg;

double *result_2;

int area_1_arg;

(24)

#ifndef DEBUG

clnt = 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 DEBUG

clnt_destroy (clnt); #endif /* DEBUG */

}

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

(25)

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

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

clnt_destroy(clnt); }

(26)

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)

{

{

static double result;

result = (*argp) * (*argp);

return &result;

}

(27)

Paso IV

Compilando y

ejecutando los

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

j

programas

RPC: Remote Procedure Call

1. Usar makefile generado por rpcgen:

rogomez@costarica:281>

make -f makefile.cuadro

d

l t

d

l t

cc –g -c cuadro_clnt.c -o cuadro_clnt.o

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

(28)

2. Registrando al servidor de generación de números 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 ? S 23:10:27 0:00 cuadro server

rogomez 8068 3.4 1564 1012 ? S 23:10:27 0:00 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 costarica 2

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

rogomez@cuba:27>cuadro_client costarica 2

El perimetro del cuadrado es 8 El area del cuadrado es 4

rogomez@cuba:28>

RPC: Remote Procedure Call

Ejemplos

de

códigos

(29)

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

}

}

return (&clnt_res);

}

(30)

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

(31)

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 VERS if (!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 */ }

(32)

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

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 1

extern int * perimetro_1(int *, CLIENT *);

extern int * perimetro_1_svc(int *, struct svc_req *);

#d fi AREA 2 #define AREA 2

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

extern int 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 */

: :

(33)

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, r2

real, imag

:

res1 = raiz(a,b,c)

:

r e s b b a c a = − ± 2−4 2

:

res2 = complejo(a,b,c)

:

c o m p le x b a b a c a j = − ± 2− 2 4 2 ( )

(34)

Diseño del servicio a nivel local

Código del servidor

Código del cliente

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

else {

res.r1 = (-b + sqrt((double)temp)) / (2*a); res.r2 = (-b - sqrt((double)temp)) / (2*a); } return res; } g ( p) ( ); return(res); }

(35)

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 float real; float imag; };

(36)

Compilando y ejecutando

rogomez@armagnac:156>cc cliente.c servicio.c -lm -o toto

@

157>t t 1 1 1

rogomez@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 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)

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

(

)

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>

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

• Reescritura del archivo cliente remoto

• Compilación y ejecución

(37)

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

*/

/*

* insert server code here

*/

return (&result);

}

return (&result);

}

(38)

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

#ifndef DEBUG

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

clnt_pcreateerror(host); exit(1);

}

(39)

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 DEBUG

clnt_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); g ; char *argv[]; { char *host; exit(1); } raices = resuelve_1(&data, clnt); if (raices == (struct raiz *) NULL) {

clnt_perror(clnt, "call failed"); }

(40)

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.raiz

cc -g -c raiz_clnt.c -o raiz_clnt.o cc -g -c raiz client c -o raiz client o cc -g -c raiz_client.c -o 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

(41)

Makefile generado por rpcgen

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

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 -lm

RPCGENFLAGS =

RPC: Remote Procedure Call

Compilando de nuevo

rogomez@costarica:82>g @ !ma

make -f makefile.raiz

cc -g -o raiz_server raiz_svc.o raiz_server.o raiz_xdr.o -lnsl -lm

(42)

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 @ i 86 i li b 1 1 1 rogomez@cuba:28>raiz_server rogomez@cuba:29>

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

rogomez@costarica:86>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: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 cuba 1 -3 -40

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

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

Referencias

Documento similar

El profesor utiliza diferentes procedimientos para El profesor utiliza diferentes procedimientos para El profesor utiliza diferentes procedimientos para El profesor

destacar de la vivienda de este período es que las casas se empezaron a convertir en un espacio privado, sobre todo porque ya algunos ciudadanos como abogados,

Como sucediera con la poesía y otras manifestaciones artísticas en los próxi- mos pero ya remotos tiempos del final del franquismo, la psicología cognitiva sigue viviendo aún

 Llegue con 20 minutos de anticipación para el registro administrativo en la  CALLE 82 No 24-66 , Barrio Polo Club, Bogotá..  Uso obligatorio de tapabocas limpio y en

autónomo dependiente y su cliente como de los acuerdos de interés profesional.. z Regulación de

Es probable, por tanto, que el desarro- llo adiposo y muscular que se produce en la adolescencia sean determinantes ante la adquisición del pico de masa ósea, en tanto que

Procesos, métodos y procedimientos: procedimientos de operación con máquinas eléctricas, hidráulicas, neumáticas, electrónicas, procedimientos en operaciones de primera

Pero la aportación de Assmann a la teoría de la cultura, ejemplificada en las más avanza- das civilizaciones de los tiempos más remotos, no era ciega a lo que el transcurso de