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 )
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 }