summaryrefslogtreecommitdiffstats
path: root/tdecore/network/kstreamsocket.h
blob: 94396b38d484b12d5be99b14c9cd083db6cbd906 (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
/*
 *  Copyright (C) 2003 Thiago Macieira <thiago@kde.org>
 *
 *
 *  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 KSTREAMSOCKET_H
#define KSTREAMSOCKET_H

#include <tqstring.h>

#include "kclientsocketbase.h"

/** A namespace to store all networking-related (socket) classes. */
namespace KNetwork {

class KResolverEntry;
class KResolverResults;
class TDEServerSocket;
class TDEBufferedSocket;

class KStreamSocketPrivate;
/** @class KStreamSocket kstreamsocket.h kstreamsocket.h
 *  @brief Simple stream socket
 *
 * This class provides functionality to creating unbuffered, stream
 * sockets. In the case of Internet (IP) sockets, this class creates and
 * uses TCP/IP sockets.
 *
 * Objects of this class start, by default, on non-blocking mode. Call
 * setBlocking if you wish to change that.
 *
 * KStreamSocket objects are thread-safe and can be used in auxiliary
 * threads (i.e., not the thread in which the Qt event loop runs in).
 * Note that TDEBufferedSocket cannot be used reliably in an auxiliary thread.
 *
 * Sample usage:
 * \code
 *   TQByteArray httpGet(const TQString& hostname)
 *   {
 *     KStreamSocket socket(hostname, "http");
 *     if (!socket.connect())
 *       return TQByteArray();
 *     TQByteArray data = socket.readAll();
 *     return data;
 *   }
 * \endcode
 *
 * Here's another sample, showing asynchronous operation:
 * \code
 *  DataRetriever::DataRetriever(const TQString& hostname, const TQString& port)
 *    : socket(hostname, port)
 *  {
 *    // connect signals to our slots
 *    TQObject::connect(&socket, TQT_SIGNAL(connected(const KResolverEntry&)),
 *                     this, TQT_SLOT(slotSocketConnected()));
 *    TQObject::connect(&socket, TQT_SIGNAL(gotError(int)),
 *                     this, TQT_SLOT(slotSocketError(int)));
 *    TQObject::connect(&socket, TQT_SIGNAL(readyRead()),
 *                     this, TQT_SLOT(slotSocketReadyToRead()));
 *    TQObject::connect(&socket, TQT_SIGNAL(readyWrite()),
 *                     this, TQT_SLOT(slotSocketReadyToWrite()));
 *
 *    // set non-blocking mode in order to work asynchronously
 *    socket.setBlocking(false);
 *
 *    // turn on signal emission
 *    socket.enableRead(true);
 *    socket.enableWrite(true);
 *
 *    // start connecting
 *    socket.connect();
 *  }
 * \endcode
 *
 * @see KNetwork::TDEBufferedSocket, KNetwork::TDEServerSocket
 * @author Thiago Macieira <thiago@kde.org>
 */
class TDECORE_EXPORT KStreamSocket: public KClientSocketBase
{
  Q_OBJECT
  

public:
  /**
   * Default constructor.
   *
   * @param node	destination host
   * @param service	destination service to connect to
   * @param parent	the parent TQObject object
   * @param name        name for this object
   */
  KStreamSocket(const TQString& node = TQString::null, const TQString& service = TQString::null,
		TQObject* parent = 0L, const char *name = 0L);

  /**
   * Destructor. This closes the socket.
   */
  virtual ~KStreamSocket();

  /**
   * Retrieves the timeout value (in milliseconds).
   */
  int timeout() const;

  /**
   * Retrieves the remaining timeout time (in milliseconds). This value
   * equals @ref timeout() if there's no connection in progress.
   */
  int remainingTimeout() const;

  /**
   * Sets the timeout value. Setting this value while a connection attempt
   * is in progress will reset the timer.
   *
   * Please note that the timeout value is valid for the connection attempt
   * only. No other operations are timed against this value -- including the
   * name lookup associated.
   *
   * @param msecs		the timeout value in milliseconds
   */
  void setTimeout(int msecs);

  /**
   * Binds this socket to the given nodename and service,
   * or use the default ones if none are given. In order to bind to a service
   * and allow the operating system to choose the interface, set @p node to
   * TQString::null.
   * 
   * Reimplemented from KClientSocketBase.
   *
   * 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);

  /**
   * Reimplemented from KClientSocketBase. 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& entry)
  { return KClientSocketBase::bind(entry); }

  /**
   * Reimplemented from KClientSocketBase.
   *
   * 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, meaning the connection is completed, 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.
   *
   * This function also implements timeout handling.
   *
   * @param node	the remote node to connect to
   * @param service	the service on the remote node to connect to
   */
  virtual bool connect(const TQString& node = TQString::null,
		       const TQString& service = TQString::null);

  /**
   * Unshadowing from KClientSocketBase.
   */
  virtual bool connect(const KResolverEntry& entry);

signals:
  /**
   * This signal is emitted when a connection timeout occurs.
   */
  void timedOut();

private slots:
  void hostFoundSlot();
  void connectionEvent();
  void timeoutSlot();

private:
  /**
   * @internal
   * If the user requested local bind before connection, bind the socket to one
   * suitable address and return true. Also sets d->local to the address used.
   *
   * Return false in case of error.
   */
  bool bindLocallyFor(const KResolverEntry& peer);

  /**
   * @internal
   * Finishes the connection process by setting internal values and
   * emitting the proper signals.
   *
   * Note: assumes d->local iterator points to the address that we bound
   * to.
   */
  void connectionSucceeded(const KResolverEntry& peer);

  KStreamSocket(const KStreamSocket&);
  KStreamSocket& operator=(const KStreamSocket&);

  KStreamSocketPrivate *d;

  friend class TDEServerSocket;
  friend class TDEBufferedSocket;
};

} 				// namespace KNetwork

#endif