|
|
|
vim_util - Version-Independent Message StreamsThe VIM utilities are used to send and receive version-independent messages over TCP/IP network connections. A VIM message consists of a 12-byte header followed by a list of zero or more, XDR-encoded name/value pairs. The contents of the header specify a message ID and the length of the message body.
A VIM stream is created on a previously established network connection. The following program implements a simple VIM server that periodically sends the time-of-day to a client:
#include <stdio.h> -- Standard I/O definitions.
#include <unistd.h> -- sleep(3) definition.
#include "tcp_util.h" -- TCP/IP networking utilities.
#include "tv_util.h" -- "timeval" manipulation functions.
#include "vim_util.h" -- Version-independent message streams.
int main (int argc, char *argv[])
{
VimStream stream ;
VimHeader header ;
NVList list ;
TcpEndpoint client, server ;
tcpListen (argv[1], 99, &server) ; -- Create listening endpoint.
for ( ; ; ) { -- Answer next client.
tcpAnswer (server, -1.0, &client) ;
vimCreate (client, &stream) ;
while (vimIsUp (client)) { -- Send times to client.
nvlCreate (NULL, &list) ;
nvlAdd (list, nvpNew ("TIME", NvpTime, tvTOD ())) ;
header.ID = 0 ; header.parameter = NULL ;
vimWriteList (stream, -1.0, &header, list) ;
nvlDestroy (list) ;
sleep (1) ;
}
vimDestroy (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.
The client program below reads and displays the time-of-day messages from the VIM server:
#include <stdio.h> -- Standard I/O definitions.
#include "tcp_util.h" -- TCP/IP networking utilities.
#include "vim_util.h" -- Version-independent message streams.
int main (int argc, char *argv[])
{
VimStream stream ;
VimHeader header ;
NVList list ;
TcpEndpoint connection ;
tcpCall (argv[1], 0, &connection) ; -- Call server.
vimCreate (connection, &stream) ;
for ( ; ; ) { -- Read times from server.
if (vimReadList (stream, -1.0, &header, &list)) break ;
printf ("Server's time = %s\n", nvpString (nvlFind ("TIME"))) ;
nvlDestroy (list) ;
}
vimDestroy (stream) ; -- Lost server.
}
The VIM message header contains an integer ID field and a void *
parameter field that can be used by clients and servers for message
identification and tagging; the VIM_UTIL package does not use these
fields. Both vimRead() and vimWrite() take
a timeout argument that allows the application to limit the amount of
time these routines wait to perform their respective functions.
In event-driven applications (e.g., those based on the X Toolkit or the
IOX dispatcher), the socket connection
underlying the VIM stream, returned by vimFd(), can be
monitored for input by your event dispatcher. Because input is buffered,
the input callback must repeatedly call vimRead() or
vimReadSet() while vimIsReadable() is true.
When a VIM stream is no longer needed, a single call will close the network connection and discard the stream:
vimDestroy (stream) ;
The name/value pair, name/value list, and version-independent message stream packages were inspired by Mike Maloney's C++ implementations of named variables and named variable sets, and by Robert Martin's attributed data trees (see "Version-Independent Messages" in Appendix B of his Designing Object-Oriented C++ Applications Using the Booch Method).
vimCreate() - creates a version-independent message stream.
vimDecode() - decodes a list of name/value pairs from a VIM message.
vimDestroy() - deletes a VIM network stream.
vimFd() - returns a VIM stream's socket number.
vimIsReadable() - checks if input is waiting to be read from a stream.
vimIsUp() - checks if a VIM stream is up.
vimIsWriteable() - checks if data can be written to a stream.
vimName() - returns the name of a VIM stream.
vimRead() - reads the next message from a VIM stream.
vimReadList() - reads an NVList message from a VIM stream.
vimWrite() - writes a message to a VIM stream.
vimWriteList() - writes an NVList message to a VIM stream.
vim_util.c
vim_util.h
(See libnet for the
complete source, including support routines and build files.)