summaryrefslogtreecommitdiffstats
path: root/tdecore/network/kclientsocketbase.h
blob: 27da219a97d81b1ccd4a73456b388c4b5adac013 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
/*  -*- C++ -*-
 *  Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net>
 *
 *
 *  Permission is hereby granted, free of charge, to any person obtaining
 *  a copy of this software and associated documentation files (the
 *  "Software"), to deal in the Software without restriction, including
 *  without limitation the rights to use, copy, modify, merge, publish,
 *  distribute, sublicense, and/or sell copies of the Software, and to
 *  permit persons to whom the Software is furnished to do so, subject to
 *  the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included 
 *  in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef KCLIENTSOCKETBASE_H
#define KCLIENTSOCKETBASE_H

#include <tqobject.h>
#include <tqstring.h>

#include "tdesocketbase.h"
#include "kresolver.h"
#include <tdelibs_export.h>

#ifdef Q_MOC_RUN
#define USE_QT4
#endif // Q_MOC_RUN

namespace KNetwork {

class KClientSocketBasePrivate;
/** @class KClientSocketBase kclientsocketbase.h kclientsocketbase.h
 *  @brief Abstract client socket class.
 *
 * This class provides the base functionality for client sockets,
 * such as, and especially, name resolution and signals.
 *
 * @note This class is abstract. If you're looking for a normal,
 *       client socket class, see @ref KStreamSocket and TDEBufferedSocket
 *
 * @author Thiago Macieira <thiago.macieira@kdemail.net>
 */
class TDECORE_EXPORT KClientSocketBase :
#ifdef USE_QT4
#else // USE_QT4
public TQObject,
#endif // USE_QT4
public KActiveSocketBase
{
  Q_OBJECT
  

public:
  /**
   * Socket states.
   *
   * These are the possible states for a KClientSocketBase:
   * - Idle: socket is not connected
   * - HostLookup: socket is doing host lookup prior to connecting
   * - HostFound: name lookup is complete
   * - Bound: the socket is locally bound
   * - Connecting: socket is attempting connection
   * - Open: socket is open
   * - Connected (=Open): socket is connected
   * - Connection (=Open): yet another name for a connected socket
   * - Closing: socket is shutting down
   *
   * Whenever the socket state changes, the @ref stateChanged(int) signal
   * will be emitted.
   */
  enum SocketState
  {
    Idle,
    HostLookup,
    HostFound,
    Bound,
    Connecting,
    Open,
    Closing,

    Unconnected = Bound,
    Connected = Open,
    Connection = Open
  };

public:
  /**
   * Default constructor.
   *
   * @param parent	the parent TQObject object
   * @param name	the name of this object
   */
  KClientSocketBase(TQObject* parent, const char *name);

  /**
   * Destructor.
   */
  virtual ~KClientSocketBase();

  /**
   * Returns the current state for this socket.
   * @see SocketState
   */
  SocketState state() const;

protected:
  /**
   * Sets the socket options. Reimplemented from TDESocketBase.
   */
  virtual bool setSocketOptions(int opts);

public:
  /**
   * Returns the internal KResolver object used for
   * looking up the peer host name and service.
   *
   * This can be used to set extra options to the
   * lookup process other than the default values, as well
   * as obtaining the error codes in case of lookup failure.
   */
  KResolver& peerResolver() const;

  /**
   * Returns the internal list of resolved results for the peer address.
   */
  const KResolverResults& peerResults() const;

  /**
   * Returns the internal KResolver object used for
   * looking up the local host name and service.
   *
   * This can be used to set extra options to the
   * lookup process other than the default values, as well
   * as obtaining the error codes in case of lookup failure.
   */
  KResolver& localResolver() const;

  /**
   * Returns the internal list of resolved results for the local address.
   */
  const KResolverResults& localResults() const;

  /**
   * Enables or disables name resolution. If this flag is set to true,
   * @ref bind and @ref connect operations will trigger name lookup
   * operations (i.e., converting a hostname into its binary form).
   * If the flag is set to false, those operations will instead
   * try to convert a string representation of an address without
   * attempting name resolution.
   *
   * This is useful, for instance, when IP addresses are in
   * their string representation (such as "1.2.3.4") or come
   * from other sources like @ref TDESocketAddress.
   *
   * @param enable	whether to enable
   */
  void setResolutionEnabled(bool enable);

  /**
   * Sets the allowed families for the resolutions.
   *
   * @param families		the families that we want/accept
   * @see KResolver::SocketFamilies for possible values
   */
  void setFamily(int families);

  /**
   * Starts the lookup for peer and local hostnames as
   * well as their services.
   *
   * If the blocking mode for this object is on, this function will
   * wait for the lookup results to be available (by calling the 
   * @ref KResolver::wait method on the resolver objects).
   *
   * When the lookup is done, the signal @ref hostFound will be
   * emitted (only once, even if we're doing a double lookup).
   * If the lookup failed (for any of the two lookups) the 
   * @ref gotError signal will be emitted with the appropriate
   * error condition (see @ref TDESocketBase::SocketError).
   *
   * This function returns true on success and false on error. Note that
   * this is not the lookup result!
   */
  virtual bool lookup();

  /**
   * Binds this socket to the given nodename and service,
   * or use the default ones if none are given.
   *
   * Upon successful binding, the @ref bound signal will be
   * emitted. If an error is found, the @ref gotError
   * signal will be emitted.
   *
   * @note Due to the internals of the name lookup and binding
   *       mechanism, some (if not most) implementations of this function
   *       do not actually bind the socket until the connection
   *       is requested (see @ref connect). They only set the values
   *       for future reference.
   *
   * This function returns true on success.
   *
   * @param node	the nodename
   * @param service	the service
   */
  virtual bool bind(const TQString& node = TQString::null,
		    const TQString& service = TQString::null) = 0;

  /**
   * Reimplemented from TDESocketBase. Connect this socket to this
   * specific address.
   *
   * Unlike @ref bind(const TQString&, const TQString&) above, this function
   * really does bind the socket. No lookup is performed. The @ref bound
   * signal will be emitted.
   */
  virtual bool bind(const KResolverEntry& address);

  /**
   * Attempts to connect to the these hostname and service,
   * or use the default ones if none are given. If a connection attempt
   * is already in progress, check on its state and set the error status
   * (NoError or InProgress).
   *
   * If the blocking mode for this object is on, this function will only
   * return when all the resolved peer addresses have been tried or when
   * a connection is established.
   *
   * Upon successfully connecting, the @ref connected signal 
   * will be emitted. If an error is found, the @ref gotError
   * signal will be emitted.
   *
   * @par Note for derived classes:
   *      Derived classes must implement this function. The implementation
   *      will set the parameters for the lookup (using the peer KResolver
   *      object) and call @ref lookup to start it.
   *
   * @par
   *      The implementation should use the @ref hostFound
   *      signal to be notified of the completion of the lookup process and
   *      then proceed to start the connection itself. Care should be taken
   *      regarding the value of @ref blocking flag.
   *
   * @param node	the nodename
   * @param service	the service
   */
  virtual bool connect(const TQString& node = TQString::null,
		       const TQString& service = TQString::null) = 0;

  /**
   * @overload
   * Reimplemented from TDESocketBase.
   */
  virtual bool connect(const KResolverEntry& address);

  /**
   * @deprecated
   * This is a convenience function provided to ease migrating from
   * Qt 3.x's TQSocket class.
   */
  inline void connectToHost(const TQString& host, TQ_UINT16 port)
  { connect(host, TQString::number(port)); }

  /**
   * Disconnects the socket.
   * Note that not all socket types can disconnect.
   */
  virtual bool disconnect();

  /**
   * Opens the socket. Reimplemented from TQIODevice.
   *
   * You should not call this function; instead, use @ref connect
   */
  virtual inline bool open(TQ_OpenMode)
  { return connect(); }

  /**
   * Closes the socket. Reimplemented from TQIODevice.
   *
   * The closing of the socket causes the emission of the
   * signal @ref closed.
   */
  virtual void close();

  /**
   * This call is not supported on sockets. Reimplemented from TQIODevice.
   */
  virtual void flush()
  { }

  /**
   * Returns the number of bytes available on this socket.
   * Reimplemented from TDESocketBase.
   */
#ifdef USE_QT3
  virtual TQ_LONG bytesAvailable() const;
#endif
#ifdef USE_QT4
  virtual qint64 bytesAvailable() const;
#endif

  /**
   * Waits for more data. Reimplemented from TDESocketBase.
   */
  virtual TQ_LONG waitForMore(int msecs, bool *timeout = 0L);

  /**
   * Reads data from a socket. Reimplemented from TDESocketBase.
   */
  virtual TQT_TQIO_LONG tqreadBlock(char *data, TQT_TQIO_ULONG maxlen);

  /**
   * @overload
   * Reads data from a socket. Reimplemented from TDESocketBase.
   */
  virtual TQT_TQIO_LONG tqreadBlock(char *data, TQT_TQIO_ULONG maxlen, TDESocketAddress& from);

  /**
   * Peeks data from the socket. Reimplemented from TDESocketBase.
   */
  virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen);

  /**
   * @overload
   * Peeks data from the socket. Reimplemented from TDESocketBase.
   */
  virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen, TDESocketAddress &from);

  /**
   * Writes data to the socket. Reimplemented from TDESocketBase.
   */
  virtual TQT_TQIO_LONG tqwriteBlock(const char *data, TQT_TQIO_ULONG len);

  /**
   * @overload
   * Writes data to the socket. Reimplemented from TDESocketBase.
   */
  virtual TQT_TQIO_LONG tqwriteBlock(const char *data, TQT_TQIO_ULONG len, const TDESocketAddress& to);

  /**
   * Returns the local socket address. Reimplemented from TDESocketBase.
   */
  virtual TDESocketAddress localAddress() const;

  /**
   * Returns the peer socket address. Reimplemented from TDESocketBase.
   */
  virtual TDESocketAddress peerAddress() const;

  /**
   * Returns true if the readyRead signal is set to be emitted.
   */
  bool emitsReadyRead() const;

  /**
   * Enables the emission of the readyRead signal.
   * By default, this signal is enabled.
   *
   * @param enable	whether to enable the signal
   */
  virtual void enableRead(bool enable);

  /**
   * Returns true if the readyWrite signal is set to be emitted.
   */
  bool emitsReadyWrite() const;

  /**
   * Enables the emission of the readyWrite signal.
   * By default, this signal is disabled.
   *
   * @param enable	whether to enable the signal
   */
  virtual void enableWrite(bool enable);

protected slots:
  // protected slots

  /**
   * This slot is connected to the read notifier's signal meaning
   * the socket can read more data. 
   *
   * The default implementation only emits the readyRead signal.
   *
   * Override if your class requires processing of incoming
   * data.
   */
  virtual void slotReadActivity();

  /**
   * This slot is connected to the write notifier's signal
   * meaning the socket can write more data.
   *
   * The default implementation only emits the readyWrite signal.
   *
   * Override if your class writes data from another source
   * (like a buffer).
   */
  virtual void slotWriteActivity();

private slots:
  void lookupFinishedSlot();

signals:
  /**
   * This signal is emitted whenever the socket state changes.
   *
   * Note: do not delete this object inside the slot called by this
   * signal.
   *
   * @param newstate	the new state of the socket object
   */
  void stateChanged(int newstate);

  /**
   * This signal is emitted when this object finds an error.
   * The @p code parameter contains the error code that can
   * also be found by calling @ref error.
   */
  void gotError(int code);

  /**
   * This signal is emitted when the lookup is successfully completed.
   */
  void hostFound();

  /**
   * This signal is emitted when the socket successfully binds
   * to an address.
   *
   * @param local	the local address we bound to
   */
  void bound(const KResolverEntry& local);

  /**
   * This signal is emitted when the socket is about to connect
   * to an address (but before doing so).
   * 
   * The @p skip parameter can be used to make the loop skip this address.
   * Its value is initially false: change it to true if you want to
   * skip the current address (as given by @p remote).
   *
   * This function is also useful if one wants to reset the timeout.
   *
   * @param remote	the address we're about to connect to
   * @param skip	set to true if you want to skip this address
   * @note if the connection is successful, the @ref connected signal will be
   *       emitted.
   */
  void aboutToConnect(const KResolverEntry& remote, bool& skip);

  /**
   * This socket is emitted when the socket successfully connects
   * to a remote address.
   *
   * @param remote	the remote address we did connect to
   */
  void connected(const KResolverEntry& remote);

  /**
   * This signal is emitted when the socket completes the
   * closing/shut down process.
   */
  void closed();

  /**
   * This signal is emitted whenever the socket is ready for
   * reading -- i.e., there is data to be read in the buffers.
   * The subsequent read operation is guaranteed to be non-blocking.
   *
   * You can toggle the emission of this signal with the @ref enableRead
   * function. This signal is by default enabled.
   */
  void readyRead();

  /**
   * This signal is emitted whenever the socket is ready for 
   * writing -- i.e., whenever there's space available in the buffers
   * to receive more data. The subsequent write operation is
   * guaranteed to be non-blocking.
   *
   * You can toggle the emission of this signal with the @ref enableWrite
   * function. This signal is by default disabled. You will
   * want to disable this signal after the first reception, since
   * it'll probably fire at every event loop.
   */
  void readyWrite();

protected:
  /**
   * Sets the socket state to @p state. This function does not
   * emit the @ref stateChanged signal.
   */
  void setState(SocketState state);

  /**
   * This function is called by @ref setState whenever the state
   * changes. You should override it if you need to specify any
   * actions to be done when the state changes.
   *
   * The default implementation acts for these states only:
   *  - Connected: it sets up the socket notifiers to fire readyRead and 
   *               readyWrite signals.
   */
  virtual void stateChanging(SocketState newState);

  /**
   * Convenience function to set this object's error code to match
   * that of the socket device.
   */
  void copyError();

private:
  KClientSocketBase(const KClientSocketBase&);
  KClientSocketBase& operator=(const KClientSocketBase&);

  KClientSocketBasePrivate *d;
};

}				// namespace KNetwork

#endif