connectiontcpserver.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "gloox.h"
00016
00017 #include "connectiontcpserver.h"
00018 #include "connectiontcpclient.h"
00019 #include "connectionhandler.h"
00020 #include "dns.h"
00021 #include "logsink.h"
00022 #include "mutex.h"
00023 #include "mutexguard.h"
00024 #include "util.h"
00025
00026 #ifdef __MINGW32__
00027 # include <winsock.h>
00028 #endif
00029
00030 #if ( !defined( _WIN32 ) && !defined( _WIN32_WCE ) ) || defined( __SYMBIAN32__ )
00031 # include <netinet/in.h>
00032 # include <arpa/nameser.h>
00033 # include <resolv.h>
00034 # include <netdb.h>
00035 # include <arpa/inet.h>
00036 # include <sys/socket.h>
00037 # include <sys/un.h>
00038 # include <sys/select.h>
00039 # include <unistd.h>
00040 # include <errno.h>
00041 #endif
00042
00043 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
00044 # include <winsock.h>
00045 #elif defined( _WIN32_WCE )
00046 # include <winsock2.h>
00047 #endif
00048
00049 #include <cstdlib>
00050 #include <string>
00051
00052 #ifndef _WIN32_WCE
00053 # include <sys/types.h>
00054 #endif
00055
00056 namespace gloox
00057 {
00058
00059 ConnectionTCPServer::ConnectionTCPServer( ConnectionHandler* ch, const LogSink& logInstance,
00060 const std::string& ip, int port )
00061 : ConnectionTCPBase( 0, logInstance, ip, port ),
00062 m_connectionHandler( ch )
00063 {
00064 }
00065
00066 ConnectionTCPServer::~ConnectionTCPServer()
00067 {
00068 }
00069
00070 ConnectionBase* ConnectionTCPServer::newInstance() const
00071 {
00072 return new ConnectionTCPServer( m_connectionHandler, m_logInstance, m_server, m_port );
00073 }
00074
00075 ConnectionError ConnectionTCPServer::connect()
00076 {
00077 util::MutexGuard mg( &m_sendMutex );
00078
00079 if( m_socket >= 0 || m_state > StateDisconnected )
00080 return ConnNoError;
00081
00082 m_state = StateConnecting;
00083
00084 if( m_socket < 0 )
00085 m_socket = DNS::getSocket( m_logInstance );
00086
00087 if( m_socket < 0 )
00088 return ConnIoError;
00089
00090 struct sockaddr_in local;
00091 local.sin_family = AF_INET;
00092 local.sin_port = static_cast<unsigned short int>( htons( m_port ) );
00093 local.sin_addr.s_addr = m_server.empty() ? INADDR_ANY : inet_addr( m_server.c_str() );
00094 memset( local.sin_zero, '\0', 8 );
00095
00096 if( bind( m_socket, (struct sockaddr*)&local, sizeof( struct sockaddr ) ) < 0 )
00097 {
00098 std::string message = "bind() to " + ( m_server.empty() ? std::string( "*" ) : m_server )
00099 + " (" + inet_ntoa( local.sin_addr ) + ":" + util::int2string( m_port ) + ") failed. "
00100 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
00101 "WSAGetLastError: " + util::int2string( ::WSAGetLastError() );
00102 #else
00103 "errno: " + util::int2string( errno );
00104 #endif
00105 m_logInstance.dbg( LogAreaClassConnectionTCPServer, message );
00106
00107 return ConnIoError;
00108 }
00109
00110 if( listen( m_socket, 10 ) < 0 )
00111 {
00112 std::string message = "listen on " + ( m_server.empty() ? std::string( "*" ) : m_server )
00113 + " (" + inet_ntoa( local.sin_addr ) + ":" + util::int2string( m_port ) + ") failed. "
00114 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
00115 "WSAGetLastError: " + util::int2string( ::WSAGetLastError() );
00116 #else
00117 "errno: " + util::int2string( errno );
00118 #endif
00119 m_logInstance.dbg( LogAreaClassConnectionTCPServer, message );
00120
00121 return ConnIoError;
00122 }
00123
00124 m_cancel = false;
00125 return ConnNoError;
00126 }
00127
00128 ConnectionError ConnectionTCPServer::recv( int timeout )
00129 {
00130 m_recvMutex.lock();
00131
00132 if( m_cancel || m_socket < 0 || !m_connectionHandler )
00133 {
00134 m_recvMutex.unlock();
00135 return ConnNotConnected;
00136 }
00137
00138 if( !dataAvailable( timeout ) )
00139 {
00140 m_recvMutex.unlock();
00141 return ConnNoError;
00142 }
00143
00144 struct sockaddr_in they;
00145 int sin_size = sizeof( struct sockaddr_in );
00146 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
00147 int newfd = static_cast<int>( accept( static_cast<SOCKET>( m_socket ), (struct sockaddr*)&they, &sin_size ) );
00148 #else
00149 int newfd = accept( m_socket, (struct sockaddr*)&they, (socklen_t*)&sin_size );
00150 #endif
00151
00152 m_recvMutex.unlock();
00153
00154 ConnectionTCPClient* conn = new ConnectionTCPClient( m_logInstance, inet_ntoa( they.sin_addr ),
00155 ntohs( they.sin_port ) );
00156 conn->setSocket( newfd );
00157 m_connectionHandler->handleIncomingConnection( this, conn );
00158
00159 return ConnNoError;
00160 }
00161
00162 }