Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   Related Pages  

RemoteServer.h

00001 /*
00002  * Copyright 2003 Michael A. Marsh, Cornell University. All rights reserved.
00003  * This software is released under the modified BSD license.
00004  * See the file LICENSE in the top-level directory for details.
00005  */
00006 //
00007 // $Id: RemoteServer.h,v 1.3 2004/05/19 15:56:56 mmarsh Exp $
00008 //
00009 // $Log: RemoteServer.h,v $
00010 // Revision 1.3  2004/05/19 15:56:56  mmarsh
00011 // *** empty log message ***
00012 //
00013 // Revision 1.2  2003/11/04 22:17:23  mmarsh
00014 // General code cleanup.
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          //@startgroup
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          //@endgroup
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          // We may want to store a socket instead of address and port.
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    //--------- Exceptions ---------//
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 /* __CODEX_QUORUM_REMOTESERVER_H__ */

Generated on Wed Jun 2 16:32:55 2004 for COrnell Data EXchange (CODEX) by doxygen1.2.18