Universidad Simón Bolívar Departamento de Computación y Tecnología de la Información Redes de Computadores (CI-4835) TALLER ABIERTO # 4 RECURSOS REQUERIDOS: Para la ejecución de esta práctica el estudiante deberá disponer un PC ejecutando Linux® y el Software para programar RPC. DURACIÓN: 2 horas ACTIVIDADES A REALIZAR: Parte 1: El profesor expondrá a los estudiantes cómo funciona RPC y RMI. Para ello se apoyará en las láminas que se proveen con este material. Parte 2: El estudiante examinará el ejemplo que abajo se muestra, luego lo compilará y ejecutará hasta ver cómo funciona en la práctica. A.- Archivo “rand.h”: /* Please do not edit this file. It was generated using rpcgen. */ #ifndef _RAND_H_RPCGEN #define _RAND_H_RPCGEN #include <rpc/rpc.h> #ifdef __cplusplus extern "C" { #endif #define RAND_PROG 0x31111111 #define RAND_VERS 1 #if defined(__STDC__) || defined(__cplusplus) #define INITIALIZE_RANDOM 1 extern void * initialize_random_1(long *, CLIENT *); extern void * initialize_random_1_svc(long *, struct svc_req *); #define GET_NEXT_RANDOM 2 extern double * get_next_random_1(void *, CLIENT *); extern double * get_next_random_1_svc(void *, struct svc_req *); extern int rand_prog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */ #define INITIALIZE_RANDOM 1 extern void * initialize_random_1(); extern void * initialize_random_1_svc(); #define GET_NEXT_RANDOM 2 extern double * get_next_random_1(); extern double * get_next_random_1_svc(); extern int rand_prog_1_freeresult (); #endif /* K&R C */ #ifdef __cplusplus } #endif #endif /* !_RAND_H_RPCGEN */ B.- Archivo “rand.x”: /* rand.x */ program RAND_PROG { version RAND_VERS { void INITIALIZE_RANDOM(long)=1; double GET_NEXT_RANDOM(void)=2; }=1; }= 0x31111111; C.- Archivo “rand_client.c”: #include <stdlib.h> #include <stdio.h> #include "rand.h" int main (int argc, char *argv[]) { char *host; CLIENT *clnt; void *result_1; double *result_2; char *get_next_random_1_arg; long semilla; int i, iters; if (argc != 4) { fprintf (stderr, "uso: %s servidor semilla iteraciones\n", argv[0]); exit (1); } host = argv[1]; semilla = (long) atoi(argv[2]); iters = atoi(argv[3]); clnt = clnt_create (host, RAND_PROG, RAND_VERS, "udp"); if (clnt == NULL) { clnt_pcreateerror (host); exit (1); } result_1 = initialize_random_1(&semilla, clnt); if (result_1 == (void *) NULL) { clnt_perror (clnt, "call failed"); exit (2); } for (i=0; i<iters ;i++) { result_2 = get_next_random_1((void*)&get_next_random_1_arg, clnt); if (result_2 == (double *) NULL) { clnt_perror (clnt, "call failed"); exit (3); } else printf("%d: %f\n", i, *result_2); } clnt_destroy(clnt); exit (0); } D.- Archivo “rand_clnt.c”: /* Please do not edit this file. It was generated using rpcgen. */ #include <memory.h> /* for memset */ #include "rand.h" /* Default timeout can be changed using clnt_control() */ static struct timeval TIMEOUT = { 25, 0 }; void * initialize_random_1(long *argp, CLIENT *clnt) { static char clnt_res; memset((char *)&clnt_res, 0, sizeof(clnt_res)); if (clnt_call (clnt, INITIALIZE_RANDOM, (xdrproc_t) xdr_long, (caddr_t) argp, (xdrproc_t) xdr_void, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return ((void *)&clnt_res); } double * get_next_random_1(void *argp, CLIENT *clnt) { static double clnt_res; memset((char *)&clnt_res, 0, sizeof(clnt_res)); if (clnt_call (clnt, GET_NEXT_RANDOM, (xdrproc_t) xdr_void, (caddr_t) argp, (xdrproc_t) xdr_double, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return (&clnt_res); } E.- Archivo “rand_server.c”: #include <stdlib.h> #include "rand.h" void * initialize_random_1_svc(long *argp, struct svc_req *rqstp) { static char * result; srand48(*argp); result=(void *)NULL; return (void *) &result; } double * get_next_random_1_svc(void *argp, struct svc_req *rqstp) { static double result; result=drand48(); return &result; } F.- Archivo “rand_svc.c”: /* Please do not edit this file. It was generated using rpcgen. */ #include #include #include #include #include #include #include #include "rand.h" <stdio.h> <stdlib.h> <rpc/pmap_clnt.h> <string.h> <memory.h> <sys/socket.h> <netinet/in.h> #ifndef SIG_PF #define SIG_PF void(*)(int) #endif static void rand_prog_1(struct svc_req *rqstp, register SVCXPRT *transp) { union { long initialize_random_1_arg; } argument; char *result; xdrproc_t _xdr_argument, _xdr_result; char *(*local)(char *, struct svc_req *); switch (rqstp->rq_proc) { case NULLPROC: (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL); return; case INITIALIZE_RANDOM: _xdr_argument = (xdrproc_t) xdr_long; _xdr_result = (xdrproc_t) xdr_void; local = (char *(*)(char *, struct svc_req *)) initialize_random_1_svc; break; case GET_NEXT_RANDOM: _xdr_argument = (xdrproc_t) xdr_void; _xdr_result = (xdrproc_t) xdr_double; local = (char *(*)(char *, struct svc_req *)) get_next_random_1_svc; break; default: svcerr_noproc (transp); return; } memset ((char *)&argument, 0, sizeof (argument)); if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { svcerr_decode (transp); return; } result = (*local)((char *)&argument, rqstp); if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) { svcerr_systemerr (transp); } if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { fprintf (stderr, "%s", "unable to free arguments"); exit (1); } return; } int main (int argc, char **argv) { register SVCXPRT *transp; pmap_unset (RAND_PROG, RAND_VERS); transp = svcudp_create(RPC_ANYSOCK); if (transp == NULL) { fprintf (stderr, "%s", "cannot create udp service."); exit(1); } if (!svc_register(transp, RAND_PROG, RAND_VERS, rand_prog_1, IPPROTO_UDP)) { fprintf (stderr, "%s", "unable to register (RAND_PROG, RAND_VERS, udp)."); exit(1); } transp = svctcp_create(RPC_ANYSOCK, 0, 0); if (transp == NULL) { fprintf (stderr, "%s", "cannot create tcp service."); exit(1); } if (!svc_register(transp, RAND_PROG, RAND_VERS, rand_prog_1, IPPROTO_TCP)) { fprintf (stderr, "%s", "unable to register (RAND_PROG, RAND_VERS, tcp)."); exit(1); } svc_run (); fprintf (stderr, "%s", "svc_run returned"); exit (1); /* NOTREACHED */ } G.- Archivo “Makefile.rand”: # This is a template Makefile generated by rpcgen # Parameters CLIENT = rand_client SERVER = rand_server SOURCES_CLNT.c = SOURCES_CLNT.h = SOURCES_SVC.c = SOURCES_SVC.h = SOURCES.x = rand.x TARGETS_SVC.c = rand_svc.c rand_server.c TARGETS_CLNT.c = rand_clnt.c rand_client.c TARGETS = rand.h rand_clnt.c rand_svc.c rand_client.c rand_server.c OBJECTS_CLNT = $(SOURCES_CLNT.c:%.c=%.o) $(TARGETS_CLNT.c:%.c=%.o) OBJECTS_SVC = $(SOURCES_SVC.c:%.c=%.o) $(TARGETS_SVC.c:%.c=%.o) # Compiler flags CFLAGS += -g LDLIBS += -lnsl RPCGENFLAGS = # Targets all : $(CLIENT) $(SERVER) $(TARGETS) : $(SOURCES.x) rpcgen $(RPCGENFLAGS) $(SOURCES.x) $(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) $(TARGETS_CLNT.c) $(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) $(TARGETS_SVC.c) $(CLIENT) : $(OBJECTS_CLNT) $(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) $(LDLIBS) $(SERVER) : $(OBJECTS_SVC) $(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS) clean: $(RM) core $(TARGETS) $(OBJECTS_CLNT) $(OBJECTS_SVC) $(CLIENT) $(SERVER) Grupo Docente de Redes de Computadoras I / Ene-Mar 2014