0% encontró este documento útil (0 votos)
26 vistas9 páginas

Programacion RPC

Este tutorial proporciona una guía práctica para programar utilizando las RPC de Sun/ONC, enfocándose en la configuración del entorno y el desarrollo de servicios distribuidos en Ubuntu Server. A través de ejemplos progresivos, se abordan conceptos clave como la gestión de tipos de datos simples y compuestos, la utilización de uniones XDR y el manejo de vectores de tamaño variable. El documento incluye instrucciones detalladas para la instalación, configuración y ejecución de servidores y clientes RPC.

Cargado por

willibreak83
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
26 vistas9 páginas

Programacion RPC

Este tutorial proporciona una guía práctica para programar utilizando las RPC de Sun/ONC, enfocándose en la configuración del entorno y el desarrollo de servicios distribuidos en Ubuntu Server. A través de ejemplos progresivos, se abordan conceptos clave como la gestión de tipos de datos simples y compuestos, la utilización de uniones XDR y el manejo de vectores de tamaño variable. El documento incluye instrucciones detalladas para la instalación, configuración y ejecución de servidores y clientes RPC.

Cargado por

willibreak83
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd

Tutorial de programación con las

RPC de Sun/ONC
Integrante:
William Sánchez C.
Aplicaciones Distribuidas
Junio 2025
Tutorial de programación con las RPC de Sun/ONC

Introducción:

El mecanismo de llamada a procedimiento remoto (RCP) de Open Network Computing (ONC)


de Sun es ampliamente utilizado, especialmente gracias al éxito de productos como NFS que se
basan en él, aunque tiene algunas limitaciones en comparación con otros mecanismos de RPC,
es una excelente opción para familiarizarse con la programación de servicios usando RPCs,
esto se debe a que cualquier sistema UNIX, incluyendo el usado en esta guía, incluye todo el
software necesario para su uso en su instalación básica.

Esta guía tiene como objetivo proporcionar un tutorial rápido y practico para la programación
en este entorno, utilizando ejemplos de dificultad progresiva que nos permitirán comprender
los conceptos clave sin necesidad de consultar documentación adicional.

Preparacion del entorno

Para lograr ejecutar los casos que expondremos a continuación, necesitamos asegurarnos que
nuestra maquina virtual tenga todo lo necesario y para esta guía usaremos Ubuntu Server
24.04.

Instalación de prerrequisitos

Para empezar, necesitamos tener nuestro Ubuntu Server actualizado e instalar algunos
paquetes necesarios ejecutando los siguientes comandos como usuario root:

 sudo apt update

1
 sudo apt install build-essential rpcbind manpages-dev

Configuración de Permisos RPC

Por defecto, algunas distribuciones de Linux pueden restringir a los usuarios normales la
capacidad de iniciar servidores que usan este tipo de RPC. Para los propósitos de este taller
vamos a ejecutarlo como root.

 sudo rpcbind -i

Para este caso ya se encuentra activo, de no ser así ejecutaremos:

 sudo systemctl start rcpbind

Copiaremos los archivos de los casos a nuestro servidor y procederemos a descomprimir de


modo que tendremos los archivos listos.

Habilitar rpcbind para usuarios:

Por defecto, en algunas distribuciones de Linux, solo el superusuario puede registrar servicios
RPC. Para permitir que tu usuario normal lo haga, necesitas reconfigurar rpcbind.

 sudo systemctl stop rpcbind.socket


 sudo systemctl stop rpcbind
2
 sudo rpcbind -i -w

¡Listo! El entorno está preparado. Ahora vamos a trabajar con cada caso.

Paso 1: Primer Caso - Servicios con Tipos de Datos Simples

Aquí desarrollarás un servidor con dos funciones: una que obtiene el UID (identificador de
usuario) a partir de un nombre de usuario, y otra que hace lo contrario.

Entendiendo la versión errónea (caso_1_erroneo)

Vamos a compilar y ejecutar la primera versión que tiene un error intencional.

Navega al directorio y genera los resguardos (stubs):

En la terminal, ve al directorio IDL del primer caso. IDL (Interface Definition Language) es
donde se define el servicio.

 cd caso_1_erroneo/idl

Usa rpcgen para procesar el archivo .x y generar el código base para el cliente y el servidor.

 rpcgen rusuarios.x
 ls -l

Verás archivos nuevos como rusuarios_clnt.c, rusuarios_svc.c y rusuarios.h.

Compilación del servidor y el cliente:

Ahora, vamos a compilar todo, los archivos de ejemplo suelen incluir un Makefile que
simplifica esto. Navega a la raíz de caso_1_erroneo y usa el comando make.

 cd ..
 make

3
Ejecutar el servidor:

Una vez compilado, iniciamos el servidor y lo ejecutaremos en segundo plano (con &) para
poder seguir usando la misma terminal.

 ./servidor/rusuariosd &

Verifica que el servicio se ha registrado correctamente con rpcinfo.

 rpcinfo -p

Deberías ver tu programa (666666666) listado con sus versiones y puertos.

Prueba de los clientes y reproduce el error:

Primero, prueba el cliente getuid, que debería funcionar bien.

 ./cliente/getuid localhost root

Ahora, prueba el cliente getname. Lo probaremos con un UID que existe (como 0 para root) y
uno que no existe (como 877).

 ./cliente/getname localhost 0 877 1001

Aquí verás el error, el programa mostrará error en la llamada: RPC: Can't decode result para el
UID inexistente, esto ocurre porque el servidor retorna NULL, que no es un string válido en
XDR.

4
La solución (caso1_OK)

Ahora, vamos a ver la versión corregida, el error se soluciona asegurándose de que el servidor
siempre devuelva un string válido, en caso de no encontrar el usuario, devuelve un string vacío
("") en lugar de NULL, además, usa strdup para evitar problemas de sobreescritura de memoria
estática y xdr_free para gestionar la memoria dinámica correctamente.

Compilamos y ejecutamos la versión corregida:

Ve al directorio caso1_OK y compila el código.

 cd ../caso1_OK/
 cd ..
 gcc -o servidor/rusuariosd servidor/rusuariosd.c idl/rusuarios_svc.c -Iidl
-I/usr/include/tirpc -ltirpc

Ejecutamos el nuevo servidor. (Si el servidor anterior sigue corriendo, puedes detenerlo con el
comando fg y luego Ctrl+C, o killall rusuariosd).

 ./servidor/rusuariosd &

Prueba el cliente getname corregido:

Ejecutamos el mismo comando que antes.

 ./cliente/getname localhost 0 877 1001

Ahora, en lugar del error, el programa simplemente indicará que el UID no existe, porque el
cliente fue modificado para comprobar la longitud del string devuelto (strlen(*result) != 0).

5
Paso 2: Segundo Caso - Tipos de Datos Compuestos

En este caso, se amplía el servicio para manejar structs, permitiendo enviar y recibir múltiples
valores en una sola llamada RPC. Se añaden dos funciones: una que comprueba si dos UIDs
pertenecen al mismo grupo y otra que devuelve el UID y el GID (Group ID) de un usuario.

Generamos los resguardos y compilamos:

Navegamos al directorio caso_2 y compilamos el proyecto.

 cd ../caso_2

Al ejecutar rpcgen sobre el nuevo IDL, notarás que se genera un archivo rusuarios_xdr.c. Este
archivo contiene el código para serializar (marshalling) y deserializar (unmarshalling) las
nuevas estructuras (struct) que definiste.

Ejecuta el servidor y los nuevos clientes:

Inicia el servidor de este caso (recuerda detener el anterior).

 ./servidor/rusuariosd &

Prueba el nuevo cliente getugid que obtiene el UID y GID

 ./cliente/getugid localhost root nobody

Prueba el cliente agrupa_por_gids, que es más complejo y utiliza varios de los servicios
disponibles.

 ./cliente/agrupa_por_gids localhost 0 1001 1

6
Paso 3: Tercer Caso - Uso de union de XDR

Este caso presenta una forma más elegante de manejar los errores, como un UID no
encontrado. En lugar de devolver un valor "mágico" (como un string vacío), se utiliza el tipo
union de XDR, que es similar a un registro variante. Permite que el valor de retorno tenga
diferentes tipos según un campo discriminante (en este caso, un booleano existe).

Compila y ejecuta:

Ve al directorio caso_3 y compila.

 cd ../caso_3

Inicia el servidor.

 ./servidor/rusuariosd &

Prueba el cliente modificado:

Ejecuta el cliente getname de este caso.

 ./cliente/getname localhost 0 877 1001

El código del cliente ahora comprueba result->existe para saber si la llamada fue exitosa antes
de intentar acceder al nombre del usuario. La salida será limpia, sin errores de RPC.

Paso 4: Cuarto Caso - Vectores de Tamaño Variable

Aquí aprenderás a manejar colecciones de datos cuyo tamaño no se conoce de antemano,


como una lista de UIDs. XDR proporciona un tipo para vectores de longitud variable (<>) que es
más eficiente que usar un array de tamaño fijo.

7
Compila y ejecuta:

Ve al directorio caso_4 y compila.

 cd ../caso_4

Inicia el servidor.

 ./servidor/rusuariosd &

Prueba el cliente para vectores:

El nuevo cliente getgids envía una lista de UIDs al servidor y recibe una lista de GIDs.

 ./cliente/getgids localhost 0 1001 877

En el código, verás que el vector se representa en C como una struct con un campo para la
longitud (uids_len) y un puntero a los datos (uids_val).

También podría gustarte