rpc
TRANSCRIPT
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
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
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
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
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
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)
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
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.
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>
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
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
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
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;
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
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
:
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);
}
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);
}
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>
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;
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 ]
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.
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
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;
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
}
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);}
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;
}
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
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
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);
}
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 *);
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 */
}
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 */
::
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( )
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);
}
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;
};
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
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);}
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 */
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");}
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>
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
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