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

cabal_tcpsocket.cpp

00001 /*
00002    cabal_tcpsocket.cpp
00003    Basic TCP socket object for cabal
00004 
00005    $Id: cabal_tcpsocket.cpp,v 1.2 2004/04/10 15:28:16 jonnymind Exp $
00006 ---------------------------------------------
00007    Begin      : Thu, 11 Mar 2004 03:05:18 +0100
00008    Author     : Giancarlo Niccolai
00009 
00010    Last modified because:
00011 
00012 */
00013 
00014 #include <cabal_tcpsocket.h>
00015 
00016 namespace Cabal {
00017 
00018 bool TCPSocket::connect()
00019 {
00020    
00021    if( ! Net::connect( m_skCom, m_remote.address() ) && ! Net::inProgress() )
00022    {
00023       m_osError = Net::errorCode();
00024       return false;
00025    }
00026 
00027 
00028    if(! selectFor( true ) )  //select for write
00029    {
00030       /* Timed out */
00031       m_osError = 0;
00032       m_opType = OT_CONNECTING;
00033       m_bTout = true;
00034       return false;
00035    }
00036 
00037    //Connection has been completed with a failure or a success
00038    
00039    int iErrval;
00040    Net::getSocketOption( m_skCom, SO_ERROR, iErrval ); 
00041    
00042    if ( iErrval ) {
00043       m_osError = iErrval;
00044       return false;
00045    }
00046 
00047    m_bTout = false;
00048    m_osError = 0;
00049    return true;
00050 }
00051 
00052 void TCPSocket::buildSocket( const Address *local, const Address *remote ) 
00053    throw( InitError )
00054 {
00055    m_skCom = Net::createTCPSocket();
00056    if ( ! Net::validSocket( m_skCom ) )
00057       throw InitError( "Low level socket not created", Net::errorCode() );
00058 
00059    Net::setNonBlocking( m_skCom );
00060    Net::setTCPDefaults( m_skCom );
00061 
00062    // if we have a local address, we must bind.
00063    if ( local != 0 )
00064    {
00065       m_local = *local;
00066       if ( ! Net::bind( m_skCom, m_local.address() ) )
00067       {
00068          Net::closeSocket( m_skCom );
00069          Net::invalidate( m_skCom );
00070          throw InitError( "Low level socket can't bind", Net::errorCode() );
00071       }
00072    }
00073 
00074    // if we have a remote address, we must connect
00075    if ( remote != 0 )
00076    {
00077       m_remote = *remote;
00078    }
00079 }
00080 
00081 std::string TCPSocket::recvLine( int maxCount )
00082 {
00083    int recvd = 0;
00084    int r;
00085    int pos = 0;
00086    std::string ret = "";
00087    char buf[ 512 ];
00088 
00089    while ( (maxCount == 0 || recvd < maxCount ) )
00090    {
00091       r = recv( buf + pos, 1 );
00092       if ( r < 0 ) return "";
00093       if ( r == 0 ) {
00094          if ( pos > 0 ) {
00095             buf[pos] = '\0';
00096             ret+=buf;
00097          }
00098 
00099          return ret;
00100       }
00101 
00102       if ( pos >=1 ) {
00103          if ( buf[pos-1] == '\r' && buf[pos] == '\n' ) {
00104             buf[pos-1] = '\0';
00105             pos = 0;
00106             ret += buf;
00107             break;
00108          }
00109       }
00110 
00111       pos ++;
00112       recvd++;
00113 
00114       if ( (pos == 510 && buf[509] != '\r') || pos == 511) {
00115          buf[pos] = '\0';
00116          ret+=buf;
00117          pos = 0;
00118       }
00119    }
00120 
00121    if ( pos > 0 ) {
00122       buf[pos] = '\0';
00123       ret+=buf;
00124    }
00125 
00126    return ret;
00127 }
00128 
00129 
00130 int TCPSocket::sendAll( const void *buffer, const int len )
00131 {
00132    int sent;
00133    int sentTotal =0;
00134 
00135    while ( sentTotal < len ) {
00136       sent = rawSend( static_cast<const void *>(static_cast<const char *>(buffer) + sentTotal), len - sentTotal );
00137       if ( sent < 0 || hasTimedOut() ) {
00138          m_opType = OT_SENDINGALL;
00139          m_buffer = buffer;
00140          m_buflen = len;
00141          m_bufdone = sentTotal;
00142          return sentTotal;
00143       }
00144       sentTotal += sent;
00145    }
00146    return sentTotal;
00147 }
00148 
00149 
00150 int TCPSocket::recvAll( void *buffer, const int len )
00151 {
00152    int recvd;
00153    int recvTotal = 0;
00154 
00155    while ( recvTotal < len ) {
00156       recvd = recv( static_cast<char *>(buffer) + recvTotal, len - recvTotal );
00157       if ( recvd < 0 || hasTimedOut() ) {
00158          m_opType = OT_RECEIVINGALL;
00159          m_buffer = buffer;
00160          m_buflen = len;
00161          m_bufdone = recvTotal;
00162          return recvTotal;
00163       }
00164       recvTotal += recvd;
00165    }
00166    return recvTotal;
00167 }
00168 
00169 
00170 bool TCPSocket::continueOp()
00171 {
00172    switch( m_opType ) {
00173       case OT_CONNECTING:
00174          m_osError = 0;
00175          if(! selectFor( true ) )  //select for write
00176          {
00177             /* Timed out */
00178             m_bTout = true;
00179             return false;
00180          }
00181 
00182          m_bTout = false;
00183       return true;
00184       // others not yet implemented
00185    }
00186 
00187    return false;
00188 }
00189  
00190 }
00191 
00192 /* end of cabal_tcpsocket.h */

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