Question: Modify the average RPC programs (avg.x, avg_proc.c and ravg.c) so that it computes the standard deviation of a maximum of 100 numbers instead of the

Modify the average RPC programs (avg.x, avg_proc.c and ravg.c) so that it computes the standard deviation of a maximum of 100 numbers instead of the average of a maximum of 200 numbers. Test your program on the server. The average RPC program is available on Canvas - a Makefile is included). Just type make (make sure you have an .rhost file under your home directory, and that 'white' space works correctly in the makefile (i.e., cut and paste the makefile will not work).

For the avg program: Run the RPC server program by starting the server: ./avg_svc For the avg program: Run the RPC client program by: ./ravg 127.0.0.1 1 2 3 4 Try to use a different 'port number' than other classmates by changing the 22855 number given in the avg.x file. Suggestion, use the last 4 digits of your student ID number or some other unique number. Deliverable: A zip or tar file with the full directory of files implementing this logic.

RPC Makefile

CC = gcc BIN = ravg avg_svc GEN = avg_clnt.c avg_svc.c avg_xdr.c avg.h RPCCOM = rpcgen

all: $(BIN)

ravg: ravg.o avg_clnt.o avg_xdr.o $(CC) -o $@ ravg.o avg_clnt.o avg_xdr.o -lnsl

ravg.o: ravg.c avg.h $(CC) -g ravg.c -c

avg_svc: avg_proc.o avg_svc.o avg_xdr.o $(CC) -o $@ avg_proc.o avg_svc.o avg_xdr.o -lnsl

avg_proc.o: avg_proc.c avg.h $(CC) -g avg_proc.c -c

$(GEN): avg.x $(RPCCOM) avg.x

clean cleanup: rm -f $(GEN) *.o $(BIN)

avg.x

/* * The average procedure receives an array of real

* numbers and returns the average of their

* values. This toy service handles a maximum of

* 200 numbers.

* http://www.linuxjournal.com/article/2204?page=0,1

*/ const MAXAVGSIZE = 200;

struct input_data

{

double input_data<200>;

};

typedef struct input_data input_data;

program AVERAGEPROG {

version AVERAGEVERS {

double AVERAGE(input_data) = 1;

} = 1;

} = 22855;

rhost

127.0.0.1 pghosh

Makefile

CC = gcc BIN = ravg avg_svc GEN = avg_clnt.c avg_svc.c avg_xdr.c avg.h RPCCOM = rpcgen CPATH = $CPATH:/usr/include/tirpc

all: $(BIN)

ravg: ravg.o avg_clnt.o avg_xdr.o $(CC) -o $@ ravg.o avg_clnt.o avg_xdr.o -lnsl -ltirpc

ravg.o: ravg.c avg.h $(CC) -g ravg.c -c

avg_svc: avg_proc.o avg_svc.o avg_xdr.o $(CC) -o $@ avg_proc.o avg_svc.o avg_xdr.o -lnsl -ltirpc

avg_proc.o: avg_proc.c avg.h $(CC) -g avg_proc.c -c

$(GEN): avg.x $(RPCCOM) avg.x

clean cleanup: rm -f $(GEN) *.o $(BIN)

avg_proc.c

#include #include "avg.h" #include /* run locally on 'server' called by a remote client. */ static double sum_avg; /* * routine notice the _1 the version number * notice the client handle, not sued here but needs to be * a parameter */ double * average_1(input_data *input, CLIENT *client) { /* input is paramters were marshalled by genrated routine */ /* a pointer to a double, is set to begining of data array */ double *dp = input->input_data.input_data_val; u_int i; sum_avg = 0; /* iterate until end of number of times (data_len) */ for( i = 1; i <= input->input_data.input_data_len; i++ ) { sum_avg = sum_avg + *dp; /* add what ptrs points to ( '*' gets content ) */ dp++; } sum_avg = sum_avg / input->input_data.input_data_len; return( &sum_avg ); } /* * server stub 'average_1_svc function handle called in avg_svc that was * generated by rpcgen * FYI: * result = (*local)((char *)&argument, rqstp); * where local is (char *(*)(char *, struct svc_req *)) average_1_svc; */ double * average_1_svc(input_data *input, struct svc_req *svc) { CLIENT *client; return( average_1( input, client) );

m-rusers-1.c

#include #include #include /* uses callrpc */ int main(int argc, char **argv) { long nusers; enum clnt_stat stat; if( argc<=1 ) { printf( "Usage: %s hostname ", argv[0] ); exit(1); } stat=callrpc( argv[1], RUSERSPROG, RUSERSVERS_3, RUSERSPROC_NUM, (xdrproc_t) xdr_void, NULL, (xdrproc_t) xdr_u_long, (char*)&nusers); if( stat != RPC_SUCCESS ) { clnt_perrno(stat); printf(" "); exit(1); } printf( "There are %d users on %s ", nusers, argv[1] ); }

ravg.c

/* written by client - calls client stub, xdr client, xdr xerver, server stub, server routine */ #include "avg.h" /* header file generated by rpcgen */ #include /* local routine client */ /* prototype can be whatever you want */ void averageprog_1( char* host, int argc, char *argv[] ) { CLIENT *clnt; /* client handle, rpc.h included in avg.h from rpcgen */ int i; double f, *result_1, *dp; char *endptr; input_data average_1_arg; /* input_data rpc struct */ average_1_arg.input_data.input_data_val = (double*) malloc(MAXAVGSIZE*sizeof(double)); /* pointer to double, beginning of input data */ dp = average_1_arg.input_data.input_data_val; /* set number of items */ average_1_arg.input_data.input_data_len = argc - 2; for( i = 1; i <= (argc - 2); i++ ) { /* str to d ASCII string to floating point nubmer */ f = strtod( argv[i+1], &endptr); printf("value = %e ", f); *dp = f; dp++; } /* clnt_create(host, program, version, protocol) * generic client create routine from rpc library * * program = AVERAGEPROG is the number 22855 * version = AVERAGEVERS is 1 * transfer protocol * * defined by application programmer in avg.x and then * these definitions in turn are generated into avg.h * udp is of-course the user datagram protocol * * returns a client RPC handle */ clnt = clnt_create( host, AVERAGEPROG, AVERAGEVERS, "udp" ); /* check if error */ if (clnt == NULL) { /* * rpc error library routine * print a more descriptive error */

clnt_pcreateerror( host ); exit(1); } /* now call average routine 'just' like a local routine * but this will now go over network * average_1 is definined in the client stub * avg_clnt.c that was generated by rpcgen * send in ptr to the parameters or args in first field, and * client handle in second field (created in clnt_create ) * average_1 ultimately calls clnt_call() macro see man rpc * than calls the remote routine associated with the client handle * so AVERAGEPROG, VERSION */ result_1 = average_1( &average_1_arg, clnt ); if (result_1 == NULL) { clnt_perror(clnt, "call failed:"); } clnt_destroy( clnt ); printf( "average = %e ",*result_1 ); } /* here is main */ main( int argc, char* argv[] ) { char *host; /* check correct syntax */ if( argc < 3 ) { printf( "usage: %s server_host value ... ", argv[0]); exit(1); } if( argc > MAXAVGSIZE + 2 ) { printf("Two many input values "); exit(2); } /* host name is in first parameter (after program name) */ host = argv[1]; averageprog_1( host, argc, argv);

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!