<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://jackxiang.com/post//</link>
<title><![CDATA[Sun Rpc English Language]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[WEB2.0]]></category>
<pubDate>Tue, 21 Dec 2010 15:04:17 +0000</pubDate> 
<guid>http://jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	<br/>Sun Remote Procedure Call Mechanism<br/><br/>Originally developed by Sun, but now widely available on other platforms (including Digital Unix). Also known as Open Network Computing (ONC).<br/><br/>Sun RPC package has an RPC compiler (rpcgen) that automatically generates the client and server stubs.<br/><br/>RPC package uses XDR (eXternal Data Representation) to represent data sent between client and server stubs.<br/><br/>Has built-in representation for basic types (int, float, char).<br/><br/>Also provides a declarative language for specifying complex data types.<br/><br/>Remote Date Example<br/><br/>From Stevens Unix Networking book.<br/>Running rpcgen date.x generates date.h, date_clnt.c and date_svc.c. The header file is included with both client and server. The respective C source files are linked with client and server code.<br/><br/>/*<br/> * date.x&nbsp;&nbsp;Specification of the remote date and time server<br/> */<br/> <br/>/*<br/> * Define two procedures<br/> *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bin_date_1() returns the binary date and time (no arguments)<br/> *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str_date_1() takes a binary time and returns a string<br/> *<br/> */<br/> <br/>program DATE_PROG &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;version DATE_VERS &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long BIN_DATE(void) = 1;&nbsp;&nbsp;&nbsp;&nbsp;/* procedure number = 1 */<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string STR_DATE(long) = 2;&nbsp;&nbsp;/* procedure number = 2 */<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125; = 1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* version number = 1 */<br/>&#125; = 0x31234567;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* program number = 0x31234567 */<br/>Notes:<br/><br/>Start numbering proceedures at 1 (procedure 0 is always the ``null procedure&#039;&#039;.<br/>Program number is defined by the user. Use range 0x20000000 to 0x3fffffff.<br/>Provide a prototype for each function. Sun RPC allows only a single parameter and a single result. Must use a structure for more parameters or return values (see XDRC++ example).<br/>use clnt_create() to get handle to remote procedure.<br/>do not have to use rpcgen. Can handcraft own routines.<br/>/*<br/> * rdate.c&nbsp;&nbsp;client program for remote date program<br/> */<br/> <br/>#include &lt;stdio.h&gt;<br/><br/>#include &lt;rpc/rpc.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;/* standard RPC include file */<br/>#include &quot;date.h&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* this file is generated by rpcgen */<br/><br/>main(int argc, char *argv[])<br/>&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;CLIENT *cl;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* RPC handle */<br/>&nbsp;&nbsp;&nbsp;&nbsp;char *server;<br/>&nbsp;&nbsp;&nbsp;&nbsp;long *lresult;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* return value from bin_date_1() */<br/>&nbsp;&nbsp;&nbsp;&nbsp;char **sresult;&nbsp;&nbsp;&nbsp;&nbsp; /* return value from str_date_1() */<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (argc != 2) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, &quot;usage: %s hostname&#92;n&quot;, argv[0]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;server = argv[1];<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/*<br/>&nbsp;&nbsp;&nbsp;&nbsp; * Create client handle<br/>&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if ((cl = clnt_create(server, DATE_PROG, DATE_VERS, &quot;udp&quot;)) == NULL) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * can&#039;t establish connection with server<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clnt_pcreateerror(server);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(2);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/*<br/>&nbsp;&nbsp;&nbsp;&nbsp; * First call the remote procedure &quot;bin_date&quot;.<br/>&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;if ( (lresult = bin_date_1(NULL, cl)) == NULL) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clnt_perror(cl, server);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(3);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;time on host %s = %ld&#92;n&quot;,server, *lresult);<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/*<br/>&nbsp;&nbsp;&nbsp;&nbsp; * Now call the remote procedure str_date<br/>&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;if ( (sresult = str_date_1(lresult, cl)) == NULL) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clnt_perror(cl, server);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(4);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;time on host %s = %s&quot;, server, *sresult);<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;clnt_destroy(cl);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* done with the handle */<br/>&nbsp;&nbsp;&nbsp;&nbsp;exit(0);<br/>&#125;<br/>/*<br/> * dateproc.c&nbsp;&nbsp; remote procedures; called by server stub<br/> */<br/> <br/>#include &lt;rpc/rpc.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* standard RPC include file */<br/>#include &quot;date.h&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* this file is generated by rpcgen */<br/><br/>/*<br/> * Return the binary date and time<br/> */<br/> <br/> long *bin_date_1()<br/> &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;static long timeval;&nbsp;&nbsp;&nbsp;&nbsp;/* must be static */<br/> <br/>&nbsp;&nbsp;&nbsp;&nbsp;timeval = time((long *) 0);<br/>&nbsp;&nbsp;&nbsp;&nbsp;return(&amp;timeval);<br/> &#125;<br/> <br/>/*<br/> * Convert a binary time and return a human readable string<br/> */<br/>&nbsp;&nbsp;<br/>char **str_date_1(long *bintime)<br/>&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;static char *ptr;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* must be static */<br/>&nbsp;&nbsp;&nbsp;&nbsp;ptr = ctime(bintime);&nbsp;&nbsp; /* convert to local time */<br/>&nbsp;&nbsp;&nbsp;&nbsp;return(&amp;ptr);<br/>&#125;<br/>Notes:<br/><br/>No main() routine in server code. It is in the _svc.c code generated by rpcgen.<br/>Extra level of indirection. bin_date() does not return a long, but returns a pointer to a long. Have a pointer to a string in str_date().<br/>The variable being returned needs to be declared static otherwise it will be deallocated on the stack when the function returns.<br/>&lt; wpi /cs/cs4513/public/example/Date 1 &gt;ls<br/><br/>date.x&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dateproc.c&nbsp;&nbsp; rdate.c<br/>&lt; wpi /cs/cs4513/public/example/Date 2 &gt;rpcgen date.x<br/><br/><br/>&lt; wpi /cs/cs4513/public/example/Date 3 &gt;ls<br/><br/>date.h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;date_clnt.c&nbsp;&nbsp; dateproc.c<br/>date.x&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;date_svc.c&nbsp;&nbsp;&nbsp;&nbsp;rdate.c<br/>&lt; wpi /cs/cs4513/public/example/Date 4 &gt;cc -o rdate rdate.c date_clnt.c<br/><br/>rdate.c:<br/>date_clnt.c:<br/>&lt; wpi /cs/cs4513/public/example/Date 5 &gt;cc -o dateproc dateproc.c date_svc.c<br/><br/>dateproc.c:<br/>date_svc.c:<br/>&lt; wpi /cs/cs4513/public/example/Date 6 &gt;dateproc&amp;<br/><br/>[1] 17940<br/>&lt; wpi /cs/cs4513/public/example/Date 7 &gt;rdate wpi<br/><br/>time on host wpi = 954778980<br/>time on host wpi = Mon Apr&nbsp;&nbsp;3 12:23:00 2000<br/><br/>&lt; wpi /cs/cs4513/public/example/Date 8 &gt;exit<br/><br/>exit<br/>What happens with these processes:<br/><br/>Server process creates a UDP socket and binds to a local port. It calls svc_register() routine to register its program number and version with the local port mapper process. This process should have been started as a daemon at system boot time. Server then waits for requests.<br/>Client program contacts the port mapper on the designated machine using UDP. Gets port number for the server process.<br/>Client program calls the client stub for the remote procedure (first bin_date_1() and then str_date_1. Defaults for how long to wait, how many times to retry, etc.<br/>Remote Message Printing Example<br/><br/>Adaptation of the sample program in the rpcgen Programming Guide. Changes:<br/><br/>Server output sent to stdout rather than console.<br/>ANSI C style function declaration rather than classic C style.<br/>/*<br/> * msg.x Remote message printing protocol<br/> */<br/><br/>program MESSAGEPROG &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;version MESSAGEVERS &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int PRINTMESSAGE(string) = 1;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125; = 1;<br/>&#125; = 0x20000099;<br/>/*<br/> * rprintmsg.c&nbsp;&nbsp; remote printing version of &quot;printmsg.c&quot;<br/> */<br/> <br/>#include &lt;stdio.h&gt;<br/>#include &lt;rpc/rpc.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* always needed */<br/>#include &quot;msg.h&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* msg.h wil be generated by rpcgen */<br/><br/>main(int argc, char *argv[])<br/>&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;CLIENT *cl;<br/>&nbsp;&nbsp;&nbsp;&nbsp;int *result;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char *server;<br/>&nbsp;&nbsp;&nbsp;&nbsp;char *message;<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (argc != 3) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;usage %s host message&#92;n&quot;,argv[0]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;server = argv[1];<br/>&nbsp;&nbsp;&nbsp;&nbsp;message = argv[2];<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/* Creare client handle for calling MESSAGEPROG on the server<br/>&nbsp;&nbsp;&nbsp;&nbsp; * designated on the command line.&nbsp;&nbsp;We tell the RPC package<br/>&nbsp;&nbsp;&nbsp;&nbsp; * to use the tcp protocol when contacting the server.<br/>&nbsp;&nbsp;&nbsp;&nbsp; */&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;cl = clnt_create(server, MESSAGEPROG, MESSAGEVERS, &quot;tcp&quot;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (cl == NULL) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Couldn&#039;t establish connection with server.<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Print error message and die.<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clnt_pcreateerror(server);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/* <br/>&nbsp;&nbsp;&nbsp;&nbsp; * Call the remote procedure &quot;printmessage&quot; on the server.<br/>&nbsp;&nbsp;&nbsp;&nbsp; */&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;result = printmessage_1(&amp;message, cl);<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (result == NULL) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * An error occurred while calling the server.<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Print error message and die<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clnt_perror(cl, server);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/*<br/>&nbsp;&nbsp;&nbsp;&nbsp; * Okay, we successfully called the remote procedure<br/>&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (*result == 0) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Server was unable to print our message.<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Print error message and die.<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, &quot;%s: %s couldn&#039;t print your message&#92;n&quot;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argv[0], server);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/*<br/>&nbsp;&nbsp;&nbsp;&nbsp; * Message got printed at server<br/>&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot;Message delivered to %s!&#92;n&quot;, server);<br/>&nbsp;&nbsp;&nbsp;&nbsp; exit(0);<br/>&#125;<br/><br/>/*<br/> * msg_proc.c&nbsp;&nbsp;implementation of the remote procedure call &quot;printmessage&quot;<br/> */<br/> <br/>#include &lt;stdio.h&gt;<br/>#include &lt;rpc/rpc.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* always needed */<br/>#include &quot;msg.h&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* msg.h will be generated by rpcgen */<br/><br/>/*<br/> * Remote version of &quot;printmessage&quot;<br/> */<br/><br/>int * printmessage_1(char **msg)<br/>&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;static int result;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* must be static! */<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;%s&#92;n&quot;, *msg);<br/>&nbsp;&nbsp;&nbsp;&nbsp;result = 1;<br/>&nbsp;&nbsp;&nbsp;&nbsp;return(&amp;result);<br/>&#125;<br/>&lt; wpi /cs/cs4513/public/example/Message 1 &gt;ls<br/><br/>msg.x&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; msg_proc.c&nbsp;&nbsp;&nbsp;&nbsp;rprintmsg.c<br/>&lt; wpi /cs/cs4513/public/example/Message 2 &gt;rpcgen msg.x<br/><br/><br/>&lt; wpi /cs/cs4513/public/example/Message 3 &gt;ls<br/><br/>msg.h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; msg_clnt.c&nbsp;&nbsp;&nbsp;&nbsp;msg_svc.c<br/>msg.x&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; msg_proc.c&nbsp;&nbsp;&nbsp;&nbsp;rprintmsg.c<br/>&lt; wpi /cs/cs4513/public/example/Message 4 &gt;cc -o msg_server msg_proc.c msg_svc.c <br/><br/>msg_proc.c:<br/>msg_svc.c:<br/>&lt; wpi /cs/cs4513/public/example/Message 5 &gt;cc -o rprintmsg rprintmsg.c msg_clnt. c<br/><br/>rprintmsg.c:<br/>msg_clnt.c:<br/>&lt; wpi /cs/cs4513/public/example/Message 6 &gt;./msg_server&amp;<br/><br/>[1] 23501<br/>&lt; wpi /cs/cs4513/public/example/Message 7 &gt;./rprintmsg wpi &quot;Hello wpi!&quot;<br/><br/>Hello wpi!<br/>Message delivered to wpi!<br/><br/>&lt; wpi /cs/cs4513/public/example/Message 8 &gt;Hello from sequoia<br/>Hello from crane, a Sun<br/>Hello from emu, a Linux machine<br/>exit<br/><br/>exit<br/>Note that the client was run on a different types of machines all sending a message to server running on wpi machine.<br/><br/>XDR/C++ Example<br/><br/><br/>/*<br/> * testxdr.x&nbsp;&nbsp;<br/> */<br/> <br/>/*<br/> * Define a procedure<br/> *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str_test_1() takes a structure parameter and returns a string<br/> *<br/> */<br/> <br/>struct testxdr&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;long long_arg;<br/>&nbsp;&nbsp;&nbsp;&nbsp;string string_arg &lt; 128 &gt;;<br/>&#125;;<br/><br/>program TEST_PROG &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;version TEST_VERS &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;string STR_TEST(testxdr) = 1;&nbsp;&nbsp;/* procedure number = 1 */<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125; = 1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* version number = 1 */<br/>&#125; = 0x31234567;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* program number = 0x31234567 */<br/>So here is an example of how to pass multiple arguments. A long and a string in a single argument. Note that rpcgen will create another file testxdr_xdr.c that must be compiled and linked.<br/><br/><br/>/* client.C&nbsp;&nbsp;*/<br/><br/>#include &lt;iostream.h&gt;<br/>#include &lt;string.h&gt;<br/><br/>#include &lt;rpc/rpc.h&gt;<br/><br/>extern &quot;C&quot; &#123;<br/>#include &quot;testxdr.h&quot;<br/>&#125;<br/><br/>main(int argc, char *argv[])<br/><br/>&#123;<br/>&nbsp;&nbsp;CLIENT *c1;<br/>&nbsp;&nbsp;char *server;<br/><br/>&nbsp;&nbsp;char **sresult;<br/><br/><br/>&nbsp;&nbsp;if (argc !=2)&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;cerr &lt;&lt;&quot;usage:&quot; &lt;&lt; argv[0] &lt;&lt;&quot; hostname&#92;n&quot;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;exit(1);<br/>&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;server = argv[1];<br/><br/>&nbsp;&nbsp;if ((c1 = clnt_create(server, TEST_PROG, TEST_VERS, &quot;udp&quot;)) == NULL)&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clnt_pcreateerror(server);<br/>&nbsp;&nbsp;&nbsp;&nbsp;exit(2);<br/>&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;testxdr xdrmessage; //structure testxdr defined in testxdr.x<br/><br/>&nbsp;&nbsp;long temp_long = 1;<br/>&nbsp;&nbsp;char *temp_str = &quot;Client is testing&quot;;<br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;//initialize xdrmessage<br/>&nbsp;&nbsp;xdrmessage.long_arg = temp_long;<br/>&nbsp;&nbsp;xdrmessage.string_arg = temp_str;<br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;if ((sresult = str_test_1(&amp;xdrmessage, c1)) == NULL)&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clnt_perror(c1, server);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(4);<br/>&nbsp;&nbsp;&nbsp;&nbsp; &#125;<br/><br/>&nbsp;&nbsp;cout &lt;&lt; &quot;Client call server successfully&#92;n &quot;;<br/>&nbsp;&nbsp;cout &lt;&lt; &quot;Server send message back:&#92;n &quot; &lt;&lt; server &lt;&lt; &quot; = &quot; &lt;&lt;*sresult&lt;&lt;&quot;&#92;n&quot;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;clnt_destroy(c1);<br/>&nbsp;&nbsp;exit(0);<br/> &#125;<br/><br/>//server.C&nbsp;&nbsp; remote procedures; called by server stub<br/><br/>#include &lt;iostream.h&gt;<br/>#include &lt;string.h&gt;<br/>#include &lt;rpc/rpc.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//* standard RPC include file */<br/><br/>extern &quot;C&quot;&#123;<br/>#include &quot;testxdr.h&quot;<br/>&#125;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//* this file is generated by rpcgen */<br/><br/><br/>/*<br/> * Accept and print out client message and return a server string<br/> */<br/>&nbsp;&nbsp;<br/>char **str_test_1(testxdr *xdrm)<br/>&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;static char *ptr = &quot;Server say Hi to client!&quot;; /* must be static */<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;cout &lt;&lt; &quot;Message from client: &quot;&lt;&lt; xdrm-&gt;string_arg &lt;&lt; &quot;&#92;n&quot;;<br/>&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;return(&amp;ptr);<br/>&#125;<br/><br/>%rpcgen testxdr.x<br/>%cc -c *.c<br/>testxdr_clnt.c:<br/>testxdr_svc.c:<br/>testxdr_xdr.c:<br/>%g++ -o server server.C testxdr_xdr.o testxdr_svc.o<br/>%g++ -o client client.C testxdr_xdr.o testxdr_clnt.o<br/>%exit<br/>exit<br/>Sun RPC Summary<br/><br/>Parameter passing: single argument passed and received (must use structures for more).<br/>Binding: done through port mapper daemon process. Must know remote server name.<br/>Transport protocol: Can use either UDP or TCP, Total size of arguments must be less than 8192 bytes for UDP. rpcgen defaults to UDP.<br/>Exception handling: If UDP is used and the client times it then it resends the request. If TCP is used and an error occurs then the request is not resent.<br/>Data representation: uses XDR.<br/>Security. Set cl-&gt;cl_auth = (3 basic types). :<br/>AUTH_NULL. null authentification (default)<br/>AUTH_SYS. Unix authentification causes following fields to be included with each RPC request: time stamp, name of the local host, Default used by NFS (network file system). client&#039;s effective user id, list of all client groups.<br/>AUTH_DES. exchanges secure information using DES (data encryption standard) for standard. Also AUTH_KERBEROS.<br/>More information in the way of Internet drafts:<br/><br/>RPC: RFC1057<br/>XDR: RFC1014<br/>Look at www.ietf.org.<br/><br/>From：http://web.cs.wpi.edu/~rek/DCS/D04/SunRPC.html
]]>
</description>
</item><item>
<link>http://jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] Sun Rpc English Language]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>