Você está na página 1de 8

Prctica 4.

RPC
suma.x En los archivos .x se definen los prototipos de las funciones que queremos que se publiquen. struct sumandos { int sumando1; int sumando2; }; program PROGRAM_SUMA { version VERSION_SUMA { int suma (sumandos) = 1; } = 1; } = 0x20000001; Para compilar usamos: $rpcgen -a suma.x

Con la instruccin anterior se generan 7 archivos, sin la opcin -a se deja al programador la tarea de crear la implementacin misma. Los archivos creados son: 1.- Makefile.suma 2.- suma_xdr.c 3.- suma.h 4.- suma_server.c 5.- suma_svc.c 6.- suma_client.c 7.- suma_clnt.c El archivo suma_xdr.c es para hacer compatibles los tipos de datos con otras arquitecturas. El archivo suma.h contiene los prototipos de las funciones. El archivo suma_server.c es la aplicacin del servidor. #include "suma.h" int * suma_1_svc(sumandos *argp, struct svc_req *rqstp) { static int result; /* * insert server code here */ result = argp -> sumando1 + argp -> sumando2; return &result; }

El archivo suma_svc.c es la interfaz del servidor. El archivo suma_client.c es la aplicacin del cliente. #include "suma.h" void program_suma_1(char *host) { CLIENT *clnt; int *result_1; sumandos suma_1_arg; #ifndef DEBUG clnt = clnt_create (host, PROGRAM_SUMA, VERSION_SUMA, "udp"); if (clnt == NULL) { clnt_pcreateerror (host); exit (1); } #endif /* DEBUG */ suma_1_arg.sumando1 = 1; suma_1_arg.sumando2 = 2; result_1 = suma_1(&suma_1_arg, clnt); if (result_1 == (int *) NULL) { clnt_perror (clnt, "call failed"); } printf("La suma de %d + %d es: %d \n", suma_1_arg.sumando1,suma_1_arg.sumando2,*result_1); #ifndef DEBUG clnt_destroy (clnt); #endif /* DEBUG */ } int main (int argc, char *argv[]) { char *host; if (argc < 2) { printf ("usage: %s server_host\n", argv[0]); exit (1); } host = argv[1]; program_suma_1 (host); exit (0); } El archivo suma_clnt.c es la interfaz del cliente. Para ejecutar los programas utilizamos: $ make -f Makefile.suma

Abrimos una terminal (Terminal 1) y escribimos: $ ./suma_server

Abrimos otra terminal (Terminal 2) y escribimos: $./suma_client <maquina del servidor>

donde <maquina del servidor> es la direccin IP del servidor, pero en este caso pondremos un servidor local, ya que este programa se est probando en una misma mquina. $./suma_client localhost

Y finalmente para detener al servidor presionamos la combinacin de teclas Ctrl + C. AplicacinRPCa. Realice una aplicacin RPC similar a suma.x que implemente una calculadora con las operaciones de suma, resta, multiplicacin y divisin. El usuario debe introducir los operandos. El usuario debe decidir que operacin debe hacer. RPC en el nivel medio Los RPC's fueron desarrollados por SUN Microsystems y se apoyan en el protocolo XDR (external Data Representation). Para hacer referencia a un servicio se utiliza la siguiente estructura: <programa, versin, procedimiento> Los nmeros de identificacin de cada uno de estos estn en los siguientes rangos: 0x00000000 0x1fffffff -> aplicaciones de SUN 0x20000000 0x3fffffff -> Usuario 0x40000000 0x5fffffff -> Transitorios de usuario Segn el nivel de profundidad en las funciones que se utilizan de RPC se tiene: Alto Intermedio (solo tres funciones) Bajo

A nivel intermedio el cliente utiliza: callrpc -> rpccall

Las llamadas al sistema para RPC se ponen a continuacin: registerrpc() #include <rpc.h> int registerrpc(prognum, versnum, procnum, procname, inproc, outproc) u_long prognum; u_long versnum; u_long procnum; char *(*procname) (); xdrproc_t inproc; xdrproc_t outproc; rpc_call() #include <rpc/rpc.h> enum clnt_stat rpc_call(const char *host, const u_long prognum, const u_long versnum, const u_log procnum, const xdrproc_t inproc, const char *in, const xdrproc_t outproc, char *out, const char *nettype); En el lado del servidor se utilizan registerrpc() #include <rpc.h> int registerrpc(prognum, versnum, procnum, procname, inproc, outproc) u_long prognum; u_long versnum; u_long procnum; char *(*procname) (); xdrproc_t inproc; xdrproc_t outproc; svc_run() #include <rpc.h> svc_run() Tiempo.c En una aplicacin tradicional se tiene: #include <stdio.h>

#include <stdlib.h> #include <time.h> long bin_date() { long timeval; timeval=time((long *) NULL); return (timeval); } char *str_date(long bintime) { char *ptr; ptr=ctime(&bintime); return (ptr); } main() { long lresult; char *sresult; lresult=bin_date(); printf("Hora Local = %ld \n",lresult); sresult= str_date(lresult); printf("Hora Local = %s \n", sresult); exit(0); } Para compilarlo se usa: $gcc Tiempo.c -o Tiempo Cliente.c Una evolucin ser tener dos archivos. #include <stdio.h> #include <stdlib.h> long bin_date(void ); char *str_date(long ); main() { long lresult; char *sresult; lresult=bin_date(); printf("Hora Local = %ld \n",lresult); sresult= str_date(lresult); printf("Hora Local = %s \n", sresult); exit(0); }

Servidor.c Una evolucin ser tener dos archivos. #include <stdio.h> #include <time.h> long bin_date() { long timeval; timeval=time((long *) NULL); return (timeval); } char *str_date(long bintime) { char *ptr; ptr=ctime(&bintime); return (ptr); } Se compila de la siguiente manera: $gcc Cliente.c Servidor.c -o Tiempo

Finalmente nuestra aplicacin RPC quedara de la siguiente manera: cl_sv.h #include <rpc/rpc.h> #define DATE_PROG 0x31234567 #define DATE_VERS 1 #define BIN_DATE 1 #define STR_DATE 2 Servidor2.c #include <stdio.h> #include <time.h> #include "cl_sv.h" long *bin_date() { static long timeval; timeval=time((long *) NULL); return (&timeval); } char **str_date(long *bintime) { static char *ptr; ptr=ctime(bintime); return (&ptr);

} main() { registerrpc(DATE_PROG, DATE_VERS, BIN_DATE, bin_date, xdr_void, xdr_long); registerrpc(DATE_PROG, DATE_VERS, STR_DATE, str_date, xdr_long, xdr_wrapstring); svc_run(); } Cliente2.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include "cl_sv.h" long bin_date(void ); char *str_date(long ); char *server; xdrproc_t inproc, outproc; main(int argc, char *argv[]) { long lresult; char *sresult; if(argc != 2) { fprintf(stderr, "Uso: %s hostname \n", argv[0]); exit(1); } server=argv[1]; lresult=bin_date(); printf("Hora en %s = %ld \n", server, lresult); sresult= str_date(lresult); printf("Hora en %s = %s \n", server, sresult); exit(0); } long bin_date() { long timeval; callrpc(server, DATE_PROG, DATE_VERS, BIN_DATE, xdr_void, 0, xdr_long, (char *)(&timeval)); return timeval; } char *str_date(long bintime) {

static char *ptr; // callrpc(server, DATE_PROG, DATE_VERS, STR_DATE, inproc, (char *)(&bintime), outproc, (char *)(&ptr)); callrpc(server, DATE_PROG, DATE_VERS, STR_DATE, xdr_long, (char *)(&bintime), xdr_wrapstring, (char *)(&ptr)); return (ptr); } Para evitar los llamados warnings es necesario hacer un cast en la funcin bin_date(): callrpc(server, DATE_PROG, DATE_VERS, BIN_DATE, xdr_void, 0, xdr_long, (char *)(&timeval)); y en la funcin str_date(bintime): callrpc(server, DATE_PROG, DATE_VERS, STR_DATE, xdr_long, (char *)(&bintime), xdr_wrapstring, (char *)(&ptr));

Para compilar el Cliente hacemos: $gcc Cliente2.c -o Cliente2 -lnsl Para compilar el Servidor hacemos:: $gcc Servidor2.c -o Servidor2 l

Ejecucin del Cliente y servidor: En terminal1: $./Cliente2 <direccin IP> Para nuestro ejemplo basta con: $./Cliente2 localhost En terminal2: $./Servidor2 AplicacinRPCb. Crear una aplicacin con RPC a nivel medio que simule un chat. (30% de la calificacin de la prctica) AplicacionRPCc. Servicio de archivos y directorios. Desarrollar un aplicacin que permita crear, leer y borrar archivos y directorios de la mquina servidor, as como cambiar los permisos de estos, esta aplicacin debe ser desarrollada con RPC a nivel medio. (40% de la calificacin de la prctica)

Você também pode gostar