00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __CODEX_QUORUM_REMOTESERVER_H__
00019 #define __CODEX_QUORUM_REMOTESERVER_H__
00020
00021 #include <sys/time.h>
00022 #include <sys/socket.h>
00023 #include <netinet/in.h>
00024 #include <string>
00025
00026 #include "QSExceptions.h"
00027 #include "Message.h"
00028 #include "Socket.h"
00029
00030 namespace CODEX_Quorum
00031 {
00032 class SocketBase;
00033 class SocketBuilder;
00034
00039 class RemoteServerReturn
00040 {
00041 public :
00042 enum ReturnCode
00043 {
00044 kSuccess,
00045 kFailure,
00046 kNumReturnCodes
00047 };
00048
00049 enum ErrorCode
00050 {
00051 kNone,
00053 kTimeout,
00054 kNumErrorCodes
00055 };
00056
00064 RemoteServerReturn() :
00065 m_ret( kFailure ),
00066 m_err( kNone )
00067 {
00068 if ( gettimeofday( &m_created, 0 ) )
00069 {
00070 m_created.tv_sec = 0;
00071 m_created.tv_usec = 0;
00072 }
00073 m_time.tv_sec = m_created.tv_sec;
00074 m_time.tv_usec = m_created.tv_usec;
00075 }
00076
00078 RemoteServerReturn( const RemoteServerReturn& sr ) :
00079 m_ret( sr.m_ret ),
00080 m_err( sr.m_err )
00081 {
00082 m_created.tv_sec = sr.m_created.tv_sec;
00083 m_created.tv_usec = sr.m_created.tv_usec;
00084
00085 m_time.tv_sec = sr.m_time.tv_sec;
00086 m_time.tv_usec = sr.m_time.tv_usec;
00087 }
00088
00090 ReturnCode returnCode() const { return m_ret; }
00092 ErrorCode errorCode() const { return m_err; }
00093
00099 struct timeval elapsed() const {
00100 struct timeval retval;
00101 retval.tv_sec = m_time.tv_sec - m_created.tv_sec;
00102 retval.tv_usec = m_time.tv_usec - m_created.tv_usec;
00103 if ( retval.tv_usec < 0 )
00104 {
00105 --retval.tv_sec;
00106 retval.tv_usec += 1000000;
00107 }
00108 return retval;
00109 }
00110
00112 void setReturnCode( ReturnCode ret ) { m_ret = ret; }
00114 void setErrorCode( ErrorCode err ) { m_err = err; }
00115
00119 void updateTime( const struct timeval& t ) {
00120 m_time.tv_sec = t.tv_sec;
00121 m_time.tv_usec = t.tv_usec;
00122 }
00123
00132 void reset() {
00133 m_ret = kFailure;
00134 m_err = kNone;
00135 if ( gettimeofday( &m_created, 0 ) )
00136 {
00137 m_created.tv_sec = 0;
00138 m_created.tv_usec = 0;
00139 }
00140 m_time.tv_sec = m_created.tv_sec;
00141 m_time.tv_usec = m_created.tv_usec;
00142 }
00143
00144 private :
00145 ReturnCode m_ret;
00146 ErrorCode m_err;
00147 struct timeval m_created;
00148 struct timeval m_time;
00149 };
00150
00151
00156 class RemoteServer
00157 {
00158 public :
00176 RemoteServer( struct timeval* timeout,
00177 string address,
00178 int port,
00179 const SocketBuilder& socketBuilder,
00180 SocketBase* socket = 0 );
00181
00183 virtual ~RemoteServer();
00184
00186 const struct sockaddr_in* sockaddr_in() const;
00188 const struct sockaddr* sockaddr() const;
00190 socklen_t addrlen() const;
00192 string name() const;
00194 int port() const;
00195
00207 int set_fd( fd_set* fd_bitmap, SocketBase::StateType s ) const;
00208
00223 bool isset_fd( const fd_set* fd_bitmap, SocketBase::StateType s )
00224 const;
00225
00232 void flushSocket() const;
00233
00244
00245
00255 void contact( const Message& msg ,
00256 Response& response ,
00257 RemoteServerReturn& retval );
00258
00294 void sendTo( const Message& msg ,
00295 RemoteServerReturn& retval ) const;
00296
00328 size_t receiveFrom( Response& response ,
00329 RemoteServerReturn& retval ,
00330 size_t length = 0 );
00331
00332
00333
00337 void closeSocket();
00338
00339 protected :
00346 SocketBase* socket() const;
00347
00352 virtual bool checkTimeout( const RemoteServerReturn& retval ) const;
00354 virtual void updateTime( RemoteServerReturn& retval ) const;
00355
00356 private :
00357 struct timeval* m_timeout;
00358
00359 string m_address;
00360 int m_port;
00361 const SocketBuilder& m_socketBuilder;
00362 mutable SocketBase* m_socket;
00363 mutable struct sockaddr_in* m_sockaddr;
00364 };
00365
00373 class AsynchronousRemoteServer : public RemoteServer
00374 {
00375 public :
00381 AsynchronousRemoteServer( string address,
00382 int port,
00383 const SocketBuilder& socketBuilder,
00384 SocketBase* socket = 0) :
00385 RemoteServer(0, address, port, socketBuilder, socket) {}
00386
00388 virtual ~AsynchronousRemoteServer() {}
00389
00390 protected :
00391 bool checkTimeout( const RemoteServerReturn& retval ) const;
00392 void updateTime( RemoteServerReturn& retval ) const;
00393 };
00394
00395
00396
00397
00399 class QSERemoteServer : public QSExceptionBase
00400 {
00401 public :
00403 QSERemoteServer( const string& fname,
00404 int line,
00405 const RemoteServer* server ) :
00406 QSExceptionBase( fname, line ),
00407 m_server( server )
00408 {}
00409
00411 virtual ~QSERemoteServer() {}
00412
00413 protected :
00415 const RemoteServer* server() const { return m_server; }
00416
00417 void derivedMsg() const;
00418
00420 virtual void errMsg() const = 0;
00421
00422 private :
00423 const RemoteServer* m_server;
00424 };
00425
00427 class QSERemoteServerGethostbynameFailed : public QSERemoteServer
00428 {
00429 public :
00431 QSERemoteServerGethostbynameFailed( const string& fname,
00432 int line,
00433 const RemoteServer* server ) :
00434 QSERemoteServer( fname, line, server )
00435 {}
00436
00438 virtual ~QSERemoteServerGethostbynameFailed() {}
00439
00440 protected :
00441 void errMsg() const;
00442 };
00443
00444 }
00445
00446 #endif