gloox 1.0.27
connectiontcpclient.cpp
1/*
2 Copyright (c) 2004-2023 by Jakob Schröter <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#include "config.h"
15
16#include "gloox.h"
17
18#include "connectiontcpclient.h"
19#include "dns.h"
20#include "logsink.h"
21#include "mutexguard.h"
22#include "util.h"
23
24#ifdef __MINGW32__
25# include <winsock.h>
26#endif
27
28#if ( !defined( _WIN32 ) && !defined( _WIN32_WCE ) ) || defined( __SYMBIAN32__ )
29# include <sys/types.h>
30# include <sys/socket.h>
31# include <sys/select.h>
32# include <unistd.h>
33# include <string.h>
34# include <errno.h>
35#elif ( defined( _WIN32 ) || defined( _WIN32_WCE ) ) && !defined( __SYMBIAN32__ )
36# include <winsock.h>
37#endif
38
39#include <cstdlib>
40#include <string>
41
42namespace gloox
43{
44
46 const std::string& server, int port )
47 : ConnectionTCPBase( logInstance, server, port )
48 {
49 }
50
52 const std::string& server, int port )
53 : ConnectionTCPBase( cdh, logInstance, server, port )
54 {
55 }
56
57
61
63 {
64 return new ConnectionTCPClient( m_handler, m_logInstance, m_server, m_port );
65 }
66
68 {
69 m_sendMutex.lock();
70// FIXME CHECKME
71 if( !m_handler )
72 {
73 m_sendMutex.unlock();
74 return ConnNotConnected;
75 }
76
77 if( m_socket >= 0 && m_state > StateDisconnected )
78 {
79 m_sendMutex.unlock();
80 return ConnNoError;
81 }
82
84
85 if( m_socket < 0 )
86 {
87 if( m_port == -1 )
88 m_socket = DNS::connect( m_server, m_logInstance );
89 else
90 m_socket = DNS::connect( m_server, m_port, m_logInstance );
91 }
92
93 m_sendMutex.unlock();
94
95 if( m_socket < 0 )
96 {
97 switch( m_socket )
98 {
101 m_server + ": connection refused" );
102 break;
103 case -ConnDnsError:
105 m_server + ": host not found" );
106 break;
107 default:
109 "Unknown error condition" );
110 break;
111 }
112 m_handler->handleDisconnect( this, static_cast<ConnectionError>( -m_socket ) );
113 return static_cast<ConnectionError>( -m_socket );
114 }
115 else
116 {
118 }
119
120 m_cancel = false;
121 m_handler->handleConnect( this );
122 return ConnNoError;
123 }
124
126 {
127 m_recvMutex.lock();
128
129 if( m_cancel || m_socket < 0 )
130 {
131 m_recvMutex.unlock();
132 return ConnNotConnected;
133 }
134
135 if( !dataAvailable( timeout ) )
136 {
137 m_recvMutex.unlock();
138 return ConnNoError;
139 }
140
141#if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
142 int size = static_cast<int>( ::recv( m_socket, m_buf, m_bufsize, 0 ) );
143#else
144 int size = static_cast<int>( ::recv( m_socket, m_buf, m_bufsize, MSG_DONTWAIT ) );
145#endif
146 if( size > 0 )
147 m_totalBytesIn += size;
148
149 m_recvMutex.unlock();
150
151 if( size <= 0 )
152 {
153 if( size == -1 )
154 {
155
156#if defined(__unix__)
157 if( errno == EAGAIN || errno == EWOULDBLOCK )
158 return ConnNoError;
159#endif
160
161 // recv() failed for an unexpected reason
162 std::string message = "recv() failed. "
163#if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
164 "WSAGetLastError: " + util::int2string( ::WSAGetLastError() );
165#else
166 "errno: " + util::int2string( errno ) + ": " + strerror( errno );
167#endif
168 m_logInstance.err( LogAreaClassConnectionTCPClient, message );
169 }
170
171 ConnectionError error = ( size ? ConnIoError : ConnStreamClosed );
172 if( m_handler )
173 m_handler->handleDisconnect( this, error );
174 return error;
175 }
176
177 m_buf[size] = '\0';
178
179 if( m_handler )
180 m_handler->handleReceivedData( this, std::string( m_buf, size ) );
181
182 return ConnNoError;
183 }
184
185}
An abstract base class for a connection.
ConnectionState m_state
ConnectionDataHandler * m_handler
This is an abstract base class to receive events from a ConnectionBase-derived object.
virtual void handleReceivedData(const ConnectionBase *connection, const std::string &data)=0
virtual void handleDisconnect(const ConnectionBase *connection, ConnectionError reason)=0
virtual void handleConnect(const ConnectionBase *connection)=0
This is a base class for a simple TCP connection.
This is an implementation of a simple TCP connection.
virtual ConnectionError recv(int timeout=-1)
virtual ConnectionBase * newInstance() const
virtual ConnectionError connect()
ConnectionTCPClient(const LogSink &logInstance, const std::string &server, int port=-1)
static int connect(const std::string &host, const LogSink &logInstance)
Definition dns.cpp:247
An implementation of log sink and source.
Definition logsink.h:39
void err(LogArea area, const std::string &message) const
Definition logsink.h:84
The namespace for the gloox library.
Definition adhoc.cpp:28
ConnectionError
Definition gloox.h:684
@ ConnNotConnected
Definition gloox.h:715
@ ConnConnectionRefused
Definition gloox.h:698
@ ConnDnsError
Definition gloox.h:700
@ ConnNoError
Definition gloox.h:685
@ ConnStreamClosed
Definition gloox.h:689
@ ConnIoError
Definition gloox.h:696
@ LogAreaClassConnectionTCPClient
Definition gloox.h:1062
@ StateDisconnected
Definition gloox.h:642
@ StateConnected
Definition gloox.h:644
@ StateConnecting
Definition gloox.h:643