EpochStream - EPOCH V3 Network Stream

EpochStream objects are used to exchange EPOCH V3-compatible messages over TCP/IP network connections. The EpochStream implementation differs from the comparable capabilities in the ISI Communications Library in that:

    The network communications are divorced from the event loop; consequently, EpochStream connections are easily used with the ISI Communications Library main loop, the X Toolkit main loop, and the ERAL Dispatcher, among others. The mechanics of the network communications are close to the surface, thus giving you great flexibility in and control over using these streams, as well as knowledge of what is actually going on "under the hood". Input and output on EpochStreams are both buffered, so large-volume data transfers are handled efficiently.

The following (working) program is a simple server that unconditionally returns an EPOCH V3 acknowledgement for every command it receives:

    #include  "EpochStream.h"			// Epoch stream class.

    int  main (int argc, char *argv[])
        EpochStream  client ;
        TcpEndpoint  server (argv[1]) ;
        server.Listen () ;			// Listen for clients.

        for ( ; ; ) {
            EpochMessage  *command, response ;
            server.Answer (client) ;		// Answer next client.
            for ( ; ; ) {			// Service connected client.
                if (client.Read (command))  break ;
                response.Type (MSG_ACK) ;	// Construct response message.
                response.ID (command->ID ()) ;
                delete command ;
                client.Write (response) ;	// Send acknowledgement message.
            client.Close () ;			// Lost client.


The following (working) program is a simple client that connects to an EPOCH V3 device handler and initiates the reading of data from the device:

    #include  <cstdio>			// Standard I/O definitions.
    #include  "EpochStream.h"			// Epoch stream class.

    int  main (int argc, char *argv[])
        EpochStream  device (argv[1]) ;
        device.Call () ;			// Connect to device handler.

        EpochMessage  *message = new EpochMessage (MSG_CONNECT) ;
        NVarSet  *set = new NVarSet ;
        set->Add (new NVar (0, "HANDLEUNIT")) ;
        set->Add (new NVar (1, "STATUSCHANGE")) ;
        message->Encode (set) ;
        device.Write (*message) ;		// Send CONNECT message.
        delete set ;

        message->Type (MSG_DEV_READ) ;
        message->Body (0, 0) ;
        device.Write (*message) ;		// Request data from device.
        delete message ;

        for ( ; ; ) {				// Read and display messages.
            if (device.Read (message))  break ;
            set = message->Decode () ;
            for (int  i = 0 ;  i < set->Count () ;  i++)
                printf ("  %d:\t%s\n", i, (set->Get (i))->Encode ()) ;
            delete set ;
            delete message ;


In event-driven applications (e.g., those based on the X Toolkit or the ERAL Dispatcher), the socket connection underlying the EPOCH stream, returned by Fd(), can be monitored for input by the event dispatcher. Because input is buffered, the input callback must repeatedly call Read() while IsReadable() is true.

Output can be buffered by specifying a zero or positive timeout in the call to Write(). Subsequently calling Flush() or Write() with a negative timeout results in all of the buffered output being written to the network connection. If output is buffered in an event-driven application, the stream's socket connection can be registered as an output source with the event dispatcher. When the dispatcher detects that the connection is ready for output, the output callback should call Flush() with a zero or positive timeout in order to output as much as it can of the buffered data. After all of the buffered data has been flushed [PendingOutput() returns false], the output callback should unregister the socket connection so as to keep the event dispatcher from endlessly cycling on an output-ready condition.

Public Methods

(In addition to those inherited from BufferedTCP.)

EpochStream() - creates an EPOCH stream by service name.
EpochStream() - creates an EPOCH stream by port number.
~EpochStream() - destroys an EPOCH stream.
Read() - reads an EPOCH message from a stream.
Write() - writes an EPOCH message to a stream.

Source Files


Alex Measday  /  E-mail