Home

GEONius.com
2-Oct-2015
E-mail

xnet_util - XDR Networking Utilities

The XNET utilities provide a high-level interface to the Sun XDR routines that perform record-oriented communications across a network connection. The XNET package is layered on top of the lower-level TCP_UTIL functions. Network connections can be established between clients and servers and XDR streams are built on these connections. The read and write functions make it easy to send ASCII text records back and forth between processes.

A simple server process that reads and displays the ASCII text messages it receives could be as brief as the following program:

    #include  <stdio.h>				-- Standard I/O definitions.
    #include  "tcp_util.h"			-- TCP/IP networking utilities.
    #include  "xnet_util.h"			-- XNET definitions.

    int  main (int argc, char *argv[])
    {
        char  *message ;
        TcpEndpoint  client, server ;
        XnetStream  stream ;

        tcpListen (argv[1], 99, &server) ;	-- Create listening endpoint.

        for ( ; ; ) {				-- Answer next client.
            tcpAnswer (server, -1.0, &client) ;
            xnetCreate (client, NULL, &stream) ;
            for ( ; ; ) {			-- Service connected client.
                if (xnetRead (stream, -1.0, &message))  break ;
                printf ("Message: %s\n", message) ;
            }
            xnetDestroy (stream) ;		-- Lost client.
        }

    }

The server's name is specified as the first argument on the command line (i.e., argv[1]). If a client connection is broken, the server loops back to wait for another client.

A simple client process that reads its user's input and forwards it to the server process would look as follows:

    #include  <stdio.h>				-- Standard I/O definitions.
    #include  "tcp_util.h"			-- TCP/IP networking utilities.
    #include  "xnet_util.h"			-- XNET definitions.

    int  main (int argc, char *argv[])
    {
        char  buffer[128] ;
        TcpEndpoint  connection ;
        XnetStream  stream ;
						-- Call server.
        tcpCall (argv[1], -1.0, -1.0, &connection) ;
        xnetCreate (connection, NULL, &stream) ;
        for ( ; ; ) {				-- Forward input to server.
            if (gets (buffer) == NULL)  break ;
            xnetWrite (stream, -1.0, "%s", buffer) ;
        }
        xnetDestroy (stream) ;			-- Lost user!

    }

Although the XNET functions are especially suited to exchanging ASCII messages between processes, an application can still access the lower-level XDR routines. xnetHandle() returns the address of the XDR stream structure that is needed for the system XDR calls. The following server periodically sends its client the current time (in a record containing a UNIX timeval structure):

    #include  <stdio.h>				-- Standard I/O definitions.
    #include  <rpc/rpc.h>			-- RPC/XDR definitions.
    #include  <sys/time.h>			-- System time definitions.
    #include  "tcp_util.h"			-- TCP/IP networking utilities.
    #include  "xnet_util.h"			-- XNET definitions.

    int  main (int argc, char *argv[])
    {
        struct  timeval  currentTime ;
        TcpEndpoint  client, server ;
        XDR  *xdrStream ;
        XnetStream  stream ;

        tcpListen (argv[1], 99, &server) ;	-- Create listening endpoint.

        for ( ; ; ) {				-- Answer next client.
            tcpAnswer (server, -1.0, &client) ;
            xnetCreate (client, NULL, &stream) ;
            xdrStream = xnetHandle (stream) ;
            for ( ; ; ) {			-- Service connected client.
                gettimeofday (¤tTime, NULL) ;
                if (!xdr_timeval (xdrStream, ¤tTime) ||
                    xnetEndRecord (stream))  break ;
                sleep (1) ;
            }
            xnetDestroy (stream) ;		-- Lost client.
        }

    }

After manually constructing an output record using low-level XDR functions, the program must terminate the record with a call to xnetEndRecord(), as the example above shows. Likewise, after decoding an input record using low-level XDR functions, the program must "close" the current record and advance to the beginning of the next record with a single call to xnetNextRecord(). [xnetWrite() and xnetRead(), respectively, call these functions automatically.]

In event-driven applications (e.g., those based on the X Toolkit or the IOX dispatcher), the socket connection underlying the XDR stream, returned by xnetFd(), can be monitored for input by your event dispatcher. Because input is buffered by the XDR library, the input callback must continue to read XDR records while xnetIsReadable() is true. When reading string records, calls to xnetRead() can simply be interleaved with calls to xnetIsReadable():

    while (xnetIsReadable (stream)) {
        if (xnetRead (stream, -1.0, &message))  break ;
        ... process message ...
    }

When manually decoding input records, xnetIsReadable() should only be checked in between records, not in the middle of a record:

    while (xnetIsReadable (stream)) {
        if (!xdr_int (xdrStream, &value1) ||
            !xdr_int (xdrStream, &value2) ||
            xnetEndRecord (stream))  break ;
        ... process values ...
    }

Public Procedures

xnetCreate() - creates an XDR-based network stream.
xnetDestroy() - deletes an XDR-based network stream.
xnetEndRecord() - outputs the contents of the current output record to an XDR stream and begins a new record.
xnetFd() - returns an XNET stream's socket number.
xnetFlush() - flushes any queued output to the XNET stream's socket.
xnetHandle() - returns an XNET stream's XDR handle.
xnetIsReadable() - checks if input is waiting to be read from a stream.
xnetIsUp() - checks if an XNET stream is up.
xnetIsWriteable() - checks if data can be written to a stream.
xnetNextRecord() - positions to the beginning of the next input record.
xnetRead() - reads a record containing an XDR string from an XNET stream.
xnetSetTimeout() - sets the I/O timeout on an XNET stream.
xnetWrite() - writes a record containing an XDR string to an XNET stream.

Source Files

xnet_util.c
xnet_util.h

(See libnet for the complete source, including support routines and build files.)


Alex Measday  /  E-mail