Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

cabal_socket.cpp

00001 /*
00002    CABAL Protocol
00003    Socket class implementation
00004 
00005    $Id: cabal_socket.cpp,v 1.4 2004/03/26 12:03:02 jonnymind Exp $
00006 ---------------------------------------------
00007    Begin      :
00008    Author     : Giancarlo Niccolai
00009 
00010    Last modified because:
00011 
00012 */
00013 
00014 #ifdef __MSC_VER
00015 #pragma warning ( disable : 4786 )
00016 #endif
00017 
00018 #include <cabal_socket.h>
00019 #include <cabal_channel.h>
00020 #include <fcntl.h>
00021 #include <string>
00022 #include <cassert>
00023 
00024 namespace Cabal {
00025 
00026 Socket::Socket( const Socket &orig )
00027    throw( InitError )
00028 {
00029    m_skCom = Net::dup( orig.m_skCom );
00030    if ( ! Net::validSocket( m_skCom ) )
00031       throw InitError( "Can't create a new file descriptor", Net::errorCode() );
00032 
00033    m_timeout = orig.m_timeout;
00034    m_bTout = orig.m_bTout;
00035    m_type = orig.m_type;
00036 
00037    m_remote = orig.m_remote;
00038    m_local = orig.m_local;
00039    
00040    m_channel = 0;
00041    m_recpt = 0;
00042 }
00043 
00044 
00045 bool Socket::bind( const Address &local ) 
00046 {
00047    if ( ! Net::bind( m_skCom, local.address() )  ) 
00048    {
00049       m_osError = Net::errorCode();
00050       return false;
00051    }
00052 
00053    m_osError = 0;
00054    m_local =  local;
00055    return true;
00056 }
00057 
00058 int Socket::selectFor( bool rw )
00059 {
00060    // if this socket is managed, always return as if data was ready.
00061    if ( managed() ) return 1;
00062 
00063    fd_set set;
00064    struct timeval tv;
00065 
00066    FD_ZERO( &set );
00067    FD_SET(m_skCom, &set);
00068    Net::resetError();
00069 
00070    if ( m_timeout == -1 )
00071    {
00072       if ( rw )
00073          select(m_skCom+1, NULL, &set, NULL, NULL);
00074       else
00075          select(m_skCom+1, &set, NULL, NULL, NULL);
00076    }
00077    else
00078    {
00079       tv.tv_sec = m_timeout/ 1000;
00080       tv.tv_usec = (m_timeout % 1000) * 1000;
00081       if ( rw )
00082          select(m_skCom + 1, NULL, &set, NULL, &tv);
00083       else
00084          select(m_skCom + 1, &set, NULL, NULL, &tv);
00085    }
00086 
00087    return FD_ISSET( m_skCom, &set );
00088 }
00089 
00090 
00091 int Socket::recv( void *buffer, const int len )
00092 {
00093    int retlen;
00094    
00095    if( selectFor( false ) ) //read
00096    {
00097       retlen = rawRecv( buffer, len );
00098          
00099       if ( retlen <  0 )
00100          m_osError = Net::errorCode();
00101       else {
00102          m_osError = 0;
00103          // closed.
00104          if ( retlen == 0 ) {
00105             Net::closeSocket( m_skCom );
00106             Net::invalidate( m_skCom );
00107          }
00108       }
00109 
00110       m_bTout = false;
00111       return retlen;
00112    }
00113    else
00114    {
00115       m_osError = 0;
00116       m_bTout = true;
00117       return 0;
00118    }
00119 }
00120 
00121 int Socket::send( const void *buffer, const int len )
00122 {
00123    if ( ! Net::validSocket( m_skCom ) ) return -1;
00124 
00125    int readin;
00126    if( selectFor( true ) ) //write
00127    {
00128       readin = rawSend( buffer, len );
00129       
00130       if ( readin <  0 ) {
00131          if ( Net::errorPipe() ) {
00132             // connection closed
00133             Net::closeSocket( m_skCom );
00134             Net::invalidate( m_skCom );
00135             readin = 0;
00136             m_osError = 0;
00137          }
00138          else
00139             m_osError = Net::errorCode();
00140       }
00141       else
00142          m_osError = 0;
00143       m_bTout = false;
00144       return readin;
00145    }
00146    else
00147    {
00148       m_osError = 0;
00149       m_bTout = true;
00150       return 0;
00151    }
00152 }
00153 
00154 bool Socket::close()
00155 {
00156    m_osError = 0;
00157    if ( m_recpt != 0 )
00158    {
00159       m_recpt->terminate( this );
00160       delete m_recpt;
00161       m_recpt = 0;
00162    }
00163 
00164    if ( ! Net::validSocket( m_skCom ) ) 
00165       return false;
00166    
00167    if (  Net::closeSocket( m_skCom ) == 0 ) {
00168       Net::invalidate( m_skCom );
00169       return true;
00170    }
00171    else {
00172       m_osError = Net::errorCode();
00173       return false;
00174    }
00175 }
00176 
00177 
00178 void Socket::channel( Channel *chn, Reception* rcpt )
00179 { 
00180    if ( m_recpt != 0 )
00181    {
00182       m_recpt->terminate( this );
00183       delete m_recpt;
00184    }
00185    
00186    m_recpt = rcpt;
00187    m_recpt->init( this );
00188    
00189    if ( m_channel ) 
00190       m_channel->removeSocket( this );
00191    
00192    m_channel = chn; 
00193    
00194    if ( m_channel )
00195       m_channel->addSocket( this );
00196 }
00197 
00198 } //namespace

Generated on Sat Apr 10 17:41:48 2004 for Cabal by doxygen 1.3.5