gloox  1.0
connectiontcpclient.cpp
1 /*
2  Copyright (c) 2004-2009 by Jakob Schroeter <js@camaya.net>
3  This file is part of the gloox library. http://camaya.net/gloox
4 
5  This software is distributed under a license. The full license
6  agreement can be found in the file LICENSE in this distribution.
7  This software may not be copied, modified, sold or distributed
8  other than expressed in the named license agreement.
9 
10  This software is distributed without any warranty.
11 */
12 
13 
14 
15 #include "gloox.h"
16 
17 #include "connectiontcpclient.h"
18 #include "dns.h"
19 #include "logsink.h"
20 #include "mutexguard.h"
21 
22 #ifdef __MINGW32__
23 # include <winsock.h>
24 #endif
25 
26 #if ( !defined( _WIN32 ) && !defined( _WIN32_WCE ) ) || defined( __SYMBIAN32__ )
27 # include <sys/types.h>
28 # include <sys/socket.h>
29 # include <sys/select.h>
30 # include <unistd.h>
31 #elif ( defined( _WIN32 ) || defined( _WIN32_WCE ) ) && !defined( __SYMBIAN32__ )
32 # include <winsock.h>
33 #endif
34 
35 #include <cstdlib>
36 #include <string>
37 
38 namespace gloox
39 {
40 
42  const std::string& server, int port )
43  : ConnectionTCPBase( logInstance, server, port )
44  {
45  }
46 
48  const std::string& server, int port )
49  : ConnectionTCPBase( cdh, logInstance, server, port )
50  {
51  }
52 
53 
55  {
56  }
57 
59  {
60  return new ConnectionTCPClient( m_handler, m_logInstance, m_server, m_port );
61  }
62 
64  {
65  m_sendMutex.lock();
66 // FIXME CHECKME
67  if( !m_handler )
68  {
69  m_sendMutex.unlock();
70  return ConnNotConnected;
71  }
72 
73  if( m_socket >= 0 && m_state > StateDisconnected )
74  {
75  m_sendMutex.unlock();
76  return ConnNoError;
77  }
78 
80 
81  if( m_socket < 0 )
82  {
83  if( m_port == -1 )
84  m_socket = DNS::connect( m_server, m_logInstance );
85  else
86  m_socket = DNS::connect( m_server, m_port, m_logInstance );
87  }
88 
89  m_sendMutex.unlock();
90 
91  if( m_socket < 0 )
92  {
93  switch( m_socket )
94  {
96  m_logInstance.err( LogAreaClassConnectionTCPClient,
97  m_server + ": connection refused" );
98  break;
99  case -ConnDnsError:
100  m_logInstance.err( LogAreaClassConnectionTCPClient,
101  m_server + ": host not found" );
102  break;
103  default:
104  m_logInstance.err( LogAreaClassConnectionTCPClient,
105  "Unknown error condition" );
106  break;
107  }
108  m_handler->handleDisconnect( this, (ConnectionError)-m_socket );
109  return (ConnectionError)-m_socket;
110  }
111  else
112  {
114  }
115 
116  m_cancel = false;
117  m_handler->handleConnect( this );
118  return ConnNoError;
119  }
120 
122  {
123  m_recvMutex.lock();
124 
125  if( m_cancel || m_socket < 0 )
126  {
127  m_recvMutex.unlock();
128  return ConnNotConnected;
129  }
130 
131  if( !dataAvailable( timeout ) )
132  {
133  m_recvMutex.unlock();
134  return ConnNoError;
135  }
136 
137  int size = static_cast<int>( ::recv( m_socket, m_buf, m_bufsize, 0 ) );
138  if( size > 0 )
139  m_totalBytesIn += size;
140 
141  m_recvMutex.unlock();
142 
143  if( size <= 0 )
144  {
145  ConnectionError error = ( size ? ConnIoError : ConnStreamClosed );
146  if( m_handler )
147  m_handler->handleDisconnect( this, error );
148  return error;
149  }
150 
151  m_buf[size] = '\0';
152 
153  if( m_handler )
154  m_handler->handleReceivedData( this, std::string( m_buf, size ) );
155 
156  return ConnNoError;
157  }
158 
159 }