 |
|
Simulator API
We have implemented a collection of C++ classes for interacting with
the MapleSim simulator. These classes encapsulate the details of
building, sending, receiving, and parsing command messages, and can be
extended as the user desires. The classes have been successfully
built and tested under Windows NT, Linux, and Solaris, and should be portable
to other versions of Unix (contact us if you require assistance).
All of the communication used in the SimSpy demonstration makes use of
these classes exclusively.
Class Organization
Two base classes, SimApi and SimCmd, handle all of the network
i/o and message parsing. The SimApi class maintains the network
connection, and provides methods for sending and receiving data, and for
handling exceptions. From SimApi are derived two child classes, SimApiClient
and SimApiServer, which handle the special needs of each side of
the network connection.
The SimCmd class is used for sending and receiving commands.
From it are derived classes for each of the command types and responses.
Since each command has its own class with its particular arguments, syntactic
errors are caught by the compiler as type mismatches. The structure
is also easily extensible, allowing new parameters or even entire commands
to be added without changes to the base class.
SimApi family
class SimApi
- This class defines the basic functionality of the network communication.
The class cannot be created directly; create a SimApiClient or SimApiServer instead.
MEMBER FUNCTIONS
- void Send(const SimCmd &command)
- Sends the supplied command across the network connection.
This function blocks only as long as it takes to deliver the command; it
does not wait for the response. command is usually one of
the specific command classes inherited from the SimCmd base class.
- SimCmd Receive()
- Receives a command from the network connection. The constructed command is returned to the caller. If a command isn't waiting to be read
this function will block until one becomes available.
- bool CmdWaiting()
- Returns true if the socket has data to be read, false otherwise.
class SimApiClient : public SimApi
MEMBER FUNCTIONS
- SimApiClient(const std::string &hostname, unsigned short port )
- Creates the client object. Upon creation, the class attempts to establish
a TCP/IP connection to hostname on port number port.
The connection will be maintained until there is either a network interruption
(see exceptions thrown, below) or the class instance is destroyed.
class SimApiServer : public SimApi
MEMBER FUNCTIONS
- SimApiServer(unsigned short port)
-
Creates the server object. Upon creation, the class attempts to establish
a TCP/IP server-side socket at port number port that is available
to accept incoming connections. The server socket will be maintained
until the class instance is destroyed.
SimCmd family
class SimCmd
A SimCmd is a generic command, from which all other commands are derived.
It has a command type to distinguish what variety of command it is, and
a data portion to hold the arguments to the command. The contents
of the data portion are defined by each of the derived classes for that
command type.
Each new command created contains a unique message ID number, and each
reply contains the matching ID number. The ID can be used to pair-up
responses with their corresponding requests if there are several pending
commands at a time.
Since an application cannot predict what type of command its peer will
send to it at any particular time, it must first read in the socket data
as a generic SimCmd. Once the SimCmd is read, its command type can
be determined. The SimCmd can then be passed to the constructor of
the matching SimCmd child class, which knows how to interpret the data
portion of the command in order to extract the command parameters.
When a SimCmd is read from a socket, it records the internal socket
ID and the ip address and port number of the peer that sent the command.
These fields are useful in helping a server application determine which
client has made the request.
MEMBER VARIABLES
-
const SOCKET socketid
-
The ID of the internal socket that the command was received from.
The ID will remain constant for a particular peer for as long as the connection
remains up. This field is valid only for received commands.
-
const string reason
-
The error message from the server explaining why the command failed. This
field is valid only for received commands of type FAIL.
-
unsigned long peer_ip
-
The IP address of the peer that sent the command, in host byte order. This
field is valid only for received commands.
-
unsigned short peer_port
-
The port number of the peer that sent the command, in host byte order.
This
field is valid only for received commands.
MEMBER FUNCTIONS
-
SIMCMD message_type()
-
Returns the enum value describing what type of command this is. Once
the enum type has been determined the application can pass the generic
SimCmd to the corresponding derived-class constructor for that command
type.
-
int message_id()
-
Returns the unique ID number for this command. For new commands,
this number is automatically assigned by each host. For reply commands,
the number matches the ID of the original request. A client can record
the ID numbers of command request it sends out, and then match up the responses
with the requests based on the response ID number.
-
void ReplyDone()
-
Builds a generic SIMCMD_DONE message and sends it to the requesting party.
This function is normally not used, since it doesn't provide for any return
parameters; use the specific ReplyDone() function defined for each child
class.
-
void ReplyFail(const string &reason)
-
Builds a SIMCMD_FAIL message and sends it to the requesting party.
The supplied reason should identify to the requestor why the command
failed. This reply function can be used for any of the command types.
class SimCmdRegister
-
SimCmdRegister(std::string username, std::string userorg)
-
Registers the client with the server. username and userorg
are strings identifying the user to the server. On success the server
returns a command of type SIMCMD_REGISTER_DONE; on failure it returns type
SIMCMD_FAIL.
class SimCmdRegisterDone
SimCmdRegisterDone(SimCmd &sc)
-
Processes a SimCmd of type SIMCMD_REGISTER_DONE.
class SimCmdGetMap
-
SimCmdGetMap()
-
Requests a copy of the road map from the simulation server. On success
the server returns a command of type SIMCMD_GETMAP_DONE; on failure it
returns type SIMCMD_FAIL.
class SimCmdGetMapDone
-
SimCmdGetMapDone(SimCmd &sc)
-
Processes a SimCmd of type SIMCMD_REGISTER_DONE and extracts the road map
from the data portion.
MEMBER VARIABLES
-
RoadNetwork roadnetwork
-
The road map returned from the server.
class SimCmdCreate
-
SimCmdCreate(SIM_AGENTTYPE type,SIM_LOCATION loc)
-
Creates a new type agent in the simulator at location.
SIM_AGENTTYPE and SIM_LOCATION are each enums defined in simdefs.h.
On success the server returns a command of type SIMCMD_CREATE_DONE; on
failure it returns SIMCMD_FAIL.
class SimCmdCreateDone
-
SimCmdCreateDone(SimCmd &sc)
-
Processes a SimCmd of type SIMCMD_CREATE_DONE and extracts the new agent
id from the data portion.
MEMBER VARIABLES
-
const unsigned int agentid
-
The identification number of the newly-created agent.
class SimCmdCreateXY
-
SimCmdCreateXY(SIM_AGENTTYPE type, double X, double Y, double X2, double
Y2)
-
Creates a new type agent in the simulator at location (X,Y).
If the agent is of type SIMAGENT_AIRPLANE then the arguments X2,Y2
specify the target destination; otherwise they are ignored. On success
the server returns a SimCmd of type SIMCMD_CREATEXY_DONE; on failure it
returns a SIMCMD_FAIL.
class SimCmdCreateXYDone
-
SimCmdCreateXYDone(SimCmd &sc)
-
Processes a SimCmd of type SIMCMD_CREATEXY_DONE and extracts the new agent
id from the data portion.
MEMBER VARIABLES
-
const unsigned int agentid
-
The identification number of the newly-created agent.
class SimCmdQuery
-
SimCmdQuery(unsigned short id=0, double dist=0.0, SIM_AGENTTYPE type=SIMAGENT_NONE)
-
Queries the simulator for a report of all agents of id number id,
within dist, and of agent type type. Any or all of
the arguments can be left out or set to zero in order to act as wildcards
for that field. On success the server returns a SimCmd of type SIMCMD_QUERY_DONE
containing the agent details; on failure it returns a SIMCMD_FAIL.
class SimCmdQueryDone
SimCmdQueryDone(SimCmd &sc)
-
Processes a SimCmd of type SIMCMD_QUERY_DONE and extracts the agent state
information from the data portion.
MEMBER VARIABLES
-
const SimAgentStates updates
-
A std::vector of SimAgentState information about the agents that matched
the query.
class SimCmdMove
-
SimCmdMove(unsigned short id, int heading, int speed)
-
Requests the simulator to start moving agent number id towards heading
at speed. On success the server returns a SimCmd of type SIMCMD_MOVE_DONE;
on failure it returns a SIMCMD_FAIL.
class SimCmdMoveDone
-
SimCmdMove(SimCmd &sc)
-
Processes a SimCmd of type SIMCMD_MOVE_DONE.
class SimCmdDestroy
-
SimCmdDestroy(unsigned short id)
-
Requests that the simulator remove agent number id from the simulation.
On success the server returns a SimCmd of type SIMCMD_DESTROY_DONE; on
failure it returns a SIMCMD_FAIL.
class SimCmdDestroyDone
SimCmdDestroy(SimCmd &sc)
-
Processes a SimCmd of type SIMCMD_DESTROY_DONE.
SimCmdError exceptions
The SimApi and SimCmd classes throw exceptions under certain circumstances.
These exceptions can be caught and handled by the application in order
to provide for robust error recovery, or they can be left to terminate
the application in order to prevent serious problems.
All of the exception classes have a public member message which
describes the reason for the exception. The message value
is suitable for printing to the end user in order to explain what went
wrong in the cases that the exception cannot be handled by the application.
class SimCmdError
This exception can be thrown by the following functions under the circumstances
described:
-
SimApi::SimApi()
-
Unable to locate compatible winsock.dll (WindowsNT version only)
-
SimApiClient::SimApiClient()
-
Unable to resolve hostname to an IP address
-
Unable to create socket for communications
-
Unable to connect to the Simulation server
-
SimApiServer::SimApiServer()
-
Unable to create server socket
-
Unable to bind address to server socket
-
Unable to listen for new connections
-
SimApi::Send()
-
Output buffer overflow; message not sent
-
SimApi::Receive()
-
WSA Error number #### encountered while retrieving peer IP address
(WindowsNT version only)
-
SimApiServer::Receive()
-
Primary server socket received an error
-
Unable to accept new connection
-
SimApiServer::CmdWaiting()
-
Primary server socket received an error
-
SimCmd::message_type()
-
Invalid command type detected
-
SimCmd***::SimCmd***() [any of the SimCmd*** constructors, when extracting
from a generic SimCmd]
-
Mismatched command type
-
SimApiServer::Read()
-
Primary server socket received an error
-
class SimCmdSocketClosed
This exception is used to alert the application that the communications
socket has closed during reading or writing. The application can
then take measures to re-establish communication (usually in the case of
a client), or to free the other resources associated with the connection
and wait for a reconnect (in the case of a server). The public member
variable closedsocket is set to the SOCKET id of the socket that
closed. By the time the application receives this exception SimApi
has already closed the socket itself and freed any internal resources associated
with it.
This exception can be thrown by the following functions:
-
SimApi::Send()
-
SimApi::Receive()
-
SimApiClient::CmdWaiting()
-
SimApiServer::CmdWaiting()
-
SimApiServer::Receive()
-
Last Updated May 8, 1999
|
|
 |