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 | |
35 | namespace KNetwork { |
36 | |
37 | class 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 | */ |
50 | class KDECORE_EXPORT_DEPRECATED KClientSocketBase : public KActiveSocketBase |
51 | { |
52 | Q_OBJECT |
53 | |
54 | public: |
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 | |
87 | public: |
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 | |
106 | protected: |
107 | /** |
108 | * Sets the socket options. Reimplemented from KSocketBase. |
109 | */ |
110 | virtual bool setSocketOptions(int opts); |
111 | |
112 | public: |
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 | |
332 | protected 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 | |
357 | private Q_SLOTS: |
358 | void lookupFinishedSlot(); |
359 | |
360 | Q_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 | |
448 | protected: |
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 | |
488 | private: |
489 | KClientSocketBase(const KClientSocketBase&); |
490 | KClientSocketBase& operator=(const KClientSocketBase&); |
491 | |
492 | KClientSocketBasePrivate* const d; |
493 | }; |
494 | |
495 | } // namespace KNetwork |
496 | |
497 | #endif |
498 | |