summaryrefslogtreecommitdiff
path: root/reference/C/CONCEPT/rpc.html
diff options
context:
space:
mode:
Diffstat (limited to 'reference/C/CONCEPT/rpc.html')
-rw-r--r--reference/C/CONCEPT/rpc.html356
1 files changed, 356 insertions, 0 deletions
diff --git a/reference/C/CONCEPT/rpc.html b/reference/C/CONCEPT/rpc.html
new file mode 100644
index 0000000..e45041c
--- /dev/null
+++ b/reference/C/CONCEPT/rpc.html
@@ -0,0 +1,356 @@
+<title>RPC</title>
+<body bgcolor="#ffffcc">
+<hr>
+<center><h1>Remote Procedure Calls (RPC).</h1></center>
+<hr>
+In the normal scope of things, a program can only call a function
+that is linked into the executable or provided by a shared library.
+RPC allows programs to execute functions in another executing program, cool!
+<p>
+RPC has a concept of clients and servers.
+<ol>
+<li>The client issues requests to the server.
+<li>Servers perform the requests and return the results.
+<li>The data that flows between client and server includes
+int, float, strings and structures.
+<li>The client and server can be on the same host or different hosts
+connected via a network.
+<li>The hosts do not have to be the same artitechture.
+</ol>
+
+The RPC <a href=../glossary.html#api>API</a> has three levels of support.
+By using the highest level
+RPC is responcable for most of the code but is not too flexable. The lowest
+level requres more coding but gives the programmer more control over how RPC
+functions.
+<p>
+The easiest way to start with RPC is to use a program called <b>rpcgen</b>
+this reads a file that describes the required interface between client and server
+and generates C code that you can include in your client and server.
+
+<pre>
+
+ prog.x --> rpcgen ---> prog.h Header file
+ ---> prog_clnt.c Client stubs file
+ ---> prog_svc.c Server stubs file
+ ---> prog_xdr.c XDR routines (more later).
+
+</pre>
+You write <b>prog.x</b> and rpcgen generates
+<b>prog.h prog_clnt.c prog_svc.c prog_xdr.c</b>
+
+You then write the client and server and link them with the rpcgen code
+to complete the RPC system.
+
+<pre>
+
+ client.c -----> client executable
+ prog.h ---|
+ prog_clnt.c ---|
+ prog_xdr.c ---|
+
+ server.c -----> Server executable
+ prog.h ---|
+ prog_svc.c ---|
+ prog_xdr.c ---|
+
+
+</pre>
+
+Ok, time for some examples.
+
+<h3>Calling an RPC server function without passing any arguments.</h3>
+This is the simplest form of RPC.
+
+<p>
+<center>
+<table bgcolor=ivory width=80%>
+<th>
+void.x
+</th>
+<tr>
+<td>
+<pre>
+
+ /* RPCGEN code decribing the client/server API. */
+
+ program MJLPROG
+ {
+ version MJLVERS
+ {
+ void VOID(void) = 1;
+
+ } = 1;
+ } = 0x20000001;
+</pre>
+</td>
+</tr>
+</table>
+</center>
+<p>
+
+<b>void.x</b> describes the RPC interface between the client
+and server. There are some important items to note here.
+<p>
+<table><tr>
+<td bgcolor=silver>
+<pre>
+program MJLPROG
+{
+} = 0x20000001;
+</pre></td>
+<td>This is the RPC program number. It is used by the client to
+identify the server it intends to use.
+It is important that you provide a unique number here. You can see
+which values are in use with the Unix command <b>rpcinfo -p</b> or
+by looking at <b>/etc/rpc</b>. Please note that the number is supplied
+in void.x as a hex value but shown as a decimal value by <b>rpcinfo</b>
+One other point, you should only use values in the range 0x20000000
+0x3FFFFFFF as these have been reserved for use local use.
+</td>
+</tr>
+<tr>
+<td bgcolor=silver>
+<pre>
+version MJLVERS
+{
+} = 1;
+</pre></td>
+<td>The RPC Version number.</td>
+</tr>
+<tr>
+<td bgcolor=silver><pre>void VOID(void) = 1;</pre></td>
+<td>This defines the only RPC function that the server will provide.</td>
+</tr>
+</table>
+<p>
+
+<center>
+<table bgcolor=ivory width=80%>
+<th>
+void_client.c
+</th>
+<tr>
+<td>
+<pre>
+
+ #include &lt;rpc/rpc.h&gt;
+ #include "void.h"
+
+ main()
+ {
+ CLIENT *pclnt;
+ void *pVoid;
+
+ char Host[256];
+
+ /* Get the name of the host running the server. */
+
+ gethostname(Host, 256);
+
+ /* Connect to the server. */
+
+ pclnt = clnt_create(Host, MJLPROG, MJLVERS, "udp");
+
+ /* Issue a request to the server. */
+
+ void_1(pVoid, pclnt);
+
+ /* Disconnect from the server. */
+
+ clnt_destroy(pclnt);
+
+ }
+</pre>
+</td>
+</tr>
+</table>
+</center>
+
+<p>
+<table>
+<tr>
+<td bgcolor=silver>
+<pre>
+#include &lt;rpc/rpc.h&gt;
+
+</pre>
+</td>
+<td>
+Include the standard RPC headers.
+</td>
+</tr>
+<tr>
+<td bgcolor=silver>
+<pre>
+#include "void.h"
+</pre>
+</td>
+<td>
+Include the header file generated by <b>rpcgen</b>
+</td>
+</tr>
+<tr>
+<td bgcolor=silver>
+<pre>
+pclnt = clnt_create();
+</pre>
+</td>
+<td>Connect to the server <b>MJLPROG</b> on <b>Host</b> and return a
+pointer to the <b>CLIENT</b> control structure.
+</td>
+</tr>
+<tr>
+<td bgcolor=silver>
+<pre>
+void_1(pVoid, pclnt);
+</pre>
+</td>
+<td>
+Call the remote function.
+</td>
+</tr>
+<tr>
+<td bgcolor=silver>
+<pre>
+clnt_destroy();
+</pre>
+</td>
+<td>
+Disconnect from the server.
+</td>
+</tr>
+</table>
+<p>
+
+<center>
+<table bgcolor=ivory width=80%>
+<th>
+void_server.c
+</th>
+<tr>
+<td>
+<pre>
+
+ #include <rpc/rpc.h>
+ #include "void.h"
+
+ void *void_1_svc(void *pVoid, struct svc_req *X)
+ {
+ printf("Function called without passing arguments\n");
+ }
+
+</pre>
+</td>
+</tr>
+</table>
+</center>
+
+<p>
+<table>
+<tr>
+<td bgcolor=silver>
+<pre>
+void *void_1_svc()
+</pre>
+</td>
+<td>
+The server function that will be run for the client.
+</td>
+</tr>
+</table>
+<p>
+
+Please note that the server does not have a <b>main()</b>, rpcgen
+generates it for you.
+<p>
+The code can be compiled with the following commands
+
+<pre>
+ gcc void_server.c void_svc.c -o void_server
+ gcc void_client.c void_clnt.c -o void_client
+</pre>
+<p>
+In theory you should be able to start the server and it will
+respond everytime the client is executed. I have not included any
+error recovery into this example as it makes the code harder to
+read. As an exercise try adding the error recovery code yourself :-)
+
+<h3>Transfer integers between the client and server</h3>
+
+
+<p>
+<center>
+<table bgcolor=ivory width=80%>
+<th>
+integer.x
+</th>
+<tr>
+<td>
+<pre>
+
+ /* RPCGEN code decribing the client/server API. */
+
+ program MJLPROG
+ {
+ version MJLVERS
+ {
+ int INTEGER(int) = 1;
+
+ } = 1;
+ } = 0x20000001;
+</pre>
+</td>
+</tr>
+</table>
+</center>
+
+<p>
+<table>
+<tr>
+<td bgcolor=silver>
+<pre>
+int INTEGER(int) = 1;
+</pre>
+</td>
+<td>
+Server function now accepts an integer and returns an integer.
+</td>
+</tr>
+</table>
+
+
+
+
+<p>
+
+<hr>
+<h2>See Also:</h2>
+
+<img src=../../GRAPHICS/whiteball.gif>
+<a href=../SYNTAX/void.html>VOID keyword.</a>
+<hr>
+<p>
+<center>
+<table border=2 width=80% bgcolor=ivory>
+<tr align=center>
+<td width=25%>
+<a href=../cref.html>Top</a>
+</td><td width=25%>
+<a href=../master_index.html>Master Index</a>
+</td><td width=25%>
+<a href=../SYNTAX/keywords.html>Keywords</a>
+</td><td width=25%>
+<a href="../FUNCTIONS/funcref.htm">Functions</a>
+</td>
+</tr>
+</table>
+</center>
+<p>
+
+<hr>
+29-Dec-97
+<address>Martin Leslie
+
+
+