index previous next 

file name: sockstre.hpp, sockstre.cpp
classification: simulation
contents: class CStreamInterface, derived from class CSocket, class CStreamServer, derived from class CStreamInterface, class CStreamClient, derived from class CStreamInterface
use: an interface to stream sockets, plus server and client sockets
 

global items used by CStreamInterface:

 
local items defined in the implementation file:

static const INT16 ByteOrderTest: This constant is sent to check the byte order of the communication partner.

static INT32 Convert (INT32 src): Reverts the byte order of src and returns the reverted value.

 
member variables of CStreamInterface:

EBool byteOrderReversed_: is set to True if the byte ordering of the communication partners is not the same, False if it is.
default value: False

SINT32 receiveMsgID_: The message ID of the last message that was received.
default and reset value: NoAccount

INT32 sendMsgID_: The message ID of the next message that is to be sent.
default and reset value: 0
 

member functions of CStreamInterface:

CStreamInterface (ACSocketAddress* addr, INT32 sid): Calls the ctor of the base class with stream = True, sets all members to their default values.

CStreamInterface (ACSocketAddress *addr): Calls the corresponding ctor of the base class with stream = True, sets all members to their default values.

EBool ByteOrderReversed () const: Returns True if the byte ordering of the communication partners is not the same (use SendByteOrder()/ReceiveByteOrder() to find out about that), False if the ordering is the same or if it was never checked.

static void *GetMessageBuffer (INT32 size): Allocates an array of size bytes and returns a pointer to the memory. If size is greater than MaxMessageSize, an assert fails.

SINT32 GetMessageID () const: Returns the ID of the last message that has been received, or NoAccount if no message has ever been received.

virtual void Init (): Sets all members to their reset values.

EBool ReceiveByteOrder (double timeout=0): Assumes that a message sent by
SendByteOrder() is pending on the socket. The function first reads the header (which blocks according to timeout), and if that was successful, the INT16 value is read (now the internal timeout is used). If the message was received successfully, the value read is compared with the default value 0x1234. If the two are equal, byteOrderReversed is set to False, if they are different, byteOrderReversed is set to True. In any case, the function returns True if the message could be read successfully, False if an error occurred.

EBool ReceiveMessage (SBase **data): The function assumes that the message type has already been read using ReceiveMessageHeader(), and that the message ID is the next item in the socket, followed by a structure derived from SBase. The first member in SBase must be INT32 size, which should contain the size of the structure. The function first reads the four bytes of the message ID and stores it in sendMsgID. Then, it reads the next four bytes, which must already belong to SBase (the size member). If ByteOrderReversed() returns True, the order of these four bytes is reversed to get the correct size. Using this, the function allocates the appropriate amount of memory, stores the size into the size member, reads the rest of the structure into it (here, the byte order is ignored, since the contents of the structure is not known) and stores a pointer to the memory in *data.  If the data is split into several packets, the function reads packets and stores their data in the allocated memory until the expected amount of bytes has been read or a receive error occurs. The function returns True if everything could be read successfully, False if some error occurred (the socket calls block according to the internal timeout of the base class).
Note: the memory *must* be returned using ReturnMessageBuffer()! If data is NULL, an assert fails.

EBool ReceiveMessageHeader (EMessageType *type, double timeout = 0): Reads the first datum of a message, which is a one byte message type. The call blocks according to timeout: if timeout is negative, the call waits for ever, otherwise it waits for at most timeout seconds. If the type was received, it is copied into *type and True is returned. If the socket call timed out, False is returned and type is not modified. If type is NULL, an assert fails.

EBool ReceiveMessageID (double timeout = 0): Reads four bytes from the socket and stores them in receiveMsgID if successful. The socket call blocks according to timeout. The function returns True if successful, False in case of an error.

EBool ReceiveModule (EModule& module, double timeout=0): Assumes that a message sent by SendModule() is pending on the socket. The function first reads the header (which blocks according to timeout), and if that was successful, the module is read (now the internal timeout is used). If the message was received successfully, the module type is stored in module and True is returned. If an error occurred, the function returns False and leaves module unchanged.

EBool ReplyToMessage (SBase *data): Sends a message of type MsgReply with the message body data. Uses receiveMsgID as message ID (so it is a reply to the last received message). The function returns True if the message could be sent successfully, False in case of an error. If data is NULL, or if no message has been received (receiveMsgID is set to NoAccount), an assert fails.

EBool Resynchronize(): Sends the message header MsgResynchronize. Returns True if the message could be sent successfully, False if not.

static void ReturnMessageBuffer (void *buffer): Deallocates the buffer. The function assumes that the memory has been allocated using function GetMessageBuffer().
Note: buffers obtained by ReceiveMessage() *must* be returned using this function.

EBool SendByteOrder(): : Sends a message with the header MsgByteOrder, which is followed directly by an INT16 with the value 0x1234. Returns True if the message could be sent successfully, False if not.
Note: use ReceiveByteOrder() to receive such a message.

INT32 SendMessage (EMessageType type, SBase *data): Transmits the type, sendMsgID and the structure over the socket (the message ID is inserted automatically), returns the message ID. If the message ID was transmitted successfully, sendMsgID is incremented. If the send operation has failed, NoAccount is returned. The size parameter of the data structure and the message ID are converted to the byte order of the peer before they are sent. If data is NULL, an assert fails.

EBool SendMessage (void *data, INT32 size): Sends a message consisting of the INT32 size, followed by data. If ByteOrderReversed() returns True, then size is converted to the byte order of the receiver before it is sent. The function returns True if the message could be sent successfully, False if an error occurred.

EBool SendMessageHeader (EMessageType type): Sends the first byte of the message (ie., the type). Returns True if the message could be sent successfully, else False.

EBool SendMessageID (): Calls SendMessageID (INT32) with the (default) message ID stored in sendMsgID. If the message could be sent successfully, sendMsgID is incremented and the function returns True. Otherwise, the default message ID stays the same and False is returned.

EBool SendMessageID (INT32 id): Sends the message ID id. If ByteOrderReversed() is True then id is converted to the byte order of the peer before it is sent. The function returns True if the message could be sent successfully, else False.

EBool SendModule (EModule module): Sends a message consisting of the header
MsgModule, directly followed by module, which is cast to INT8. Returns True if the message could be sent successfully, False if not.
Note: use ReceiveModule() to receive such a message.

EBool SendSynchronizationByte(): Sends the header MsgSynchronizationByte. Returns True if the message could be sent successfully, False if not.
 

global items used by CStreamServer:

 
member functions of CStreamServer:

CStreamServer (ACSocketAddress *addr): Creates a socket with address addr and listens to it. The socket ID is stored using function SetSocketID().

virtual ~CStreamServer (): Closes the socket and unlinks it if its address family is AF_UNIX.

CStreamInterface *Accept(): Accepts a new connection. If the call to s_accept() fails, NULL is returned. Otherwise, a new socket with the socket ID obtained from s_accept() is created, ReceiveByteOrder() is called to establish the byte order of the client, and the new socket is returned. If the call to ReceiveByteOrder() returns False, an assert fails.
 

global items used by CStreamClient:

 
member functions of CStreamClient:

CStreamClient (ACSocketAddress *addr): Calls Connect() to connect to the socket. Connect() tries to connect for at most MaxTrials times. If the connection cannot be established, an assert fails.

CStreamClient (ACSocketAddress *addr, int numberOfTrials): Calls Connect() to connect to the socket. Connect() gives up after numberOfTrials trials. If the connection cannot be established, an assert fails.

EBool Connect (ACSocketAddress *addr, int numberOfTrials): Repeatedly calls s_ident() to connect to the socket until the connection is established. The function is called for at most numberOfTrials times. If s_ident() succeeds, the socket ID is stored using function SetSocketID(), SendByteOrder() is called to notify the server of the local byte order, and True is returned. Otherwise, the function returns False.
If the call to SendByteOrder() returns False, an assert fails.
 


last modified: Fri Feb 5 18:56:35 1999