Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

ssobjects::SimpleServer Class Reference

Simple Server object used for creating a full fledged server. More...

#include <simpleserver.h>

Inheritance diagram for ssobjects::SimpleServer::

ssobjects::ThreadHandler ssobjects::CMclThreadHandler List of all members.

Public Types

enum  { MIN_FREQ = 10 }

Public Methods

 SimpleServer (const SockAddr &saBind, const unsigned32 nFreq=1000, const unsigned32 nMaxConnections=100)
 Single-threaded constructor. More...

 SimpleServer (ServerSocket *const psocket, const unsigned32 nFreq)
 Multi-threaded constructor. More...

virtual ~SimpleServer ()
virtual void startServer ()
 Starts up the server, makes ready for connections. More...

virtual void killServer ()
 Stops server, and closes all connections. More...

virtual void pauseIncomingConnections ()
 (Not currently in use.) Server will no longer accept connections. More...

virtual void sendPacket (ServerSocket *psocket, const PacketBuffer &packet)
 Sends a packet over a socket. More...

virtual void sendPacket (ServerSocket *psocket, const PacketBuffer *ppacket)
 Sends a packet over a socket. More...

virtual void send2All (const PacketBuffer &packet)
 Sends a packet to all client sockets connected to the server. More...

virtual void send2All (const PacketBuffer *ppacket)
 Sends a packet to all client sockets connected to the server. More...

virtual void removeSocket (ServerSocket *psocket)
 Removes a socket from the server. More...

unsigned32 getTicks ()
 System timer ticks. More...

bool isThreaded ()
 Check if server is in single or multi-threaded mode. More...


Static Public Methods

bool canBind (SockAddr &saBind)
 Checks if we are able to bind. good for when you are about to start the server. More...


Protected Methods

virtual void processSingleMsg (PacketMessage *pmsg)=0
 Override this to process packets that come in from clients. More...

virtual void idle (unsigned32 nTimer=0)
 Override to have a timer in your server. More...

threadReturn ThreadHandlerProc (void)
void processMessages ()
bool processSockets (int iReady)
void processSelectError ()
void acceptConnection ()
int getMaxFD ()
long getSleepTime ()
void addMsg (PacketMessage *pmsg)
void queClosedMessage (ServerSocket *psocketRemoving)

Protected Attributes

SocketInstance m_sListen
SockAddr m_saServer
LinkedList< ServerSocketm_listClients
PacketMessageQue m_que
unsigned32 m_nIdleFrequency
unsigned32 m_nMaxCon
bool m_bUsingThread
bool m_bPause
unsigned32 m_nSleepTime
timeval m_tvServerStarted
fd_set m_rset
fd_set m_wset

Detailed Description

Simple Server object used for creating a full fledged server.

Overview
Simple server is a class that you dirive from to create a fully functional server. The simple server class handles creating a listen socket, reading full packets from a client connection, and idling the server.

You only need to override processSingleMsg() in order to process packets that come from a client socket. idle() is overridden if you want to have an idle task.

The two ways of constructing a simple server are for a single-threaded server, and a multi-threaded server.

User overridables
namespace ssobjects processSingleMsg()
idle()

Components
o Message Pump
o Idler

Message Pump
The message pump is the way the server talks to your code. When data comes into the server, it is first parsed into packets, and a PacketMessage is created that references the packet and the socket that it was sent from. It is then posted to the message que. Once there, processSingleMsg is called for every packet that was parsed from the incoming data.

This is where your code comes into play. You check what the packet command was, then extract the data from the packet if appropreate, perform some kind of operation, and perhaps send a reply back. This is the process of processing a clients request.

Care should be taken to make sure that when processSingleMsg is called, your operations don't take very long. In a single threaded environment, all other packets - and there-for all the clients - will waiting for you to process thier requests.

Idler
Idling is the process of repeating tasks at a regular interval, like having a main loop, or more accuratly, like using a WM_TIMER message in Windows. The frequency is controlled by the m_nFrequency attribute.

Override idle() method if you want to do things on a regular basis without waiting for a packet from a client. This is prefered over putting the server into a busy loop. If the server is in a busy loop, it will not process additional packets in a single-threaded environment. You can set how often this is called via the frequency attribute.

Threading
It is possible to write the server in such a way that it will operate as a single-threaded server or a multi-threaded server, and this decision can be made at run time. It simply requires a little for-planning, and knowing where to put shared data.

The reason you would want to have a server capable of running as a single or threaded server is for debugging purposes under Linux. Single threading is easier to debug. Multi-threaded can give better performance, and is the best way to handle lengthy operations.

Threading requires the use of the SimpleManager object. It's a little tricky to setup.

Note:
When running multi-threaded, any shared data in your dirived classes should be in the SimpleManager and passed into the simple server. If you idle in the manager, you should idle the same way in the server. The simple server however should check if it is running multi threaded, and only idle shared data if it is running single threaded.


Member Enumeration Documentation

anonymous enum
 

Enumeration values:
MIN_FREQ  Used internally when calculating how much time has been spent waiting for data.


Constructor & Destructor Documentation

SimpleServer::SimpleServer const SockAddr   saBind,
const unsigned32    nFreq = 1000,
const unsigned32    nMaxCon = 100
 

Single-threaded constructor.

This constructs the server object to run as a single threaded server.

[Win32] WSAStartup is called at this point. You should construct the server before calling canBind method.

Parameters:
saBind  Port and protocal address information you want to bind to. See SimpleServer::canBind for more details on using saBind.
nFreq  How often idle method will be called in milli-seconds.
nMaxCon  Reserved for future expansion.
Exceptions:
SimpleServerException  If nFreq is out of range.
GeneralException  [Win32] If WSAStartup call failes.
Todo:
Test passing in the protocol address.

SimpleServer::SimpleServer ServerSocket *const    psocket,
const unsigned32    nFreq
 

Multi-threaded constructor.

Creating a simple server as a handler for a socket. This constructor is used in the simple manager. The socket is already attached. This instance of a simple server is meant to be run multi-threaded.

Parameters:
psocket  Client socket that is connected.
nFreq  idle frequency. (See note below.)
\Todo Finish explaining how threading and idling is accomplished.

SimpleServer::~SimpleServer   [virtual]
 

Destroys the server object, closes the listening socket, removes all msg's in the message que, removes all client socket connects and closes them.

[Win32] Calls WSACleanup()


Member Function Documentation

threadReturn SimpleServer::ThreadHandlerProc void    [protected, virtual]
 

Reimplemented from ssobjects::ThreadHandler.

void SimpleServer::acceptConnection   [protected]
 

void ssobjects::SimpleServer::addMsg PacketMessage   pmsg [inline, protected]
 

bool SimpleServer::canBind SockAddr   saBind [static]
 

Checks if we are able to bind. good for when you are about to start the server.

Creates a listen socket and tries binding it using the port information passed in. Once the connection has been bound, the connection is put into listen mode, and is then closed. Good for when you want to start the server in single threaded mode, but need to make sure that you were able to bind.

When using the protocol address in saBind, this will bind this server to a specific IP address. Useful when the machine this server is running on has more then one IP address assigned to it. See the manpage on bind for more details.

Parameters:
saBind  Port and protocol address information you want to bind to.

int SimpleServer::getMaxFD   [protected]
 

long SimpleServer::getSleepTime   [protected]
 

unsigned32 SimpleServer::getTicks  
 

System timer ticks.

Returns:
(windows) number of ticks since windows started. (linux) number of ticks since server app started

virtual void ssobjects::SimpleServer::idle unsigned32    nTimer = 0 [inline, protected, virtual]
 

Override to have a timer in your server.

bool ssobjects::SimpleServer::isThreaded   [inline]
 

Check if server is in single or multi-threaded mode.

void SimpleServer::killServer   [virtual]
 

Stops server, and closes all connections.

void SimpleServer::pauseIncomingConnections   [virtual]
 

(Not currently in use.) Server will no longer accept connections.

void SimpleServer::processMessages   [protected]
 

void SimpleServer::processSelectError   [protected]
 

virtual void ssobjects::SimpleServer::processSingleMsg PacketMessage   pmsg [protected, pure virtual]
 

Override this to process packets that come in from clients.

The server will call this method when there was enough data to have parsed it into a packet and needs to have the packet processed. A PacketMessage object is created to contain both the packet and client socket that send the packet. You will typically send your reply to this socket. In certain circumstances you will send the reply to all client connections such as in the case of a chat message.

When you override this method, your function will typically look something like:

        ...
        void
        YourServer::processSingleMsg(PacketMessage* pmsg)
        {
          ServerSocket* psocket = (ServerSocket*)pmsg->socket();
          PacketBuffer* ppacket = pmsg->packet();
          switch(ppacket->getCmd())
          {
            //One way to handle the message. Process and reply within the switch.
            case PacketBuffer::pcPing:
              //do something importaint
              sendPacket(psocket,PacketBuffer(PacketBuffer::pcPong)); //send a reply pong
              break;

            //The prefered way to handle the message. Keeps the switch clean.
            case PacketBuffer::pcGetVersion: onGetVersion(pmsg); break;
          }
          DELETE_NULL(ppacket);   //IMPORTANT! The packet is no longer needed. You must delete it.
        }
        ...
        void
        YourServer::onGetVersion(PacketMessage* pmsg)
        {
          ServerSocket* psocket = (ServerSocket*)pmsg->socket();
          PacketBuffer version(PacketBuffer::pcVersion);  //create the reply packet
          version << "Version: 1.0";              //insert the version information into the packet
          sendPacket(psocket,version);            //send the packet to the client socket
        }
        ...
        

For more information see the Message Pump section in the Detailed Description section.

Parameters:
pmsg  Pointer to the message object that contains the packet and cilent socket that sent the packet.

bool SimpleServer::processSockets int    iReady [protected]
 

void SimpleServer::queClosedMessage ServerSocket   s [protected]
 

Creates and posts a PacketBuffer::pcClosed message to the server message que. The message contains the socket handle, and the ip address in dotted decimal format. The socket you pass in is the socket that you are removing. The socket should still be valid (not yet deleted) when this method is called.

Parameters:
s  Pointer to the socket that is being removed.

void SimpleServer::removeSocket ServerSocket   psocketRemoving [virtual]
 

Removes a socket from the server.

Removes this socket from our client list, deletes the object, and posts a message to say that this guy is gone. Once this function returns, the socket passed in can no longer be used. Undefined behavior will occur If you attempt to use the socket after a call to this function.

You will receive a pcClosed message in a call to processSingleMsg. Included in the message is the socket number, and dotted decimal IP address that was attached to the socket. You should no longer use the socket number, or the socket object.

Typically, you store the socket number in a list somewhere so when a socket is closed, you will be able to find it and remove it from your user data.

Parameters:
psocketRemoving  Pointer to the socket object that should be removed.

void SimpleServer::send2All const PacketBuffer   ppacket [virtual]
 

Sends a packet to all client sockets connected to the server.

Use this when you want to send a packet to all client connections.

Parameters:
ppacket  Pointer to the packet you want to send. You are responsible for deleting the packet when you are finished with it.
Exceptions:
SocketInstanceException  if the send operation had an error.

void SimpleServer::send2All const PacketBuffer   packet [virtual]
 

Sends a packet to all client sockets connected to the server.

Use this when you want to send a packet to all client connections.

Parameters:
packet  Packet you wish to send.
Exceptions:
SocketInstanceException  if the send operation had an error.

void SimpleServer::sendPacket ServerSocket   s,
const PacketBuffer   ppacket
[virtual]
 

Sends a packet over a socket.

Parameters:
s  Socket you are sending this packet to.
ppacket  Packet containing the data you are sending.
Exceptions:
SocketInstanceException  if the send operation had an error.

void SimpleServer::sendPacket ServerSocket   s,
const PacketBuffer   packet
[virtual]
 

Sends a packet over a socket.

Parameters:
s  Socket you are sending this packet to.
packet  Packet containing the data you are sending.
Exceptions:
SocketInstanceException  if the send operation had an error.

void SimpleServer::startServer   [virtual]
 

Starts up the server, makes ready for connections.

Creates the listen socket, binds to the address passed in at construction, and puts the listen socket into listen mode.

This method does not return until the server has stopped. The message pump and idler are your only access points after this call. You would typically do any setup you need to do before this is called. Once this returns, the server object can be destroyed.


Member Data Documentation

bool ssobjects::SimpleServer::m_bPause [protected]
 

bool ssobjects::SimpleServer::m_bUsingThread [protected]
 

LinkedList<ServerSocket> ssobjects::SimpleServer::m_listClients [protected]
 

unsigned32 ssobjects::SimpleServer::m_nIdleFrequency [protected]
 

unsigned32 ssobjects::SimpleServer::m_nMaxCon [protected]
 

unsigned32 ssobjects::SimpleServer::m_nSleepTime [protected]
 

PacketMessageQue ssobjects::SimpleServer::m_que [protected]
 

fd_set ssobjects::SimpleServer::m_rset [protected]
 

SocketInstance ssobjects::SimpleServer::m_sListen [protected]
 

SockAddr ssobjects::SimpleServer::m_saServer [protected]
 

struct timeval ssobjects::SimpleServer::m_tvServerStarted [protected]
 

fd_set ssobjects::SimpleServer::m_wset [protected]
 


The documentation for this class was generated from the following files:
Generated on Thu Nov 8 12:39:29 2001 for SimpleServerObjects by doxygen1.2.11 written by Dimitri van Heesch, © 1997-2001