Вы находитесь на странице: 1из 8

Prctica 3. Llamadas a procedimientos remotos.

Sun-RPC
SOLUCION A EJERCICIO # 2
SCS, 2010/11
ndice General
Ejercicio 2: Uso de tipos complejos en interfaces remotos
o Pasos a seguir
o Tareas a realizar
Documentacin a entregar
Ejercicio 2: Uso de tipos complejos en interfaces remotos
Se parte de un cdigo de ejemplo que implementa una serie de procedimientos remotos para el
procesamiento de vectores:
escalado de un vector (multiplicacin por una constante)
suma de 2 vectores
Descarga: rpc2.tar.gz
Pasos a seguir
1. Descomprimir el paquete.
2. $ tar xzvf rpc2.tar.gz
3. $ cd rpc2
4. Contenido
o vector.x: Definicin XDR del interfaz remoto.
La sintaxis de XDR es similar a la C, pero no es C.
En este caso se usa el tipo de dato XDR que implementa un ''vector de tamao
variable'' t_vector, que no existe en C.
Al generar el cdigo C ese ''vector variable'' se definir como un estrucutra con
dos campos: t_vector_len con la longitud del vector y t_vector_val con un puntero
al array de nmeros reales en memoria.
typedef struct {
u_int t_vector_len;
float *t_vector_val;
} t_vector;
o servidor_vector.c: Implementacin de los procedimientos remotos definidos.
o cliente_vector.c: Ejemplo de llamadas a los mtodos remotos exportados.
Revisar el fichero vector.x y sus declaraciones de datos.
5. Compilar con rpcgen la definicin del interfaz remoto
6. $ rpcgen vector.x
Genera los siguientes ficheros.
o vector.h: Fichero de cabecera con constantes y las definiciones de las estructuras usadas
como parmetros de entrada y como valores e salida.
Comprobar la definicin de los tipos
o vector_clnt.c: Cdigo C con la implementacin del stub
o vector_svc.c: Cdigo C con la implementacin del skeleton
o vector_xdr.c: Cdigo C con la implementacin de las rutinas XDR para
aplanar/desaplanar los argumentos y el valor de retorno

7. Generar los ejecutables del servidor y del cliente y ejecutarlos


8. $ gcc -o servidor_vector servidor_vector.c vector_svc.c vector_xdr.c
9. $ gcc -o cliente_vector cliente_vector.c vector_clnt.c vector_xdr.c
10. $ ./servidor_vector &
11. $ ./cliente_vector localhost
Tareas a realizar
Se tratar de extender el interfaz remoto con una nueva operacin de vectores, el producto escalar de 2
vectores.
El producto escalar de y es el nmero, que es el resultado de calcular
Ver producto escalar
Pasos:
1. Modificar el interfaz XDR ''vector.x'' para incluir un nuevo procedimiento producto_escalar
o recibir como parmetro una estructura con 2 vectores (como en suma_vectores)
o devolver un nmero real (float)
2. Compilar el nuevo interfaz con rpcgen
3. $ rpcgen vector.x
Idea: Se puede usar rpcgen -a vector.x y comprobar como ser el prototipo de la nueva funcin a
implementar/llamar en vector_server.c y vector_client.c.
4. Incluir en servidor_vector.c la implementacin del mtodo producto_escalar_1_svc()
5. Incluir en cliente_vector.c la llamada al mtodo producto_escalar_1()
6. Compilar cliente y servidor y comprobar su funcionamiento
7. $ gcc -o servidor_vector servidor_vector.c vector_svc.c vector_xdr.c
8. $ gcc -o cliente_vector cliente_vector.c vector_clnt.c vector_xdr.c
9. $ ./servidor_vector &
10. $ ./cliente_vector localhost
Documentacin a entregar
Para el ejercicio 2 se entregar el framento de cdigo fuente donde se implementa el producto
escalar de vectores (funcin producto_escalar_1_svc()) y el fragmento donde realiza la llamada a
producto_escalar_1() desde el cliente.
Se deber comentar tambin el contenido del cdigo generado automticamente por rpcgen:
vector_clnt.c, vector_svc.c, vector_xdr.c, vector.h, describiendo brevemente la finalidad de las
estructuras de datos y las funciones que aportan.

vector.x
const MAX_VECTOR=100;
typedef float t_vector<>;
struct entrada1 {
t_vector v;
float c;
};
struct entrada2 {
t_vector v1;
t_vector v2;
};
struct entrada3 {
t_vector v3;
t_vector v4;
};

program OPER_VECTOR {
version OPER_VECTORVER {
t_vector escalado_vector(entrada1) = 1;
t_vector suma_vectorial(entrada2) = 2;
t_vector producto_vectorial(entrada3) = 3;
} = 1;
} = 0x30000002;

cliente_vector.c
#include "vector.h"
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
/* prototipos que llamanan al metodo aleatorio y volcar vector */
float * crear_vector_aleatorio(int);
void volcar_vector(t_vector);
// METODO PRINCIPAL
int main(int argc, char ** argv) {
char *host;
if (argc != 2) {
fprintf(stderr, "ERROR: formato incorrecto \nCliente nombre_servidor\n");
exit(1);
}
host = argv[1];
CLIENT *clnt;
t_vector *resultado1;
//t_vector *resultado2;
entrada1 args1; // llamada a entrada1 del archivo vector.x
entrada2 args2; // llamada a entrada2 del archivo vector.x
entrada3 args3; // llamada a entrada3 del archivo vector.x

clnt = clnt_create (host, OPER_VECTOR, OPER_VECTORVER, "tcp");


if (clnt == NULL) {
clnt_pcreateerror (host);
exit (1);
}
/* Crear vectores aleatorios con datos aleatorios*/
t_vector vector1;
vector1.t_vector_len = 5;
vector1.t_vector_val = crear_vector_aleatorio(5);
printf("VECTOR 1:");
volcar_vector(vector1);
printf("\n");
t_vector vector2;
vector2.t_vector_len = 5;

vector2.t_vector_val = crear_vector_aleatorio(5);
printf("VECTOR 2:");
volcar_vector(vector2);
printf("\n");
/* llamada a escalado_vector */
args1.v = vector1;
args1.c = 100.0;
resultado1 = escalado_vector_1(&args1, clnt);
if (resultado1 == (t_vector *) NULL) {
clnt_perror (clnt, "call failed");
}
printf("ESCALADO DE VECTOR (*100)\n vector resultado:");
volcar_vector(*resultado1);
printf("\n");
/* llamada a suma vectorial */
args2.v1 = vector1;
args2.v2 = vector2;
resultado1 = suma_vectorial_1(&args2, clnt);
if (resultado1 == (t_vector *) NULL) {
clnt_perror (clnt, "call failed");
}
printf("SUMA VECTORIAL DE 2 VECTORES\n vector resultado:");
volcar_vector(*resultado1);
printf("\n");
//////////////////////////////////////////////////////////////////
/* llamada a producto vectorial */
args3.v3 = vector1; // se cambio v1 por v3 para que almacene vector1
args3.v4 = vector2; // se cambio v2 por v4 para que almacene vector2
// se cambio AQUI
y AQUI
resultado1 = producto_vectorial_1(&args3, clnt);
if (resultado1 == (t_vector *) NULL) {
clnt_perror (clnt, "call failed");
}
printf("PRODUCTO VECTORIAL DE 2 VECTORES\n vector resultado:");
volcar_vector(*resultado1);
printf("\n");
////////////////////////////////////////////////////////////////////
clnt_destroy (clnt);
}

// Metodo que te genera un vector con datos aleatorios


float * crear_vector_aleatorio(int tamano) {
float * aux = (float *) malloc(tamano * sizeof(float));
int i;
for (i=0; i < tamano; i++){
aux[i] = 10.0 * (random()/(float) RAND_MAX);
//
aux[i] = i;
}
return(aux);
}
void volcar_vector(t_vector aux){
int i;
printf("( ");
for (i = 0; i < aux.t_vector_len; i++) {
printf("%6.2f ", aux.t_vector_val[i]);
}
printf(")");
}

servidor_vector.c
/*
* This is sample code generated by rpcgen.
* These are only templates and you can use them
* as a guideline for developing your own functions.
*/
#include "vector.h"
#include <malloc.h>

/*
* Implementacin del escalado de vectores
* multiplica cada elemento del vector por la constante indicada
*/
t_vector * escalado_vector_1_svc(entrada1 *argp, struct svc_req *rqstp) {
static t_vector result;
/* Valor de retorno */
static float vector_aux[MAX_VECTOR]; /* Espacio esttico para almacenar el vector resultado*/

/* Recuperar argumentos: vector + constante */


t_vector vector = argp->v;
float constante = argp->c;
/* Inicializar vector de salida (indicar tamano + pedir espacio) */
result.t_vector_len = vector.t_vector_len;
result.t_vector_val = vector_aux;
/* Multiplicar cada componente por la constante */
int i;
for (i=0; i< result.t_vector_len; i++) {
result.t_vector_val[i] = constante * vector.t_vector_val[i];
}
/* Devolver valor de retorno */
return &result;
}
/*
* Implementacion de la suma vectorial de 2 vectores
*/
t_vector * suma_vectorial_1_svc(entrada2 *argp, struct svc_req *rqstp) {
static t_vector result;
/* Valor de retorno */
static float vector_aux[MAX_VECTOR]; /* Espacio esttico para almacenar el vector resultado*/

/* Recuperar argumentos: 2 vectores */


t_vector vector1 = argp->v1;
t_vector vector2 = argp->v2;
/* Inicializar vector de salida (indicar tamano + pedir espacio) */
result.t_vector_len = vector1.t_vector_len;
result.t_vector_val = vector_aux;
/* Sumar componente a componente */
int i;
for (i=0; i< result.t_vector_len; i++) {
result.t_vector_val[i] = vector1.t_vector_val[i] + vector2.t_vector_val[i];
}
/* Devolver valor de retorno */
return &result;
}
//////////////////////////////////////////////////////////////
/*
* Implementacion de la producto vectorial de 2 vectores
*/
//
SE cambio AQUI
AQUI
t_vector * producto_vectorial_1_svc(entrada3 *argp, struct svc_req *rqstp) {
static t_vector result;
/* Valor de retorno */
static float vector_aux[MAX_VECTOR]; /* Espacio esttico para almacenar el vector resultado*/
/* Recuperar argumentos: 2 vectores */
t_vector vector3 = argp->v3; // Se cambio aqui de vector1 a "vector3" y se puso argp-> v1 a "V3"
t_vector vector4 = argp->v4; // Se cambio aqui de vector2 a "vector4" y se puso argp-> v2 a "V4"
/* Inicializar vector de salida (indicar tamano + pedir espacio) */
result.t_vector_len = vector3.t_vector_len;
result.t_vector_val = vector_aux;
/* multiplicar componente a componente */
int i;
for (i=0; i< result.t_vector_len; i++) { // aqui de + a " * "
result.t_vector_val[i] = vector3.t_vector_val[i] * vector4.t_vector_val[i];
}
/* Devolver valor de retorno */
return &result;
}
//////////////////////////////////////////////////////////////////

Вам также может понравиться