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:
EpochStream connections are easily used with the ISI
Communications Library main loop, the X Toolkit main loop, and the ERAL
Dispatcher, among others.
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.
(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.
EpochStream.cpp
EpochStream.h