connectiontcpclient.cpp

00001 /*
00002   Copyright (c) 2004-2008 by Jakob Schroeter <js@camaya.net>
00003   This file is part of the gloox library. http://camaya.net/gloox
00004 
00005   This software is distributed under a license. The full license
00006   agreement can be found in the file LICENSE in this distribution.
00007   This software may not be copied, modified, sold or distributed
00008   other than expressed in the named license agreement.
00009 
00010   This software is distributed without any warranty.
00011 */
00012 
00013 
00014 
00015 #include "gloox.h"
00016 
00017 #include "connectiontcpclient.h"
00018 #include "dns.h"
00019 #include "logsink.h"
00020 #include "mutexguard.h"
00021 
00022 #ifdef __MINGW32__
00023 # include <winsock.h>
00024 #endif
00025 
00026 #if !defined( WIN32 ) && !defined( _WIN32_WCE )
00027 # include <sys/types.h>
00028 # include <sys/socket.h>
00029 # include <sys/select.h>
00030 # include <unistd.h>
00031 #else
00032 # include <winsock.h>
00033 #endif
00034 
00035 #include <cstdlib>
00036 #include <string>
00037 
00038 #ifndef _WIN32_WCE
00039 # include <sstream>
00040 #endif
00041 
00042 namespace gloox
00043 {
00044 
00045   ConnectionTCPClient::ConnectionTCPClient( const LogSink& logInstance,
00046                                             const std::string& server, int port )
00047     : ConnectionTCPBase( logInstance, server, port )
00048   {
00049   }
00050 
00051   ConnectionTCPClient::ConnectionTCPClient( ConnectionDataHandler *cdh, const LogSink& logInstance,
00052                                             const std::string& server, int port )
00053     : ConnectionTCPBase( cdh, logInstance, server, port )
00054   {
00055   }
00056 
00057 
00058   ConnectionTCPClient::~ConnectionTCPClient()
00059   {
00060   }
00061 
00062   ConnectionBase* ConnectionTCPClient::newInstance() const
00063   {
00064     return new ConnectionTCPClient( m_handler, m_logInstance, m_server, m_port );
00065   }
00066 
00067   ConnectionError ConnectionTCPClient::connect()
00068   {
00069     m_sendMutex.lock();
00070 
00071     if( !m_handler || m_socket >= 0 )
00072     {
00073       m_sendMutex.unlock();
00074       return ConnNotConnected;
00075     }
00076 
00077     if( m_state > StateDisconnected )
00078     {
00079       m_sendMutex.unlock();
00080       return ConnNoError;
00081     }
00082 
00083     m_state = StateConnecting;
00084 
00085     if( m_socket < 0 )
00086     {
00087       if( m_port == -1 )
00088         m_socket = DNS::connect( m_server, m_logInstance );
00089       else
00090         m_socket = DNS::connect( m_server, m_port, m_logInstance );
00091     }
00092 
00093     m_sendMutex.unlock();
00094 
00095     if( m_socket < 0 )
00096     {
00097       switch( m_socket )
00098       {
00099         case -ConnConnectionRefused:
00100           m_logInstance.log( LogLevelError, LogAreaClassConnectionTCPClient,
00101                              m_server + ": connection refused" );
00102           break;
00103         case -ConnDnsError:
00104           m_logInstance.log( LogLevelError, LogAreaClassConnectionTCPClient,
00105                              m_server + ": host not found" );
00106           break;
00107         default:
00108           m_logInstance.log( LogLevelError, LogAreaClassConnectionTCPClient,
00109                              "Unknown error condition" );
00110           break;
00111       }
00112       m_handler->handleDisconnect( this, (ConnectionError)-m_socket );
00113       return (ConnectionError)-m_socket;
00114     }
00115     else
00116     {
00117       m_state = StateConnected;
00118     }
00119 
00120     m_cancel = false;
00121     m_handler->handleConnect( this );
00122     return ConnNoError;
00123   }
00124 
00125   ConnectionError ConnectionTCPClient::recv( int timeout )
00126   {
00127     m_recvMutex.lock();
00128 
00129     if( m_cancel || m_socket < 0 )
00130     {
00131       m_recvMutex.unlock();
00132       return ConnNotConnected;
00133     }
00134 
00135     if( !dataAvailable( timeout ) )
00136     {
00137       m_recvMutex.unlock();
00138       return ConnNoError;
00139     }
00140 
00141 #ifdef SKYOS
00142     int size = ::recv( m_socket, (unsigned char*)m_buf, m_bufsize, 0 );
00143 #else
00144     int size = ::recv( m_socket, m_buf, m_bufsize, 0 );
00145 #endif
00146 
00147     if( size > 0 )
00148       m_totalBytesIn += size;
00149 
00150     m_recvMutex.unlock();
00151 
00152     if( size <= 0 )
00153     {
00154       ConnectionError error = ( size ? ConnIoError : ConnStreamClosed );
00155       if( m_handler )
00156         m_handler->handleDisconnect( this, error );
00157       return error;
00158     }
00159 
00160     m_buf[size] = '\0';
00161 
00162     if( m_handler )
00163       m_handler->handleReceivedData( this, std::string( m_buf, size ) );
00164 
00165     return ConnNoError;
00166   }
00167 
00168 }

Generated on Fri Oct 10 15:26:11 2008 for gloox by  doxygen 1.5.6