⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rpcgen.ms

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 MS
📖 第 1 页 / 共 3 页
字号:
.\".\" Must use  --  tbl -- for this one.\".\" @(#)rpcgen.ms	2.2 88/08/04 4.0 RPCSRC.de BT.if \\n%=1 .tl ''- % -''...ND.\" prevent excess underlining in nroff.if n .fp 2 R.OH '\fBrpcgen\fP Programming Guide''Page %'.EH 'Page %''\fBrpcgen\fP Programming Guide'.if \\n%=1 .bp.SH\&\fBrpcgen\fP Programming Guide.NH 0\&The \fBrpcgen\fP Protocol Compiler.IX rpcgen "" \fIrpcgen\fP "" PAGE MAJOR.LP.IX RPC "" "" \fIrpcgen\fPThe details of programming applications to use Remote Procedure Calls can be overwhelming.  Perhaps most daunting is the writing of the XDR routines necessary to convert procedure arguments and results into their network format and vice-versa.  .LPFortunately, .I rpcgen(1) exists to help programmers write RPC applications simply and directly..I rpcgen does most of the dirty work, allowing programmers to debug the  main  features of their application, instead of requiring them tospend most of their time debugging their network interface code..LP.I rpcgen is a  compiler.  It accepts a remote program interface definition writtenin a language, called RPC Language, which is similar to C.  It produces a Clanguage output which includes stub versions of the client routines, aserver skeleton, XDR filter routines for both parameters and results, and aheader file that contains common definitions. The client stubs interfacewith the RPC library and effectively hide the network from their callers.The server stub similarly hides the network from the server procedures thatare to be invoked by remote clients..I rpcgen 'soutput files can be compiled and linked in the usual way.  The developerwrites server procedures\(emin any language that observes Sun callingconventions\(emand links them with the server skeleton produced by.I rpcgen to get an executable server program.  To use a remote program, a programmerwrites an ordinary main program that makes local procedure calls to the client stubs produced by.I rpcgen .Linking this program with .I rpcgen 'sstubs creates an executable program.  (At present the main program must be written in C)..I rpcgen options can be used to suppress stub generation and to specify the transportto be used by the server stub..LPLike all compilers, .I rpcgen reduces development timethat would otherwise be spent coding and debugging low-level routines.All compilers, including .I rpcgen ,do this at a small cost in efficiencyand flexibility.  However,   many compilers allow  escape  hatches forprogrammers to  mix low-level code with  high-level code. .I rpcgen is no exception.  In speed-critical applications, hand-written routines can be linked with the .I rpcgen output without any difficulty.  Also, one may proceed by using.I rpcgen output as a starting point, and then rewriting it as necessary.(If you need a discussion of RPC programming without.I rpcgen ,see the.I "Remote Procedure Call Programming Guide)\..NH 1\&Converting Local Procedures into Remote Procedures.IX rpcgen "local procedures" \fIrpcgen\fP.IX rpcgen "remote procedures" \fIrpcgen\fP.LPAssume an application that runs on a single machine, one which we want to convert to run over the network.  Here we will demonstrate such a conversion by way of a simple example\(ema program that prints a message to the console:.ie t .DS.el .DS L.ft I/* * printmsg.c: print a message on the console */.ft CW#include <stdio.h>main(argc, argv)	int argc;	char *argv[];{	char *message;	if (argc < 2) {		fprintf(stderr, "usage: %s <message>\en", argv[0]);		exit(1);	}	message = argv[1];	if (!printmessage(message)) {		fprintf(stderr, "%s: couldn't print your message\en",			argv[0]);		exit(1);	} 	printf("Message Delivered!\en");	exit(0);}.ft I/* * Print a message to the console. * Return a boolean indicating whether the message was actually printed. */.ft CWprintmessage(msg)	char *msg;{	FILE *f;	f = fopen("/dev/console", "w");	if (f == NULL) {		return (0);	}	fprintf(f, "%s\en", msg);	fclose(f);	return(1);}.DE.LPAnd then, of course:.ie t .DS.el .DS L.ft CWexample%  \fBcc printmsg.c -o printmsg\fPexample%  \fBprintmsg "Hello, there."\fPMessage delivered!example%.DE.LPIf  .I printmessage() was turned into  a remote procedure,then it could be  called from anywhere in   the network.  Ideally,  one would just  like to stick   a  keyword like  .I remote in  front  of aprocedure to turn it into a  remote procedure.  Unfortunately,we  have to live  within the  constraints of  the   C language, since it existed   long before  RPC did.  But   even without language support, it's not very difficult to make a procedure remote..LPIn  general, it's necessary to figure  out  what the types are forall procedure inputs and outputs.  In  this case,   we  have a procedure.I printmessage() which takes a  string as input, and returns  an integeras output.  Knowing  this, we can write a  protocol specification in RPClanguage that  describes the remote  version of .I printmessage ().Here it is:.ie t .DS.el .DS L.ft I/* * msg.x: Remote message printing protocol */.ft CWprogram MESSAGEPROG {	version MESSAGEVERS {		int PRINTMESSAGE(string) = 1;	} = 1;} = 99;.DE.LPRemote procedures are part of remote programs, so we actually declaredan  entire  remote program  here  which contains  the single procedure.I PRINTMESSAGE .This procedure was declared to be  in version  1 of theremote program.  No null procedure (procedure 0) is necessary because.I rpcgen generates it automatically..LPNotice that everything is declared with all capital  letters.  This isnot required, but is a good convention to follow..LPNotice also that the argument type is \*Qstring\*U and not \*Qchar *\*U.  Thisis because a \*Qchar *\*U in C is ambiguous.  Programmers usually intend itto mean  a null-terminated string   of characters, but  it  could alsorepresent a pointer to a single character or a  pointer to an array ofcharacters.  In  RPC language,  a  null-terminated  string is unambiguously called a \*Qstring\*U..LPThere are  just two more things to  write.  First, there is the remoteprocedure itself.  Here's the definition of a remote procedureto implement the.I PRINTMESSAGEprocedure we declared above:.ie t .DS.el .DS L.vs 11.ft I/* * msg_proc.c: implementation of the remote procedure "printmessage" */.ft CW#include <stdio.h>#include <rpc/rpc.h>    /* \fIalways needed\fP  */#include "msg.h"        /* \fIneed this too: msg.h will be generated by rpcgen\fP */.ft I/* * Remote verson of "printmessage" */.ft CWint *printmessage_1(msg)	char **msg;{	static int result;  /* \fImust be static!\fP */	FILE *f;	f = fopen("/dev/console", "w");	if (f == NULL) {		result = 0;		return (&result);	}	fprintf(f, "%s\en", *msg);	fclose(f);	result = 1;	return (&result);}.vs.DE.LPNotice here that the declaration of the remote procedure.I printmessage_1() differs from that of the local procedure.I printmessage() in three ways:.IP  1.It takes a pointer to a string instead of a string itself.  Thisis true of all  remote procedures:  they always take pointers to  theirarguments rather than the arguments themselves..IP  2.It returns a pointer to an  integer instead of  an integer itself. This isalso generally true of remote procedures: they always return a pointerto their results..IP  3.It has an \*Q_1\*U appended to its name.  In general, all remoteprocedures called by .I rpcgen are named by  the following rule: the name in the program  definition  (here .I PRINTMESSAGE )is converted   to alllower-case letters, an underbar (\*Q_\*U) is appended to it, andfinally the version number (here 1) is appended..LPThe last thing to do is declare the main client program that will callthe remote procedure. Here it is:.ie t .DS.el .DS L.ft I/* * rprintmsg.c: remote version of "printmsg.c" */.ft CW#include <stdio.h>#include <rpc/rpc.h>     /* \fIalways needed\fP  */#include "msg.h"         /* \fIneed this too: msg.h will be generated by rpcgen\fP */main(argc, argv)	int argc;	char *argv[];{	CLIENT *cl;	int *result;	char *server;	char *message;	if (argc < 3) {		fprintf(stderr, "usage: %s host message\en", argv[0]);		exit(1);	}.ft I	/*	 * Save values of command line arguments 	 */.ft CW	server = argv[1];	message = argv[2];.ft I	/*	 * Create client "handle" used for calling \fIMESSAGEPROG\fP on the	 * server designated on the command line. We tell the RPC package	 * to use the "tcp" protocol when contacting the server.	 */.ft CW	cl = clnt_create(server, MESSAGEPROG, MESSAGEVERS, "tcp");	if (cl == NULL) {.ft I		/*		 * Couldn't establish connection with server.		 * Print error message and die.		 */.ft CW		clnt_pcreateerror(server);		exit(1);	}.ft I	/*	 * Call the remote procedure "printmessage" on the server	 */.ft CW	result = printmessage_1(&message, cl);	if (result == NULL) {.ft I		/*		 * An error occurred while calling the server. 	 	 * Print error message and die.		 */.ft CW		clnt_perror(cl, server);		exit(1);	}.ft I	/*	 * Okay, we successfully called the remote procedure.	 */.ft CW	if (*result == 0) {.ft I		/*		 * Server was unable to print our message. 		 * Print error message and die.		 */.ft CW		fprintf(stderr, "%s: %s couldn't print your message\en", 			argv[0], server);			exit(1);	} .ft I	/*	 * The message got printed on the server's console	 */.ft CW	printf("Message delivered to %s!\en", server);}.DEThere are two things to note here:.IP  1..IX "client handle, used by rpcgen" "" "client handle, used by \fIrpcgen\fP"First a client \*Qhandle\*U is created using the RPC library routine.I clnt_create ().This client handle will be passed  to the stub routineswhich call the remote procedure..IP  2.The remote procedure  .I printmessage_1() is called exactly  the same way as it is  declared in .I msg_proc.c except for the inserted client handle as the first argument..LPHere's how to put all of the pieces together:.ie t .DS.el .DS L.ft CWexample%  \fBrpcgen msg.x\fPexample%  \fBcc rprintmsg.c msg_clnt.c -o rprintmsg\fPexample%  \fBcc msg_proc.c msg_svc.c -o msg_server\fP.DETwo programs were compiled here: the client program .I rprintmsg and the server  program .I msg_server .Before doing this  though,  .I rpcgen was used to fill in the missing pieces.  .LPHere is what .I rpcgen did with the input file .I msg.x :.IP  1.It created a header file called .I msg.h that contained.I #define 'sfor.I MESSAGEPROG ,.I MESSAGEVERS and    .I PRINTMESSAGE for use in  the  other modules..IP  2.It created client \*Qstub\*U routines in the.I msg_clnt.c file.   In this case there is only one, the .I printmessage_1() that was referred to from the.I printmsg client program.  The name  of the output file forclient stub routines is always formed in this way:  if the name of theinput file is  .I FOO.x ,the   client  stubs   output file is    called.I FOO_clnt.c ..IP  3.It created  the  server   program which calls   .I printmessage_1() in.I msg_proc.c .This server program is named  .I msg_svc.c .The rule for naming the server output file is similar  to the previous one:  for an input  file   called  .I FOO.x ,the   output   server   file is  named

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -