00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __CODEX_QUORUM_REMOTESERVER_H__
00022 #define __CODEX_QUORUM_REMOTESERVER_H__
00023
00024 #include <sys/time.h>
00025 #include <sys/socket.h>
00026 #include <netinet/in.h>
00027 #include <string>
00028
00029 #include "QSExceptions.h"
00030 #include "Message.h"
00031 #include "Socket.h"
00032
00033 namespace CODEX_Quorum
00034 {
00035 class SocketBase;
00036 class SocketBuilder;
00037
00042 class RemoteServerReturn
00043 {
00044 public :
00045 enum ReturnCode
00046 {
00047 kSuccess,
00048 kFailure,
00049 kNumReturnCodes
00050 };
00051
00052 enum ErrorCode
00053 {
00054 kNone,
00056 kTimeout,
00057 kNumErrorCodes
00058 };
00059
00067 RemoteServerReturn() :
00068 m_ret( kFailure ),
00069 m_err( kNone )
00070 {
00071 if ( gettimeofday( &m_created, 0 ) )
00072 {
00073 m_created.tv_sec = 0;
00074 m_created.tv_usec = 0;
00075 }
00076 m_time.tv_sec = m_created.tv_sec;
00077 m_time.tv_usec = m_created.tv_usec;
00078 }
00079
00081 RemoteServerReturn( const RemoteServerReturn& sr ) :
00082 m_ret( sr.m_ret ),
00083 m_err( sr.m_err )
00084 {
00085 m_created.tv_sec = sr.m_created.tv_sec;
00086 m_created.tv_usec = sr.m_created.tv_usec;
00087
00088 m_time.tv_sec = sr.m_time.tv_sec;
00089 m_time.tv_usec = sr.m_time.tv_usec;
00090 }
00091
00093 ReturnCode returnCode() const { return m_ret; }
00095 ErrorCode errorCode() const { return m_err; }
00096
00102 struct timeval elapsed() const {
00103 struct timeval retval;
00104 retval.tv_sec = m_time.tv_sec - m_created.tv_sec;
00105 retval.tv_usec = m_time.tv_usec - m_created.tv_usec;
00106 if ( retval.tv_usec < 0 )
00107 {
00108 --retval.tv_sec;
00109 retval.tv_usec += 1000000;
00110 }
00111 return retval;
00112 }
00113
00115 void setReturnCode( ReturnCode ret ) { m_ret = ret; }
00117 void setErrorCode( ErrorCode err ) { m_err = err; }
00118
00122 void updateTime( const struct timeval& t ) {
00123 m_time.tv_sec = t.tv_sec;
00124 m_time.tv_usec = t.tv_usec;
00125 }
00126
00135 void reset() {
00136 m_ret = kFailure;
00137 m_err = kNone;
00138 if ( gettimeofday( &m_created, 0 ) )
00139 {
00140 m_created.tv_sec = 0;
00141 m_created.tv_usec = 0;
00142 }
00143 m_time.tv_sec = m_created.tv_sec;
00144 m_time.tv_usec = m_created.tv_usec;
00145 }
00146
00147 private :
00148 ReturnCode m_ret;
00149 ErrorCode m_err;
00150 struct timeval m_created;
00151 struct timeval m_time;
00152 };
00153
00154
00159 class RemoteServer
00160 {
00161 public :
00179 RemoteServer( struct timeval* timeout,
00180 string address,
00181 int port,
00182 const SocketBuilder& socketBuilder,
00183 SocketBase* socket = 0 );
00184
00186 virtual ~RemoteServer();
00187
00189 const struct sockaddr_in* sockaddr_in() const;
00191 const struct sockaddr* sockaddr() const;
00193 socklen_t addrlen() const;
00195 string name() const;
00197 int port() const;
00198
00210 int set_fd( fd_set* fd_bitmap, SocketBase::StateType s ) const;
00211
00226 bool isset_fd( const fd_set* fd_bitmap, SocketBase::StateType s )
00227 const;
00228
00235 void flushSocket() const;
00236
00247
00248
00258 void contact( const Message& msg ,
00259 Response& response ,
00260 RemoteServerReturn& retval );
00261
00297 void sendTo( const Message& msg ,
00298 RemoteServerReturn& retval ) const;
00299
00331 size_t receiveFrom( Response& response ,
00332 RemoteServerReturn& retval ,
00333 size_t length = 0 );
00334
00335
00336
00340 void closeSocket();
00341
00342 protected :
00349 SocketBase* socket() const;
00350
00355 virtual bool checkTimeout( const RemoteServerReturn& retval ) const;
00357 virtual void updateTime( RemoteServerReturn& retval ) const;
00358
00359 private :
00360 struct timeval* m_timeout;
00361
00362 string m_address;
00363 int m_port;
00364 const SocketBuilder& m_socketBuilder;
00365 mutable SocketBase* m_socket;
00366 mutable struct sockaddr_in* m_sockaddr;
00367 };
00368
00376 class AsynchronousRemoteServer : public RemoteServer
00377 {
00378 public :
00384 AsynchronousRemoteServer( string address,
00385 int port,
00386 const SocketBuilder& socketBuilder,
00387 SocketBase* socket = 0) :
00388 RemoteServer(0, address, port, socketBuilder, socket) {}
00389
00391 virtual ~AsynchronousRemoteServer() {}
00392
00393 protected :
00394 bool checkTimeout( const RemoteServerReturn& retval ) const;
00395 void updateTime( RemoteServerReturn& retval ) const;
00396 };
00397
00398
00399
00400
00402 class QSERemoteServer : public QSExceptionBase
00403 {
00404 public :
00406 QSERemoteServer( const string& fname,
00407 int line,
00408 const RemoteServer* server ) :
00409 QSExceptionBase( fname, line ),
00410 m_server( server )
00411 {}
00412
00414 virtual ~QSERemoteServer() {}
00415
00416 protected :
00418 const RemoteServer* server() const { return m_server; }
00419
00420 void derivedMsg() const;
00421
00423 virtual void errMsg() const = 0;
00424
00425 private :
00426 const RemoteServer* m_server;
00427 };
00428
00430 class QSERemoteServerGethostbynameFailed : public QSERemoteServer
00431 {
00432 public :
00434 QSERemoteServerGethostbynameFailed( const string& fname,
00435 int line,
00436 const RemoteServer* server ) :
00437 QSERemoteServer( fname, line, server )
00438 {}
00439
00441 virtual ~QSERemoteServerGethostbynameFailed() {}
00442
00443 protected :
00444 void errMsg() const;
00445 };
00446
00447 }
00448
00449 #endif