This the c++ version of simple oo server client python code.
i know, code is not comment friendly and not fully tested, but may be still useful.
TCPClient.h
#ifndef _TCPCLIENT_H_
#define _TCPCLIENT_H_
#include "QueuedConnectionManager.h"
#include "QueuedConnectionListener.h"
#include "Datagram.h"
#include "DatagramIterator.h"
#include "genericAsyncTask.h"
#include "asyncTaskManager.h"
#include <list>
class clTCPClient
{
private:
std::string sHost;
int iPort;
int iTimeout;
int iFlags;
QueuedConnectionManager *pcManager;
QueuedConnectionListener *pcListener;
QueuedConnectionReader *pcReader;
ConnectionWriter *pcWriter;
PT(Connection) pConnection;
bool bConnected;
public:
clTCPClient(int flags = 0)
{
iFlags = flags;
pcManager = new QueuedConnectionManager();
pcListener = new QueuedConnectionListener(pcManager, 0);
pcReader = new QueuedConnectionReader(pcManager, 0);
pcWriter = new ConnectionWriter(pcManager,0);
bConnected = false;
};
~clTCPClient()
{
//if (pcManager)
// delete pcManager;
//...
};
void fConnect (std::string hostname, int port, int timeout)
{
pConnection = pcManager->open_TCP_client_connection(hostname, port, timeout);
if (pConnection)
{
pcReader->add_connection(pConnection);
bConnected = true;
}
};
bool fIsConnected (void)
{
return bConnected;
};
void fSendData (char* data, int size)
{
Datagram myDatagram;
//myDatagram.clear();
myDatagram.append_data(data,size);
pcWriter->send(myDatagram, pConnection);
};
bool fGetData (std::list<NetDatagram>* plist)
{
bool ret = false;
while (pcReader->data_available())
{
NetDatagram datagram; // catch the incoming data in this instance
// Check the return value; if we were threaded, someone else could have
// snagged this data before we did
if (pcReader->get_data(datagram))
{
plist->push_back(datagram);
ret = true;
}
}
return ret;
};
private:
void fStartPolling (void)
{
PT(AsyncTaskManager) taskMgr = AsyncTaskManager::get_global_ptr();
PT(GenericAsyncTask) dtask = new GenericAsyncTask("serverDisconnectTask", &fTaskDisconnectPoll, (void*)this);
dtask->set_sort(-39);
taskMgr->add(dtask);
};
static AsyncTask::DoneStatus fTaskDisconnectPoll (GenericAsyncTask* task, void* data)
{
while(((clTCPClient*)data)->pcManager->reset_connection_available() == true)
{
PT(Connection) connPointer;
((clTCPClient*)data)->pcManager->get_reset_connection(connPointer);
Connection* connection = connPointer.p();
// Remove the connection we just found to be "reset" or "disconnected"
((clTCPClient*)data)->pcReader->remove_connection(connection);
((clTCPClient*)data)->bConnected = false;
}
// Tell the task manager to continue this task the next frame.
return AsyncTask::DS_cont;
};
};
#endif
TCPServer.h
#ifndef _TCPSERVER_H_
#define _TCPSERVER_H_
#include "QueuedConnectionManager.h"
#include "QueuedConnectionListener.h"
#include "Datagram.h"
#include "DatagramIterator.h"
#include "genericAsyncTask.h"
#include "asyncTaskManager.h"
#include <list>
class clTCPServer
{
public:
QueuedConnectionManager *pcManager;
QueuedConnectionListener *pcListener;
QueuedConnectionReader *pcReader;
ConnectionWriter *pcWriter;
list<PT(Connection)> lActiveConnections;
private:
int iPort;
int iBackLog;
int iFlags;
public:
clTCPServer(int flags = 0)
{
iPort = 0;
iBackLog = 0;
iFlags = flags;
pcManager = new QueuedConnectionManager();
pcListener = new QueuedConnectionListener(pcManager, 0);
pcReader = new QueuedConnectionReader(pcManager, 0);
pcWriter = new ConnectionWriter(pcManager,0);
lActiveConnections.clear(); // We'll want to keep track of these later
};
~clTCPServer()
{
//if (pcManager)
// delete pcManager;
//...
};
void fConnect (int port, int backlog = 1000)
{
PT(Connection) tcpSocket = pcManager->open_TCP_server_rendezvous(port, backlog);
pcListener->add_connection(tcpSocket);
fStartPolling();
};
void fBroadcastData (char* data, int size)
{
// Broadcast data out to all activeConnections
list<PT(Connection)>::iterator it;
for (it = lActiveConnections.begin(); it != lActiveConnections.end(); it++)
fSendData(data, size, *it);
};
void fSendData (char* data, int size, Connection* pconn)
{
Datagram myDatagram;
myDatagram.append_data(data,size);
pcWriter->send(myDatagram,pconn);
};
bool fGetData (std::list<NetDatagram> *plist)
{
bool ret = false;
while (pcReader->data_available())
{
NetDatagram datagram; // catch the incoming data in this instance
// Check the return value; if we were threaded, someone else could have
// snagged this data before we did
if (pcReader->get_data(datagram))
{
plist->push_back(datagram);
ret = true;
}
}
return ret;
};
std::list<PT(Connection)>* fGetClients (void)
{
return &lActiveConnections;
};
private:
void fStartPolling (void)
{
PT(AsyncTaskManager) taskMgr = AsyncTaskManager::get_global_ptr();
PT(GenericAsyncTask) ltask = new GenericAsyncTask("serverListenTask", &fTaskListenerPoll, (void*)this);
ltask->set_sort(-40);
taskMgr->add(ltask);
PT(GenericAsyncTask) dtask = new GenericAsyncTask("serverDisconnectTask", &fTaskDisconnectPoll, (void*)this);
dtask->set_sort(-39);
taskMgr->add(dtask);
};
static AsyncTask::DoneStatus fTaskListenerPoll (GenericAsyncTask* task, void* data)
{
if (((clTCPServer*)data)->pcListener->new_connection_available())
{
PT(Connection) rendezvous;
NetAddress netAddress;
PT(Connection) newConnection;
if (((clTCPServer*)data)->pcListener->get_new_connection(rendezvous, netAddress, newConnection))
{
newConnection = newConnection.p();
((clTCPServer*)data)->lActiveConnections.push_back(newConnection); // Remember connection
((clTCPServer*)data)->pcReader->add_connection(newConnection); // Begin reading connection
}
}
// Tell the task manager to continue this task the next frame.
return AsyncTask::DS_cont;
};
static AsyncTask::DoneStatus fTaskDisconnectPoll(GenericAsyncTask* task, void* data)
{
while(((clTCPServer*)data)->pcManager->reset_connection_available() == true)
{
PT(Connection) connPointer;
((clTCPServer*)data)->pcManager->get_reset_connection(connPointer);
Connection* connection = connPointer.p();
// Remove the connection we just found to be "reset" or "disconnected"
((clTCPServer*)data)->pcReader->remove_connection(connection);
// Loop through the activeConnections till we find the connection we just deleted
// and remove it from our activeConnections list
list<PT(Connection)>::iterator it;
for (it = ((clTCPServer*)data)->lActiveConnections.begin(); it != ((clTCPServer*)data)->lActiveConnections.end(); it++)
{
if (*it == connection)
{
((clTCPServer*)data)->lActiveConnections.erase(it);
break;
}
}
}
// Tell the task manager to continue this task the next frame.
return AsyncTask::DS_cont;
};
};
#endif
PS: the flag parameter while creating client and server is for future use. It can be used to enable compression, encryption etc…