📄 xdr.nts.ms
字号:
.\".\" Must use -- eqn -- with this one.\".\" @(#)xdr.nts.ms 2.2 88/08/05 4.0 RPCSRC.EQdelim $$.EN.de BT.if \\n%=1 .tl ''- % -''...ND.\" prevent excess underlining in nroff.if n .fp 2 R.OH 'External Data Representation: Sun Technical Notes''Page %'.EH 'Page %''External Data Representation: Sun Technical Notes'.if \\n%=1 .bp.SH\&External Data Representation: Sun Technical Notes.IX XDR "Sun technical notes".LPThis chapter contains technical notes on Sun's implementation of theExternal Data Representation (XDR) standard, a set of library routinesthat allow a C programmer to describe arbitrary data structures in amachinex-independent fashion. For a formal specification of the XDRstandard, see the.I "External Data Representation Standard: Protocol Specification".XDR is the backbone of Sun's Remote Procedure Call package, in the sense that data for remote procedure calls is transmitted using the standard. XDR library routines should be used to transmit datathat is accessed (read or written) by more than one type of machine.\**.FS.IX XDR "system routines"For a compete specification of the system External Data Representationroutines, see the .I xdr(3N) manual page..FE.LPThis chapter contains a short tutorial overview of the XDR library routines, a guide to accessing currently available XDR streams, andinformation on defining new streams and data types. XDR was designedto work across different languages, operating systems, and machine architectures. Most users (particularly RPC users) will only needthe information in the.I "Number Filters",.I "Floating Point Filters",and.I "Enumeration Filters"sections. Programmers wishing to implement RPC and XDR on new machineswill be interested in the rest of the chapter, as well as the.I "External Data Representaiton Standard: Protocol Specification",which will be their primary reference..SHNote:.I.I rpcgen can be used to write XDR routines even in cases where no RPC calls arebeing made..LPOn Sun systems,C programs that want to use XDR routinesmust include the file.I <rpc/rpc.h> ,which contains all the necessary interfaces to the XDR system.Since the C library.I libc.acontains all the XDR routines,compile as normal..DSexample% \fBcc\0\fIprogram\fP.c\fI.DE.ne 3i.NH 0\&Justification.IX XDR justification.LPConsider the following two programs,.I writer :.ie t .DS.el .DS L.ft CW#include <stdio.h>.sp.5main() /* \fIwriter.c\fP */{ long i;.sp.5 for (i = 0; i < 8; i++) { if (fwrite((char *)&i, sizeof(i), 1, stdout) != 1) { fprintf(stderr, "failed!\en"); exit(1); } } exit(0);}.DEand.I reader :.ie t .DS.el .DS L.ft CW#include <stdio.h>.sp.5main() /* \fIreader.c\fP */{ long i, j;.sp.5 for (j = 0; j < 8; j++) { if (fread((char *)&i, sizeof (i), 1, stdin) != 1) { fprintf(stderr, "failed!\en"); exit(1); } printf("%ld ", i); } printf("\en"); exit(0);}.DEThe two programs appear to be portable, because (a) they pass.I lintchecking, and (b) they exhibit the same behavior when executedon two different hardware architectures, a Sun and a VAX..LPPiping the output of the.I writer program to the.I reader program gives identical results on a Sun or a VAX..DS.ft CWsun% \fBwriter | reader\fP0 1 2 3 4 5 6 7sun%vax% \fBwriter | reader\fP0 1 2 3 4 5 6 7vax%.DEWith the advent of local area networks and 4.2BSD came the concept of \*Qnetwork pipes\*U \(em a process produces data on one machine,and a second process consumes data on another machine.A network pipe can be constructed with.I writer and.I reader .Here are the results if the first produces data on a Sun,and the second consumes data on a VAX..DS.ft CWsun% \fBwriter | rsh vax reader\fP0 16777216 33554432 50331648 67108864 83886080 100663296117440512sun%.DEIdentical results can be obtained by executing.I writer on the VAX and.I reader on the Sun. These results occur because the byte orderingof long integers differs between the VAX and the Sun,even though word size is the same.Note that $16777216$ is $2 sup 24$ \(emwhen four bytes are reversed, the 1 winds up in the 24th bit..LPWhenever data is shared by two or more machine types, there isa need for portable data. Programs can be made data-portable byreplacing the.I read() and.I write() calls with calls to an XDR library routine.I xdr_long() ,a filter that knows the standard representationof a long integer in its external form.Here are the revised versions of.I writer :.ie t .DS.el .DS L.ft CW#include <stdio.h>#include <rpc/rpc.h> /* \fIxdr is a sub-library of rpc\fP */.sp.5main() /* \fIwriter.c\fP */{ XDR xdrs; long i;.sp.5 xdrstdio_create(&xdrs, stdout, XDR_ENCODE); for (i = 0; i < 8; i++) { if (!xdr_long(&xdrs, &i)) { fprintf(stderr, "failed!\en"); exit(1); } } exit(0);}.DEand.I reader :.ie t .DS.el .DS L.ft CW#include <stdio.h>#include <rpc/rpc.h> /* \fIxdr is a sub-library of rpc\fP */.sp.5main() /* \fIreader.c\fP */{ XDR xdrs; long i, j;.sp.5 xdrstdio_create(&xdrs, stdin, XDR_DECODE); for (j = 0; j < 8; j++) { if (!xdr_long(&xdrs, &i)) { fprintf(stderr, "failed!\en"); exit(1); } printf("%ld ", i); } printf("\en"); exit(0);}.DEThe new programs were executed on a Sun,on a VAX, and from a Sun to a VAX;the results are shown below..DS.ft CWsun% \fBwriter | reader\fP0 1 2 3 4 5 6 7sun%vax% \fBwriter | reader\fP0 1 2 3 4 5 6 7vax%sun% \fBwriter | rsh vax reader\fP0 1 2 3 4 5 6 7sun%.DE.SHNote:.I.IX XDR "portable data"Integers are just the tip of the portable-data iceberg. Arbitrarydata structures present portability problems, particularly withrespect to alignment and pointers. Alignment on word boundariesmay cause the size of a structure to vary from machine to machine.And pointers, which are very convenient to use, have no meaningoutside the machine where they are defined..LP.NH 1\&A Canonical Standard.IX XDR "canonical standard".LPXDR's approach to standardizing data representations is .I canonical .That is, XDR defines a single byte order (Big Endian), a singlefloating-point representation (IEEE), and so on. Any program running onany machine can use XDR to create portable data by translating itslocal representation to the XDR standard representations; similarly, anyprogram running on any machine can read portable data by translating theXDR standard representaions to its local equivalents. The single standardcompletely decouples programs that create or send portable data from thosethat use or receive portable data. The advent of a new machine or a newlanguage has no effect upon the community of existing portable data creatorsand users. A new machine joins this community by being \*Qtaught\*U how toconvert the standard representations and its local representations; thelocal representations of other machines are irrelevant. Conversely, toexisting programs running on other machines, the local representations ofthe new machine are also irrelevant; such programs can immediately readportable data produced by the new machine because such data conforms to thecanonical standards that they already understand..LPThere are strong precedents for XDR's canonical approach. For example,TCP/IP, UDP/IP, XNS, Ethernet, and, indeed, all protocols below layer fiveof the ISO model, are canonical protocols. The advantage of any canonical approach is simplicity; in the case of XDR, a single set of conversion routines is written once and is never touched again. The canonical approach has a disadvantage, but it is unimportant in real-world data transfer applications. Suppose two Little-Endian machines are transferring integersaccording to the XDR standard. The sending machine converts the integers from Little-Endian byte order to XDR (Big-Endian) byte order; the receivingmachine performs the reverse conversion. Because both machines observe thesame byte order, their conversions are unnecessary. The point, however, isnot necessity, but cost as compared to the alternative..LPThe time spent converting to and from a canonical representation isinsignificant, especially in networking applications. Most of the time required to prepare a data structure for transfer is not spent in conversion but in traversing the elements of the data structure. To transmit a tree, for example, each leaf must be visited and each element in a leaf record mustbe copied to a buffer and aligned there; storage for the leaf may have to bedeallocated as well. Similarly, to receive a tree, storage must be allocated for each leaf, data must be moved from the buffer to the leaf andproperly aligned, and pointers must be constructed to link the leaves together. Every machine pays the cost of traversing and copying datastructures whether or not conversion is required. In networking applications, communications overhead\(emthe time required to move the datadown through the sender's protocol layers, across the network and up through the receiver's protocol layers\(emdwarfs conversion overhead..NH 1\&The XDR Library.IX "XDR" "library".LPThe XDR library not only solves data portability problems, it alsoallows you to write and read arbitrary C constructs in a consistent, specified, well-documented manner. Thus, it can make sense to use the library even when the data is not shared among machines on a network..LPThe XDR library has filter routines forstrings (null-terminated arrays of bytes),structures, unions, and arrays, to name a few.Using more primitive routines,you can write your own specific XDR routinesto describe arbitrary data structures,including elements of arrays, arms of unions,or objects pointed at from other structures.The structures themselves may contain arrays of arbitrary elements,or pointers to other structures..LPLet's examine the two programs more closely.There is a family of XDR stream creation routinesin which each member treats the stream of bits differently.In our example, data is manipulated using standard I/O routines,so we use.I xdrstdio_create ()..IX xdrstdio_create() "" "\fIxdrstdio_create()\fP"The parameters to XDR stream creation routinesvary according to their function.In our example,.I xdrstdio_create() takes a pointer to an XDR structure that it initializes,a pointer to a.I FILE that the input or output is performed on, and the operation.The operation may be.I XDR_ENCODEfor serializing in the.I writer program, or.I XDR_DECODEfor deserializing in the.I reader program..LPNote: RPC users never need to create XDR streams;the RPC system itself creates these streams,which are then passed to the users..LPThe.I xdr_long() .IX xdr_long() "" "\fIxdr_long()\fP"primitive is characteristic of most XDR library primitives and all client XDR routines.First, the routine returns.I FALSE (0) if it fails, and.I TRUE (1) if it succeeds.Second, for each data type,.I xxx ,there is an associated XDR routine of the form:.DS.ft CWxdr_xxx(xdrs, xp) XDR *xdrs; xxx *xp;{}.DEIn our case,.I xxx is long, and the corresponding XDR routine isa primitive,.I xdr_long() .The client could also define an arbitrary structure.I xxx in which case the client would also supply the routine.I xdr_xxx (),describing each field by calling XDR routinesof the appropriate type.In all cases the first parameter,.I xdrs can be treated as an opaque handle,and passed to the primitive routines..LPXDR routines are direction independent;that is, the same routines are called to serialize or deserialize data.This feature is critical to software engineering of portable data.The idea is to call the same routine for either operation \(emthis almost guarantees that serialized data can also be deserialized.One routine is used by both producer and consumer of networked data.This is implemented by always passing the addressof an object rather than the object itself \(emonly in the case of deserialization is the object modified.This feature is not shown in our trivial example,but its value becomes obvious when nontrivial data structuresare passed among machines. If needed, the user can obtain thedirection of the XDR operation. See the.I "XDR Operation Directions"section below for details..LPLet's look at a slightly more complicated example.Assume that a person's gross assets and liabilitiesare to be exchanged among processes.Also assume that these values are important enoughto warrant their own data type:.ie t .DS.el .DS L.ft CWstruct gnumbers { long g_assets; long g_liabilities;};.DEThe corresponding XDR routine describing this structure would be:.ie t .DS.el .DS L.ft CWbool_t /* \fITRUE is success, FALSE is failure\fP */xdr_gnumbers(xdrs, gp) XDR *xdrs; struct gnumbers *gp;{ if (xdr_long(xdrs, &gp->g_assets) && xdr_long(xdrs, &gp->g_liabilities)) return(TRUE); return(FALSE);}.DENote that the parameter.I xdrs is never inspected or modified;it is only passed on to the subcomponent routines.It is imperative to inspect the return value of each XDR routine call,and to give up immediately and return.I FALSE if the subroutine fails..LPThis example also shows that the type.I bool_tis declared as an integer whose only values are.I TRUE (1) and.I FALSE (0). This document uses the following definitions:.ie t .DS.el .DS L.ft CW#define bool_t int#define TRUE 1#define FALSE 0.DE.LPKeeping these conventions in mind,.I xdr_gnumbers() can be rewritten as follows:.ie t .DS.el .DS L.ft CWxdr_gnumbers(xdrs, gp) XDR *xdrs; struct gnumbers *gp;{ return(xdr_long(xdrs, &gp->g_assets) && xdr_long(xdrs, &gp->g_liabilities));}.DEThis document uses both coding styles..NH 1\&XDR Library Primitives.IX "library primitives for XDR".IX XDR "library primitives".LPThis section gives a synopsis of each XDR primitive.It starts with basic data types and moves on to constructed data types.Finally, XDR utilities are discussed.The interface to these primitivesand utilities is defined in the include file.I <rpc/xdr.h> ,automatically included by.I <rpc/rpc.h> ..NH 2\&Number Filters.IX "XDR library" "number filters".LPThe XDR library provides primitives to translate between numbers
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -