www.pudn.com > acdx.rar > SocketHandler.h


#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 
 
 
//##ModelId=424BB6420046 
class SocketHandler : 
	public Thread, 
	public SocketNotify 
{ 
	//##ModelId=424BB6420049 
	bool				_ownSocket;			// shows if delete socket on cleanup 
	//##ModelId=424BB6420056 
	Socket *			_socket;			// ptr to socket associated w/handler 
	//##ModelId=424BB6420066 
	SocketNotify *		_subscriber;		// subscriber to socket events 
	//##ModelId=424BB6420075 
	unsigned long		_fdEventMask;			// shows which events to fire 
 
public: 
 
	//##ModelId=424BB6420076 
	SocketHandler () : 
		Thread(), 
		SocketNotify(), 
 
		_ownSocket(false), 
		_socket(NULL), 
		_subscriber( (SocketNotify *) this ), 
		_fdEventMask(idFdAll) 
 
	{ 
		// create the socket 
		createSocket(); 
	} 
 
	//##ModelId=424BB6420077 
	SocketHandler ( SocketNotify & subscriber ) : 
		Thread(), 
		SocketNotify(), 
 
		_ownSocket(false), 
		_socket(NULL), 
		_subscriber( &subscriber ), 
		_fdEventMask(idFdAll) 
 
	{ 
		// create the socket 
		createSocket(); 
	} 
 
 
	//##ModelId=424BB6420085 
	SocketHandler ( Socket & sock ) : 
 
		Thread(), 
		SocketNotify(), 
 
		_ownSocket(false), 
		_socket( &sock ), 
		_subscriber( (SocketNotify *) this ), 
		_fdEventMask(idFdAll) 
 
	{} 
 
	//##ModelId=424BB6420087 
	SocketHandler ( Socket & sock, SocketNotify & subscriber ) : 
 
		Thread(), 
		SocketNotify(), 
 
		_ownSocket(false), 
		_socket(&sock), 
		_subscriber(&subscriber), 
		_fdEventMask(idFdAll) 
 
	{} 
 
 
	//##ModelId=424BB6420095 
	virtual ~SocketHandler () 
	{ 
		release(); 
	} 
 
	// create/release 
	//##ModelId=424BB6420097 
	bool create () 
	{ 
		if ( !Thread::create() ) 
			return false; 
 
		return true; 
	} 
 
	//##ModelId=424BB64200A4 
	void release () 
	{ 
		Thread::release(); 
 
		if ( _ownSocket && _socket ) 
			delete _socket; 
 
		_socket = 0; 
	} 
 
	// socket methods 
	//##ModelId=424BB64200A5 
	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; 
	} 
 
	//##ModelId=424BB64200A6 
	Socket & getSocket () 
	{ 
		return *_socket; 
	} 
 
	//##ModelId=424BB64200A7 
	void setSocket ( Socket & socket ) 
	{ 
		_socket = &socket; 
	} 
 
	//##ModelId=424BB64200B4 
	bool isValid () 
	{  
		if ( _socket ) 
			return true; 
		else 
			return false; 
	} 
 
	//##ModelId=424BB64200B5 
	bool isConnected () 
	{ 
		if ( _socket->isValid() ) 
			return true; 
		else 
			return false; 
	} 
 
 
 
	// subscriber methods 
 
	//##ModelId=424BB64200B6 
	long getFdEvents () 
	{ 
		return _fdEventMask; 
	} 
 
	//##ModelId=424BB64200C3 
	void asyncSelet ( long set ) 
	{ 
		_fdEventMask = set; 
	} 
 
 
	//##ModelId=424BB64200C5 
	SocketNotify & getSubscriber () 
	{ 
		return *_subscriber; 
	} 
 
	//##ModelId=424BB64200D2 
	void setSubscriber ( SocketNotify & subscriber ) 
	{ 
		_subscriber = &subscriber; 
	} 
 
	// handle socket processing 
	//##ModelId=424BB64200D4 
	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); 
 
						Sleep(100);//  [4/5/2005] this can set cpu not under 100%  by leon change it. 
					} 
				} 
				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 
	//##ModelId=424BB64200E2 
	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 
 
 
//##ModelId=424BB64200F2 
class CreateSocketHandler 
{ 
	//##ModelId=424BB64200F3 
	long	i; 
public: 
 
	//##ModelId=424BB6420101 
	CreateSocketHandler ()  
	{ 
		i = -1; 
	} 
 
	//##ModelId=424BB6420102 
	virtual ~CreateSocketHandler () 
	{} 
 
	// create/release 
	//##ModelId=424BB6420104 
	virtual bool create () 
	{ 
		return true; 
	} 
 
	//##ModelId=424BB6420106 
	virtual void release () 
	{} 
 
	// responsible for create a connection 
	//##ModelId=424BB6420112 
	virtual  
	SocketHandler * createHandler () = 0; 
 
}; 
 
 
 
 
#endif