00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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 ) )
00029 {
00030
00031 m_osError = 0;
00032 m_opType = OT_CONNECTING;
00033 m_bTout = true;
00034 return false;
00035 }
00036
00037
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
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
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 ) )
00176 {
00177
00178 m_bTout = true;
00179 return false;
00180 }
00181
00182 m_bTout = false;
00183 return true;
00184
00185 }
00186
00187 return false;
00188 }
00189
00190 }
00191
00192