connectiontcpclient.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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 ) ) || defined( __SYMBIAN32__ )
00027 # include <sys/types.h>
00028 # include <sys/socket.h>
00029 # include <sys/select.h>
00030 # include <unistd.h>
00031 #elif ( defined( _WIN32 ) || defined( _WIN32_WCE ) ) && !defined( __SYMBIAN32__ )
00032 # include <winsock.h>
00033 #endif
00034
00035 #include <cstdlib>
00036 #include <string>
00037
00038 namespace gloox
00039 {
00040
00041 ConnectionTCPClient::ConnectionTCPClient( const LogSink& logInstance,
00042 const std::string& server, int port )
00043 : ConnectionTCPBase( logInstance, server, port )
00044 {
00045 }
00046
00047 ConnectionTCPClient::ConnectionTCPClient( ConnectionDataHandler* cdh, const LogSink& logInstance,
00048 const std::string& server, int port )
00049 : ConnectionTCPBase( cdh, logInstance, server, port )
00050 {
00051 }
00052
00053
00054 ConnectionTCPClient::~ConnectionTCPClient()
00055 {
00056 }
00057
00058 ConnectionBase* ConnectionTCPClient::newInstance() const
00059 {
00060 return new ConnectionTCPClient( m_handler, m_logInstance, m_server, m_port );
00061 }
00062
00063 ConnectionError ConnectionTCPClient::connect()
00064 {
00065 m_sendMutex.lock();
00066
00067 if( !m_handler )
00068 {
00069 m_sendMutex.unlock();
00070 return ConnNotConnected;
00071 }
00072
00073 if( m_socket >= 0 && m_state > StateDisconnected )
00074 {
00075 m_sendMutex.unlock();
00076 return ConnNoError;
00077 }
00078
00079 m_state = StateConnecting;
00080
00081 if( m_socket < 0 )
00082 {
00083 if( m_port == -1 )
00084 m_socket = DNS::connect( m_server, m_logInstance );
00085 else
00086 m_socket = DNS::connect( m_server, m_port, m_logInstance );
00087 }
00088
00089 m_sendMutex.unlock();
00090
00091 if( m_socket < 0 )
00092 {
00093 switch( m_socket )
00094 {
00095 case -ConnConnectionRefused:
00096 m_logInstance.err( LogAreaClassConnectionTCPClient,
00097 m_server + ": connection refused" );
00098 break;
00099 case -ConnDnsError:
00100 m_logInstance.err( LogAreaClassConnectionTCPClient,
00101 m_server + ": host not found" );
00102 break;
00103 default:
00104 m_logInstance.err( LogAreaClassConnectionTCPClient,
00105 "Unknown error condition" );
00106 break;
00107 }
00108 m_handler->handleDisconnect( this, (ConnectionError)-m_socket );
00109 return (ConnectionError)-m_socket;
00110 }
00111 else
00112 {
00113 m_state = StateConnected;
00114 }
00115
00116 m_cancel = false;
00117 m_handler->handleConnect( this );
00118 return ConnNoError;
00119 }
00120
00121 ConnectionError ConnectionTCPClient::recv( int timeout )
00122 {
00123 m_recvMutex.lock();
00124
00125 if( m_cancel || m_socket < 0 )
00126 {
00127 m_recvMutex.unlock();
00128 return ConnNotConnected;
00129 }
00130
00131 if( !dataAvailable( timeout ) )
00132 {
00133 m_recvMutex.unlock();
00134 return ConnNoError;
00135 }
00136
00137 int size = static_cast<int>( ::recv( m_socket, m_buf, m_bufsize, 0 ) );
00138 if( size > 0 )
00139 m_totalBytesIn += size;
00140
00141 m_recvMutex.unlock();
00142
00143 if( size <= 0 )
00144 {
00145 ConnectionError error = ( size ? ConnIoError : ConnStreamClosed );
00146 if( m_handler )
00147 m_handler->handleDisconnect( this, error );
00148 return error;
00149 }
00150
00151 m_buf[size] = '\0';
00152
00153 if( m_handler )
00154 m_handler->handleReceivedData( this, std::string( m_buf, size ) );
00155
00156 return ConnNoError;
00157 }
00158
00159 }