275 lines
5.7 KiB
C++
Executable File
275 lines
5.7 KiB
C++
Executable File
#if !defined (_SIMPLE_SERVER_HANDLER_H_)
|
|
#define _SIMPLE_SERVER_HANDLER_H_
|
|
|
|
#include "cdevEventHandler.h"
|
|
#include "cdevAddr.h"
|
|
#include "cdevSocketConnector.h"
|
|
#include "cdevReactor.h"
|
|
#include "ErrorReporter.h"
|
|
#include "SocketUtil.h"
|
|
#include "fifo.h"
|
|
#include "clipMagicNumber.h"
|
|
#include "cdevMessageBinary.h"
|
|
#include "cdevMessage.h"
|
|
#include "ClientInfo.h"
|
|
|
|
|
|
const int _CDEV_CONNECTION_RETRIES = 5;
|
|
const int MAX_SERVERS = 1024;
|
|
extern FifoQueue results [MAX_SERVERS];
|
|
extern int completionCodes[MAX_SERVERS];
|
|
|
|
class DumpAllHandler : public cdevEventHandler,
|
|
public SocketReader,
|
|
public SocketWriter
|
|
{
|
|
protected:
|
|
char hostName [MAXHOSTNAMELEN + 1];
|
|
FifoQueue queue;
|
|
cdevSocketConnector stream;
|
|
int serverQuitFlag;
|
|
cdevReactor & Reactor;
|
|
int index;
|
|
ClientInfo info;
|
|
|
|
public:
|
|
DumpAllHandler (char * Host, unsigned short Port, cdevReactor & LocalReactor, int Index)
|
|
: info(),
|
|
SocketReader(CLIP_MAGIC_NUMBER),
|
|
SocketWriter(CLIP_MAGIC_NUMBER),
|
|
index(Index),
|
|
Reactor(LocalReactor),
|
|
serverQuitFlag(0)
|
|
{
|
|
cdevInetAddr addr;
|
|
hostName[0] = 0;
|
|
addr.set (Port, Host);
|
|
if(open(addr)!=0)
|
|
{
|
|
outputError(CDEV_SEVERITY_ERROR,
|
|
"DumpAllHandler::connect",
|
|
"Failed to connect to %s on port %i",
|
|
Host,
|
|
Port);
|
|
completionCodes[index]=-1;
|
|
}
|
|
|
|
completionCodes[index] = 0;
|
|
|
|
cdevData tagMap;
|
|
int * tags;
|
|
char ** ctags;
|
|
int ntags;
|
|
char * binary = NULL;
|
|
size_t binaryLen = 0;
|
|
|
|
cdevData::readTagTable(tags, ctags, ntags);
|
|
tagMap.insert(1, tags, ntags);
|
|
tagMap.insert(2, ctags, ntags);
|
|
|
|
delete tags;
|
|
delete ctags;
|
|
|
|
cdevMessageBinary packet0(index, 0, 0, 0, 0, CDEV_SERVER_OP, 0, 0,
|
|
NULL, "set ClientInfo", &info.getClientData(),
|
|
NULL, &tagMap);
|
|
|
|
packet0.streamOut(&binary, &binaryLen);
|
|
packet0.detachData();
|
|
enqueue(binary, binaryLen);
|
|
|
|
cdevMessageBinary packet1(index, 1, 0, 0, 0, CDEV_SERVER_OP, 0, 0,
|
|
NULL, "get ServerInfo", NULL, NULL, &tagMap);
|
|
|
|
packet1.streamOut(&binary, &binaryLen);
|
|
packet1.detachData();
|
|
enqueue(binary, binaryLen);
|
|
|
|
cdevMessageBinary packet2(index, 2, 0, 0, 0, CDEV_SERVER_OP, 0, 0,
|
|
NULL, "get ClientInfo", NULL, NULL, &tagMap);
|
|
packet2.streamOut(&binary, &binaryLen);
|
|
packet2.detachData();
|
|
enqueue(binary, binaryLen);
|
|
}
|
|
|
|
~DumpAllHandler (void)
|
|
{
|
|
if(completionCodes[index]!=1) completionCodes[index]=-1;
|
|
if(stream.getHandle()>0 && serverQuitFlag==0)
|
|
{
|
|
writeGoodbye();
|
|
}
|
|
|
|
if(reactor) reactor->extractHandler(this);
|
|
handleClose();
|
|
}
|
|
|
|
int open (const cdevAddr &addr)
|
|
{
|
|
int result = 0;
|
|
int count = 0;
|
|
|
|
result = stream.connect (addr);
|
|
|
|
if (result != -1)
|
|
{
|
|
if((result = Reactor.registerHandler(this, READ_MASK|WRITE_MASK|EXCEPT_MASK))==-1)
|
|
{
|
|
handleClose();
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
char * getHostName ( void )
|
|
{
|
|
if(*hostName==0)
|
|
{
|
|
cdevInetAddr addr;
|
|
if(stream.getRemoteAddress (addr)==0)
|
|
{
|
|
const char * ptr=addr.getHostName();
|
|
if(ptr) strncpy (hostName, ptr, MAXHOSTNAMELEN+1);
|
|
}
|
|
}
|
|
return hostName;
|
|
}
|
|
|
|
char * getName (void) const
|
|
{
|
|
return "DumpAllHandler";
|
|
}
|
|
|
|
int getHandle (void) const
|
|
{
|
|
return stream.getHandle();
|
|
}
|
|
|
|
void enqueue (char * buf, size_t len)
|
|
{
|
|
queue.enqueue(buf, len);
|
|
setMask(WRITE_MASK|EXCEPT_MASK);
|
|
}
|
|
|
|
void undequeue (char * buf, size_t len)
|
|
{
|
|
queue.undequeue(buf, len);
|
|
}
|
|
|
|
int dequeue (char **buf, size_t *len)
|
|
{
|
|
return queue.dequeue(buf, len);
|
|
}
|
|
|
|
int empty (void)
|
|
{
|
|
return queue.empty();
|
|
}
|
|
|
|
int handleClose (void)
|
|
{
|
|
stream.close();
|
|
return 0;
|
|
}
|
|
|
|
int handleInput (void)
|
|
{
|
|
int retval = 0;
|
|
char * buf = NULL;
|
|
size_t len = 0;
|
|
int result = 1;
|
|
|
|
while(result>0)
|
|
{
|
|
result = read(&buf, (int *)&len);
|
|
|
|
switch(result)
|
|
{
|
|
case SHUTDOWN_CODE:
|
|
outputError(CDEV_SEVERITY_INFO, (char *)getName(),
|
|
"Connection to %s terminated by client", getHostName());
|
|
retval = -1;
|
|
break;
|
|
|
|
case -1:
|
|
outputError(CDEV_SEVERITY_WARN, (char *)getName(),
|
|
"Error reading from connection to client %s", getHostName());
|
|
retval = -1;
|
|
break;
|
|
|
|
case 0:
|
|
break;
|
|
|
|
default:
|
|
{
|
|
cdevMessage *message = new cdevMessage;
|
|
unsigned transIndex = 0;
|
|
unsigned clientID = 0;
|
|
|
|
if(message->streamIn(buf, len)==0 &&
|
|
(clientID=message->getClientID())==index &&
|
|
(transIndex=message->getTransIndex())>0 &&
|
|
transIndex<3)
|
|
{
|
|
results[index].enqueue((void *)message);
|
|
if(transIndex==2) completionCodes[index] = 1;
|
|
}
|
|
else delete message;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
int handleOutput (void)
|
|
{
|
|
int retval = 0;
|
|
char * buf = NULL;
|
|
size_t len = 0;
|
|
|
|
if(!writing() && dequeue(&buf, &len)==0)
|
|
{
|
|
int full = 0;
|
|
while(!full)
|
|
{
|
|
if(!(full = writeEnqueue(buf, len)))
|
|
{
|
|
delete buf;
|
|
full = dequeue(&buf, &len);
|
|
}
|
|
else undequeue(buf, len);
|
|
}
|
|
if(writeContinue()<0) retval = -1;
|
|
}
|
|
else if(writing())
|
|
{
|
|
if(writeContinue()<0) retval = -1;
|
|
}
|
|
|
|
if(retval!=0)
|
|
{
|
|
outputError(CDEV_SEVERITY_WARN, (char *)getName(),
|
|
"Error transmitting to %s", getHostName());
|
|
}
|
|
|
|
if(empty() && !writing())
|
|
{
|
|
setMask(READ_MASK|EXCEPT_MASK);
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
int handleExcept (void)
|
|
{
|
|
stream.close();
|
|
serverQuitFlag=1;
|
|
return -1;
|
|
}
|
|
};
|
|
|
|
|
|
#endif /* _SIMPLE_SERVER_HANDLER_H_ */
|