Hello, Today we will go through rpcbind for Remote Procedure call in Distributed System.
In distributed computing, a remote procedure call (RPC) is when a computer program causes a procedure (subroutine) to execute in a different address space (commonly on another computer on a shared network), which is coded as if it were a normal (local) procedure call, without the programmer explicitly coding the details for the remote interaction.  [Source:- Wikipedia]
What is rpcbind?
The rpcbind utility is a server that converts RPC program numbers into universal addresses. It must be running on the host to be able to make RPC calls on a server on that machine. - [ $ man rpcbind ]

Install rpcbind -> sudo apt-get install rpcbind

Today we will make a simple RPC for factorial.

First make a .x file
1
2
3
4
5
6
7
8
9
10
struct values{
 int num1;
};

program Fact{
 version fact_verse{
  float fac(values) = 1;

 } = 1;
} = 456789;

Here we have a struct called values and a program Fact
save the file. For now we will save as fact.x

Now the file is created run
rpcgen -aC fact.x

Now there are several middleware files created. Among them, we need to edit that fact_client.c and fact_server.c

Here is fact_client.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/*
 * 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 "test.h"


float
fact_1(int argc, char *host)
{
 CLIENT *clnt;
 float  *result_1;
 values  fac_1_arg;
 fac_1_arg.num1 = argc;

//#ifndef DEBUG
 clnt = clnt_create (host, Fact, fact_verse, "udp");
 if (clnt == NULL) {
  clnt_pcreateerror (host);
  exit (1);
 }
//#endif /* DEBUG */

 result_1 = fac_1(&fac_1_arg, clnt);
 if (result_1 == (float *) NULL) {
  clnt_perror (clnt, "call failed");
 }
//#ifndef DEBUG
 clnt_destroy (clnt);

 
//#endif  /* DEBUG */
 return *result_1;
}


int
main (int argc, char *argv[])
{
 char *host;
 int num, ans;
 printf("Enter a number");
 scanf("%d",&num);

 if (argc < 1) {
  printf ("usage: %s server_host\n", argv[0]);
  exit (1);
 }
 host = argv[1];
 ans = fact_1 (num,host);
 printf("the factorial is %d",ans);
exit (0);
}
Here we accept a number from the users. change the fact_1 method to accept another int and return int. Also, remember our main methods accepts several args. You need not write the whole program, you will edit it once created by rpcgen.

Here is fact_server.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
 * 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 "test.h"

float *
fac_1_svc(values *argp, struct svc_req *rqstp)
{
 static float  result;

 /*
  * insert server code here
  */
 int var = argp->num1;
 int ans = factorial(5);
 printf("in server %d",ans);
 
 result = ans;
 return &result;
}

int factorial(int a){
 if (a==1)
  return 1;
 else
  return a*factorial(a-1);
}

In the server file we just get the number from the argp parameter, which is the struct we created in the .x file. calculate the factorial and return it.

Have a good day :)

Wait... How to run?

Once you perform the necessary changes, you can make the executable files for that run make -f Makefile.fact
Where do the Makefile.fact came from? It will be created while running the rpcgen command.

Run server $ ./fact_server
Open another terminal run client $ ./fact_client localhost