|
#if !defined(SocketHandler_H)
#define SocketHandler_H
#include "Socket.h"
#include "SocketNotify.h"
////////////////////////////////////////////////////////////////////////////////
// SocketHandler
//
// Purpose: handles basics of socket. provides for notification of
// socket events. event notification can be either passed in
// or used as is. also provides a socket if one is not
// passed in
class SocketHandler :
public Thread,
public SocketNotify
{
bool _ownSocket; // shows if delete socket on cleanup
Socket * _socket; // ptr to socket associated w/handler
SocketNotify * _subscriber; // subscriber to socket events
unsigned long _fdEventMask; // shows which events to fire
public:
SocketHandler () :
Thread(),
SocketNotify(),
_ownSocket(false),
_socket(NULL),
_subscriber( (SocketNotify *) this ),
_fdEventMask(idFdAll)
{
// create the socket
createSocket();
}
SocketHandler ( SocketNotify & subscriber ) :
Thread(),
SocketNotify(),
_ownSocket(false),
_socket(NULL),
_subscriber( &subscriber ),
_fdEventMask(idFdAll)
{
// create the socket
createSocket();
}
SocketHandler ( Socket & sock ) :
Thread(),
SocketNotify(),
_ownSocket(false),
_socket( &sock ),
_subscriber( (SocketNotify *) this ),
_fdEventMask(idFdAll)
{}
SocketHandler ( Socket & sock, SocketNotify & subscriber ) :
Thread(),
SocketNotify(),
_ownSocket(false),
_socket(&sock),
_subscriber(&subscriber),
_fdEventMask(idFdAll)
{}
virtual ~SocketHandler ()
{
release();
}
// create/release
bool create ()
{
if ( !Thread::create() )
return false;
return true;
}
void release ()
{
Thread::release();
if ( _ownSocket && _socket )
delete _socket;
_socket = 0;
}
// socket methods
bool createSocket ()
{
// create the socket
_socket = new Socket;
// show we own the socket
// if created okay
if ( _socket )
{
_ownSocket = true;
return true;
}
else
return false;
}
Socket & getSocket ()
{
return *_socket;
}
void setSocket ( Socket & socket )
{
_socket = &socket;
}
bool isValid ()
{
if ( _socket )
return true;
else
return false;
}
bool isConnected ()
{
if ( _socket->isValid() )
return true;
else
return false;
}
// subscriber methods
long getFdEvents ()
{
return _fdEventMask;
}
void asyncSelet ( long set )
{
_fdEventMask = set;
}
SocketNotify & getSubscriber ()
{
return *_subscriber;
}
void setSubscriber ( SocketNotify & subscriber )
{
_subscriber = &subscriber;
}
// handle socket processing
virtual
long process ( Socket & sock )
{
// if no socket stop
if ( !isValid() )
return -1;
// The fd sets should be zeroed out before using them to prevent errors.
fd_set readfds, writefds, exceptfds;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&exceptfds);
// read from socket
while ( true )
{
while ( true )
{
// show no error
long error = 0;
// set time to wait
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
// setup to wait for read event
FD_SET(sock,&readfds);
FD_SET(sock,&writefds);
FD_SET(sock,&exceptfds);
int i = select(0,&readfds,&writefds,&exceptfds,&timeout);
if ( i == SOCKET_ERROR )
{
long error = sock.getLastError();
//fprintf(stderr,"select failed %d\n",error);
return -1;
}
if ( FD_ISSET(sock,&readfds) &&
_fdEventMask | (idFdRead | idFdConnect) )
{
// got a recieve so read data
if ( _subscriber )
{
long length = sock.getRecieveSize();
if ( length == 0 )
_subscriber->onConnect(error);
else
_subscriber->onReceive(error);
}
}
else if ( FD_ISSET(sock,&writefds) && _fdEventMask | idFdWrite )
{
// got a recieve so read data
if ( _subscriber )
_subscriber->onSend(error);
}
else if ( FD_ISSET(sock,&exceptfds) && _fdEventMask | idFdClose )
{
// got a recieve so read data
if ( _subscriber )
_subscriber->onClose(error);
}
// test end event
if ( WaitForSingleObject( getEndEvent(), 0 ) != WAIT_TIMEOUT )
return -1;
// do idle processing
idle();
}
}
return 1;
}
// run method implementation
long run ()
{
// if no socket stop
if ( !isValid() )
return -1;
// get socket
Socket & sock = getSocket();
// set socket to non-blocking
if ( !sock.setSocketNonBlocking() )
return 0;
return process(sock);
}
};
////////////////////////////////////////////////////////////////////////////////////
// CreateSocketHandler
//
// Purpose: create socket handler is a class
// used only to create socket handlers or their derived classes.
// you must implement you own
class CreateSocketHandler
{
long i;
public:
CreateSocketHandler ()
{
i = -1;
}
virtual ~CreateSocketHandler ()
{}
// create/release
virtual bool create ()
{
return true;
}
virtual void release ()
{}
// responsible for create a connection
virtual
SocketHandler * createHandler () = 0;
};
#endif
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.
A list of licenses authors might use can be found here
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.