1/* -*- C++ -*-
2 * Copyright (C) 2003,2005 Thiago Macieira <thiago@kde.org>
3 *
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef KCLIENTSOCKETBASE_H
26#define KCLIENTSOCKETBASE_H
27
28#include <QtCore/QObject>
29#include <QtCore/QString>
30
31#include <kdecore_export.h>
32#include "k3socketbase.h"
33#include "k3resolver.h"
34
35namespace KNetwork {
36
37class KClientSocketBasePrivate;
38/** @class KClientSocketBase k3clientsocketbase.h k3clientsocketbase.h
39 * @brief Abstract client socket class.
40 *
41 * This class provides the base functionality for client sockets,
42 * such as, and especially, name resolution and signals.
43 *
44 * @note This class is abstract. If you're looking for a normal,
45 * client socket class, see KStreamSocket and KBufferedSocket
46 *
47 * @author Thiago Macieira <thiago@kde.org>
48 * @deprecated Use KSocketFactory or KLocalSocket instead
49 */
50class KDECORE_EXPORT_DEPRECATED KClientSocketBase : public KActiveSocketBase
51{
52 Q_OBJECT
53
54public:
55 /**
56 * Socket states.
57 *
58 * These are the possible states for a KClientSocketBase:
59 * - Idle: socket is not connected
60 * - HostLookup: socket is doing host lookup prior to connecting
61 * - HostFound: name lookup is complete
62 * - Bound: the socket is locally bound
63 * - Connecting: socket is attempting connection
64 * - Open: socket is open
65 * - Connected (=Open): socket is connected
66 * - Connection (=Open): yet another name for a connected socket
67 * - Closing: socket is shutting down
68 *
69 * Whenever the socket state changes, the stateChanged(int) signal
70 * will be emitted.
71 */
72 enum SocketState
73 {
74 Idle,
75 HostLookup,
76 HostFound,
77 Bound,
78 Connecting,
79 Open,
80 Closing,
81
82 Unconnected = Bound,
83 Connected = Open,
84 Connection = Open
85 };
86
87public:
88 /**
89 * Default constructor.
90 *
91 * @param parent the parent QObject object
92 */
93 KClientSocketBase(QObject* parent);
94
95 /**
96 * Destructor.
97 */
98 virtual ~KClientSocketBase();
99
100 /**
101 * Returns the current state for this socket.
102 * @see SocketState
103 */
104 SocketState state() const;
105
106protected:
107 /**
108 * Sets the socket options. Reimplemented from KSocketBase.
109 */
110 virtual bool setSocketOptions(int opts);
111
112public:
113 /**
114 * Returns the internal KResolver object used for
115 * looking up the peer host name and service.
116 *
117 * This can be used to set extra options to the
118 * lookup process other than the default values, as well
119 * as obtaining the error codes in case of lookup failure.
120 */
121 KResolver& peerResolver() const;
122
123 /**
124 * Returns the internal list of resolved results for the peer address.
125 */
126 const KResolverResults& peerResults() const;
127
128 /**
129 * Returns the internal KResolver object used for
130 * looking up the local host name and service.
131 *
132 * This can be used to set extra options to the
133 * lookup process other than the default values, as well
134 * as obtaining the error codes in case of lookup failure.
135 */
136 KResolver& localResolver() const;
137
138 /**
139 * Returns the internal list of resolved results for the local address.
140 */
141 const KResolverResults& localResults() const;
142
143 /**
144 * Enables or disables name resolution. If this flag is set to true,
145 * bind() and connect() operations will trigger name lookup
146 * operations (i.e., converting a hostname into its binary form).
147 * If the flag is set to false, those operations will instead
148 * try to convert a string representation of an address without
149 * attempting name resolution.
150 *
151 * This is useful, for instance, when IP addresses are in
152 * their string representation (such as "1.2.3.4") or come
153 * from other sources like KSocketAddress.
154 *
155 * @param enable whether to enable
156 */
157 void setResolutionEnabled(bool enable);
158
159 /**
160 * Sets the allowed families for the resolutions.
161 *
162 * @param families the families that we want/accept
163 * @see KResolver::SocketFamilies for possible values
164 */
165 void setFamily(int families);
166
167 /**
168 * Starts the lookup for peer and local hostnames as
169 * well as their services.
170 *
171 * If the blocking mode for this object is on, this function will
172 * wait for the lookup results to be available (by calling the
173 * KResolver::wait() method on the resolver objects).
174 *
175 * When the lookup is done, the signal hostFound() will be
176 * emitted (only once, even if we're doing a double lookup).
177 * If the lookup failed (for any of the two lookups) the
178 * gotError() signal will be emitted with the appropriate
179 * error condition (see KSocketBase::SocketError).
180 *
181 * This function returns true on success and false on error. Note that
182 * this is not the lookup result!
183 */
184 virtual bool lookup();
185
186 /**
187 * Binds this socket to the given nodename and service,
188 * or use the default ones if none are given.
189 *
190 * Upon successful binding, the bound() signal will be
191 * emitted. If an error is found, the gotError()
192 * signal will be emitted.
193 *
194 * @note Due to the internals of the name lookup and binding
195 * mechanism, some (if not most) implementations of this function
196 * do not actually bind the socket until the connection
197 * is requested (see connect()). They only set the values
198 * for future reference.
199 *
200 * This function returns true on success.
201 *
202 * @param node the nodename
203 * @param service the service
204 */
205 virtual bool bind(const QString& node = QString(),
206 const QString& service = QString()) = 0;
207
208 /**
209 * Reimplemented from KSocketBase. Connect this socket to this
210 * specific address.
211 *
212 * Unlike bind(const QString&, const QString&) above, this function
213 * really does bind the socket. No lookup is performed. The bound()
214 * signal will be emitted.
215 */
216 virtual bool bind(const KResolverEntry& address);
217
218 /**
219 * Attempts to connect to a given hostname and service,
220 * or use the default ones if none are given. If a connection attempt
221 * is already in progress, check on its state and set the error status
222 * (NoError or InProgress).
223 *
224 * If the blocking mode for this object is on, this function will only
225 * return when all the resolved peer addresses have been tried or when
226 * a connection is established.
227 *
228 * Upon successfully connecting, the connected() signal
229 * will be emitted. If an error is found, the gotError()
230 * signal will be emitted.
231 *
232 * @par Note for derived classes:
233 * Derived classes must implement this function. The implementation
234 * will set the parameters for the lookup (using the peer KResolver
235 * object) and call lookup() to start it.
236 *
237 * @par
238 * The implementation should use the hostFound()
239 * signal to be notified of the completion of the lookup process and
240 * then proceed to start the connection itself. Care should be taken
241 * regarding the value of blocking() flag.
242 *
243 * @param node the nodename (host to connect to)
244 * @param service the service to connect to
245 * @param mode the mode to open the connection in
246 */
247 virtual bool connect(const QString& node = QString(),
248 const QString& service = QString(),
249 OpenMode mode = ReadWrite) = 0;
250
251 /**
252 * @overload
253 * Reimplemented from KSocketBase.
254 */
255 virtual bool connect(const KResolverEntry& address,
256 OpenMode mode = ReadWrite);
257
258 /**
259 * Disconnects the socket.
260 * Note that not all socket types can disconnect.
261 */
262 virtual bool disconnect();
263
264 /**
265 * Opens the socket. Reimplemented from QIODevice.
266 *
267 * You should not call this function; instead, use connect()
268 */
269 virtual bool open(OpenMode mode);
270
271 /**
272 * Closes the socket. Reimplemented from QIODevice.
273 *
274 * The closing of the socket causes the emission of the
275 * signal closed().
276 */
277 virtual void close();
278
279 /**
280 * This call is not supported on unbuffered sockets.
281 * Reimplemented from QIODevice.
282 */
283 virtual bool flush();
284
285 /**
286 * Returns the number of bytes available on this socket.
287 * Reimplemented from KSocketBase.
288 */
289 virtual qint64 bytesAvailable() const;
290
291 /**
292 * Waits for more data. Reimplemented from KSocketBase.
293 */
294 virtual qint64 waitForMore(int msecs, bool *timeout = 0L);
295
296 /**
297 * Returns the local socket address. Reimplemented from KSocketBase.
298 */
299 virtual KSocketAddress localAddress() const;
300
301 /**
302 * Returns the peer socket address. Reimplemented from KSocketBase.
303 */
304 virtual KSocketAddress peerAddress() const;
305
306 /**
307 * Returns true if the readyRead signal is set to be emitted.
308 */
309 bool emitsReadyRead() const;
310
311 /**
312 * Enables the emission of the readyRead signal.
313 * By default, this signal is enabled.
314 *
315 * @param enable whether to enable the signal
316 */
317 virtual void enableRead(bool enable);
318
319 /**
320 * Returns true if the readyWrite signal is set to be emitted.
321 */
322 bool emitsReadyWrite() const;
323
324 /**
325 * Enables the emission of the readyWrite signal.
326 * By default, this signal is disabled.
327 *
328 * @param enable whether to enable the signal
329 */
330 virtual void enableWrite(bool enable);
331
332protected Q_SLOTS:
333 // protected slots
334
335 /**
336 * This slot is connected to the read notifier's signal meaning
337 * the socket can read more data.
338 *
339 * The default implementation only emits the readyRead signal.
340 *
341 * Override if your class requires processing of incoming
342 * data.
343 */
344 virtual void slotReadActivity();
345
346 /**
347 * This slot is connected to the write notifier's signal
348 * meaning the socket can write more data.
349 *
350 * The default implementation only emits the readyWrite signal.
351 *
352 * Override if your class writes data from another source
353 * (like a buffer).
354 */
355 virtual void slotWriteActivity();
356
357private Q_SLOTS:
358 void lookupFinishedSlot();
359
360Q_SIGNALS:
361 /**
362 * This signal is emitted whenever the socket state changes.
363 *
364 * Note: do not delete this object inside the slot called by this
365 * signal.
366 *
367 * @param newstate the new state of the socket object
368 */
369 void stateChanged(int newstate);
370
371 /**
372 * This signal is emitted when this object finds an error.
373 * The @p code parameter contains the error code that can
374 * also be found by calling error().
375 */
376 void gotError(int code);
377
378 /**
379 * This signal is emitted when the lookup is successfully completed.
380 */
381 void hostFound();
382
383 /**
384 * This signal is emitted when the socket successfully binds
385 * to an address.
386 *
387 * @param local the local address we bound to
388 */
389 void bound(const KNetwork::KResolverEntry& local);
390
391 /**
392 * This signal is emitted when the socket is about to connect
393 * to an address (but before doing so).
394 *
395 * The @p skip parameter can be used to make the loop skip this address.
396 * Its value is initially false: change it to true if you want to
397 * skip the current address (as given by @p remote).
398 *
399 * This function is also useful if one wants to reset the timeout.
400 *
401 * @param remote the address we're about to connect to
402 * @param skip set to true if you want to skip this address
403 * @note if the connection is successful, the connected() signal will be
404 * emitted.
405 */
406 void aboutToConnect(const KNetwork::KResolverEntry& remote, bool& skip);
407
408 /**
409 * This socket is emitted when the socket successfully connects
410 * to a remote address.
411 *
412 * @param remote the remote address we did connect to
413 */
414 void connected(const KNetwork::KResolverEntry& remote);
415
416 /**
417 * This signal is emitted when the socket completes the
418 * closing/shut down process.
419 */
420 void closed();
421
422#if 0
423 // QIODevice already has this
424 /**
425 * This signal is emitted whenever the socket is ready for
426 * reading -- i.e., there is data to be read in the buffers.
427 * The subsequent read operation is guaranteed to be non-blocking.
428 *
429 * You can toggle the emission of this signal with the enableRead()
430 * function. This signal is by default enabled.
431 */
432 void readyRead();
433#endif
434
435 /**
436 * This signal is emitted whenever the socket is ready for
437 * writing -- i.e., whenever there's space available in the buffers
438 * to receive more data. The subsequent write operation is
439 * guaranteed to be non-blocking.
440 *
441 * You can toggle the emission of this signal with the enableWrite()
442 * function. This signal is by default disabled. You will
443 * want to disable this signal after the first reception, since
444 * it'll probably fire at every event loop.
445 */
446 void readyWrite();
447
448protected:
449 /**
450 * Reads data from a socket. Reimplemented from KSocketBase.
451 */
452 virtual qint64 readData(char *data, qint64 maxlen, KSocketAddress *from);
453
454 /**
455 * Peeks data from the socket. Reimplemented from KSocketBase.
456 */
457 virtual qint64 peekData(char *data, qint64 maxlen, KSocketAddress *from);
458
459 /**
460 * @overload
461 * Writes data to the socket. Reimplemented from KSocketBase.
462 */
463 virtual qint64 writeData(const char *data, qint64 len, const KSocketAddress* to);
464
465 /**
466 * Sets the socket state to @p state. This function does not
467 * emit the stateChanged() signal.
468 */
469 void setState(SocketState state);
470
471 /**
472 * This function is called by setState() whenever the state
473 * changes. You should override it if you need to specify any
474 * actions to be done when the state changes.
475 *
476 * The default implementation acts for these states only:
477 * - Connected: it sets up the socket notifiers to fire readyRead and
478 * readyWrite signals.
479 */
480 virtual void stateChanging(SocketState newState);
481
482 /**
483 * Convenience function to set this object's error code to match
484 * that of the socket device.
485 */
486 void copyError();
487
488private:
489 KClientSocketBase(const KClientSocketBase&);
490 KClientSocketBase& operator=(const KClientSocketBase&);
491
492 KClientSocketBasePrivate* const d;
493};
494
495} // namespace KNetwork
496
497#endif
498