Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

RemoteServer.cc

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.cc,v 1.3 2004/05/19 15:56:56 mmarsh Exp $
00008 //
00009 // $Log: RemoteServer.cc,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 #include "RemoteServer.h"
00019 #include "SocketBuilder.h"
00020 #include "Socket.h"
00021 
00022 #include <iostream>
00023 #include <netdb.h>
00024 #include <arpa/inet.h>
00025 
00026 using namespace CODEX_Quorum;
00027 
00028 RemoteServer::RemoteServer( struct timeval* timeout,
00029                             string address,
00030                             int port,
00031                             const SocketBuilder& socketBuilder,
00032                             SocketBase* socket ) :
00033    m_timeout(timeout),
00034    m_socketBuilder(socketBuilder),
00035    m_socket(socket),
00036    m_sockaddr(0)
00037 {
00038    m_address = address;
00039    m_port = port;
00040 }
00041 
00042 RemoteServer::~RemoteServer()
00043 {
00044    if ( 0 != m_sockaddr )
00045       delete m_sockaddr;
00046    if ( 0 != m_socket )
00047       delete m_socket;
00048 }
00049 
00050 const struct sockaddr_in*
00051 RemoteServer::sockaddr_in() const
00052 {
00053    if ( 0 == m_sockaddr )
00054    {
00055       struct hostent* p_host = gethostbyname( name().c_str() );
00056       if ( 0 == p_host )
00057          throw QSERemoteServerGethostbynameFailed( __FILE__ ,
00058                                                    __LINE__ ,
00059                                                    this );
00060       struct in_addr* p_in_addr = (struct in_addr*) (p_host->h_addr_list[0]);
00061       m_sockaddr = new struct sockaddr_in;
00062       m_sockaddr->sin_family = AF_INET;
00063       m_sockaddr->sin_port = htons( m_port );
00064       //inet_aton(inet_ntoa(*p_in_addr),m_sockaddr->sin_addr.s_addr);
00065       m_sockaddr->sin_addr.s_addr = p_in_addr->s_addr;
00066       //m_sockaddr->sin_addr.s_addr = inet_addr(inet_ntoa(*p_in_addr));
00067    }
00068    return m_sockaddr;
00069 }
00070 
00071 const struct sockaddr*
00072 RemoteServer::sockaddr() const
00073 {
00074    return (const struct sockaddr*)sockaddr_in();
00075 }
00076 
00077 socklen_t
00078 RemoteServer::addrlen() const
00079 {
00080    return (sizeof(*sockaddr_in()));
00081 }
00082 
00083 string
00084 RemoteServer::name() const
00085 {
00086    return m_address;
00087 }
00088 
00089 int
00090 RemoteServer::port() const
00091 {
00092    return m_port;
00093 }
00094 
00095 int
00096 RemoteServer::set_fd( fd_set* fd_bitmap, SocketBase::StateType s ) const
00097 {
00098    SocketBase*  pSocket = socket();
00099    return pSocket->set_fd( fd_bitmap, s );
00100 }
00101 
00102 bool
00103 RemoteServer::isset_fd( const fd_set* fd_bitmap, SocketBase::StateType s )
00104    const
00105 {
00106    SocketBase*  pSocket = socket();
00107    return pSocket->isset_fd( fd_bitmap, s );
00108 }
00109 
00110 void
00111 RemoteServer::flushSocket() const
00112 {
00113    socket()->flush();
00114 }
00115 
00117 void
00118 RemoteServer::contact( const Message& msg ,
00119                        Response& response ,
00120                        RemoteServerReturn& retval )
00121 {
00122    sendTo(msg,retval);
00123    if ( RemoteServerReturn::kTimeout == retval.errorCode() ) return;
00124    retval.reset();
00125    // This is a blocking read until the connection terminates.
00126    // In general, this is NOT what is desired.
00127    while ( retval.returnCode() != RemoteServerReturn::kSuccess )
00128    {
00129       receiveFrom(response,retval);
00130       if ( RemoteServerReturn::kTimeout == retval.errorCode() ) return;
00131    }
00132 }
00133 
00134 void
00135 RemoteServer::sendTo( const Message& msg ,
00136                       RemoteServerReturn& retval ) const
00137 {
00138    SocketBase*  pSocket = socket();
00139    pSocket->writeTo( msg );
00140    retval.setReturnCode( RemoteServerReturn::kSuccess );
00141 }
00142 
00143 size_t
00144 RemoteServer::receiveFrom( Response& response ,
00145                            RemoteServerReturn& retval ,
00146                            size_t length )
00147 {
00148    const SocketBase*  pSocket = socket();
00149    size_t to_read = 0;
00150    try
00151    {
00152       to_read = pSocket->readAll( response, length );
00153    }
00154    catch ( QSESocketBaseSocketClosed& e )
00155    {
00156       retval.setReturnCode( RemoteServerReturn::kSuccess );
00157       closeSocket();
00158    }
00159    updateTime(retval);
00160    if ( ! checkTimeout(retval) )
00161    {
00162       retval.setErrorCode(RemoteServerReturn::kTimeout);
00163    }
00164    return to_read;
00165 }
00166 
00167 bool
00168 RemoteServer::checkTimeout( const RemoteServerReturn& retval ) const
00169 {
00170    if ( 0 == m_timeout )
00171    {
00172       return true;
00173    }
00174 
00175    struct timeval elapsed = retval.elapsed();
00176    if ( elapsed.tv_sec > m_timeout->tv_sec ) return false;
00177    if ( elapsed.tv_sec < m_timeout->tv_sec ) return true;
00178    if ( elapsed.tv_usec >= m_timeout->tv_usec ) return false;
00179    return true;
00180 }
00181 
00182 void
00183 RemoteServer::updateTime( RemoteServerReturn& retval ) const
00184 {
00185    struct timeval currentTime;
00186    gettimeofday( &currentTime, 0 );
00187    retval.updateTime(currentTime);
00188 }
00189 
00190 SocketBase*
00191 RemoteServer::socket() const
00192 {
00193    if ( 0 == m_socket )
00194    {
00195       m_socket = m_socketBuilder();
00196       m_socket->connect( *this );
00197    }
00198    return m_socket;
00199 }
00200 
00201 void
00202 RemoteServer::closeSocket()
00203 {
00204    if ( 0 != m_socket )
00205    {
00206       delete m_socket;
00207       m_socket = 0;
00208    }
00209 }
00210 
00211 
00212 bool
00213 AsynchronousRemoteServer::checkTimeout(
00214    const RemoteServerReturn& retval ) const
00215 {
00216    return true;
00217 }
00218 
00219 void
00220 AsynchronousRemoteServer::updateTime( RemoteServerReturn& retval ) const
00221 {
00222    return;
00223 }
00224 
00225 
00226 //--------- Exceptions ---------//
00227 
00228 void
00229 QSERemoteServer::derivedMsg() const
00230 {
00231    cerr << "RemoteServer -- ";
00232    errMsg();
00233 }
00234 
00235 void
00236 QSERemoteServerGethostbynameFailed::errMsg() const
00237 {
00238    cerr << "gethostbyname( " << server()->name() << " ) failed";
00239 }

Generated on Fri May 6 17:41:02 2005 for COrnell Data EXchange (CODEX) by  doxygen 1.4.1