ONC+ Developer's Guide

Record TCP/IP Streams

A record stream is an XDR stream built on top of a record-marking standard that is built on top of the UNIX file or 4.2 BSD connection interface.

#include <rpc/rpc.h>      /* xdr is part of rpc */

xdrrec_create(xdrs, sendsize, recvsize, iohandle, readproc,
              writeproc)
   XDR *xdrs;
   u_int sendsize, recvsize;
  	char *iohandle;
  	int (*readproc)(), (*writeproc)();

The routine xdrrec_create() provides an XDR stream interface that allows for a bidirectional, arbitrarily long sequence of records. The contents of the records are meant to be data in XDR form. The stream's primary use is for interfacing RPC to TCP connections. However, it can be used to stream data into or out of normal UNIX files.

The parameter xdrs is similar to the corresponding parameter described previously. The stream does its own data buffering similar to that of standard I/O. The parameters sendsize and recvsize determine the size in bytes of the output and input buffers respectively. If their values are zero (0), then predetermined defaults are used.

When a buffer needs to be filled or flushed, the routine readproc() or writeproc() is called respectively. The usage and behavior of these routines are similar to the UNIX system calls read() and write(). However, the first parameter to each of these routines is the opaque parameter iohandle. The other two parameters, and nbytes and the results, byte count, are identical to the system routines. If xxx() is readproc() or writeproc(), then it has the following form:

/* returns the actual number of bytes transferred. -1 is an error */int
xxx(iohandle, buf, len)
  	char *iohandle;
  	char *buf;
  	int nbytes;

The XDR stream provides a means for delimiting records in the byte stream. Abstract data types needed to implement the XDR stream mechanism are discussed in XDR Stream Implementation. The protocol RPC uses to delimit XDR stream records is discussed in Record-Marking Standard.

The primitives that are specific to record streams are:

bool_t
xdrrec_endofrecord(xdrs, flushnow)
   XDR *xdrs;
   bool_t flushnow;

bool_t
xdrrec_skiprecord(xdrs)
   XDR *xdrs;

bool_t
xdrrec_eof(xdrs)
   XDR *xdrs;

The routine xdrrec_endofrecord() causes the current outgoing data to be marked as a record. If the parameter flushnow is TRUE, then the stream's writeproc() is called. Otherwise, writeproc() is called when the output buffer is full.

The routine xdrrec_skiprecord() causes an input stream's position to be moved past the current record boundary and onto the beginning of the next record in the stream.

If no more data is in the stream's input buffer, then the routine xdrrec_eof() returns TRUE. That does not mean that no more data is in the underlying file descriptor.