|
|
|
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.)