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 KSERVERSOCKET_H
26#define KSERVERSOCKET_H
27
28#include <QtCore/QObject>
29#include "k3socketbase.h"
30#include "k3streamsocket.h"
31
32namespace KNetwork {
33
34class KStreamSocket;
35class KResolver;
36class KResolverResults;
37
38class KServerSocketPrivate;
39/**
40 * @class KServerSocket k3serversocket.h k3serversocket.h
41 * @brief A server socket for accepting connections.
42 *
43 * This class provides functionality for creating a socket to
44 * listen for incoming connections and subsequently accept them.
45 *
46 * To use this class, you must first set the parameters for the listening
47 * socket's address, then place it in listening mode.
48 *
49 * A typical example would look like:
50 * \code
51 * QString service = "http";
52 * KServerSocket *ss = new KServerSocket(service);
53 * connect(ss, SIGNAL(readyAccept()), this, SLOT(slotReadyAccept()));
54 * connect(ss, SIGNAL(gotError(int)), this, SLOT(slotSocketError(int)));
55 * ss->listen();
56 * \endcode
57 *
58 * In this case, this class will place the socket into listening mode on the
59 * service pointed to by @p service and will emit the readyAccept() signal
60 * when a connection is ready for accepting. The called slot is responsible for
61 * calling accept().
62 *
63 * The location of the services file (where @p service is looked up)
64 * is defined by _PATH_SERVICES in /usr/include/netdb.h. This is
65 * usually set to /etc/services.
66 * See RFC 1700 for more information on services.
67 * You can specify @p service as a port number directly, rather than as a service
68 * name. This is discouraged as it prevents the end user from easily modifying
69 * the port number.
70 *
71 * For another example of usage, this below code attempts to make a connection on any port within a range:
72 * \code
73 * KServerSocket *ss = new KServerSocket();
74 * ss->setFamily(KResolver::InetFamily);
75 * bool found = false;
76 * for( unsigned int port = firstport; port <= lastport; ++port) {
77 * ss->setAddress( QString::number( port ) );
78 * bool success = ss->listen();
79 * if( found = ( success && ss->error() ==
80 * KSocketBase::NoError ) )
81 * break;
82 * ss->close();
83 * }
84 * if( !found ) {
85 * // Couldn't connect to any port.
86 * } else {
87 * connect(ss, SIGNAL(readyAccept()), this, SLOT(slotReadyAccept()));
88 * connect(ss, SIGNAL(gotError(int)), this, SLOT(slotSocketError(int)));
89 * ss->listen();
90 * }
91 * \endcode
92 *
93 * The called slot slotReadyAccept() is responsible for calling
94 * accept().
95 *
96 * It is important to note that accept() can return either an
97 * object of type KNetwork::KStreamSocket or
98 * KNetwork::KBufferedSocket (default). If you want to accept a
99 * non-buffered socket, you must first call setAcceptBuffered.
100 *
101 * @warning If you use KServerSocket in an auxiliary (non-GUI) thread,
102 * you need to accept only KNetwork::KStreamSocket objects.
103 *
104 * @see KNetwork::KStreamSocket, KNetwork::KBufferedSocket
105 * @author Thiago Macieira <thiago@kde.org>
106 * @deprecated Use KSocketFactory or KLocalSocket instead
107 */
108class KDECORE_EXPORT_DEPRECATED KServerSocket: public QObject, public KPassiveSocketBase
109{
110 Q_OBJECT
111public:
112 /**
113 * Default constructor.
114 *
115 * If the binding address isn't changed by setAddress, this socket will
116 * bind to all interfaces on this node and the port will be selected by the
117 * operating system.
118 *
119 * @param parent the parent QObject object
120 */
121 KServerSocket(QObject* parent = 0L);
122
123 /**
124 * Construct this object specifying the service to listen on.
125 *
126 * If the binding address isn't changed by setAddress, this socket will
127 * bind to all interfaces and will listen on the port specified by
128 * @p service. This is either a service name (e.g. 'www') or a port
129 * number (e.g. '80').
130 *
131 * The location of the services file (where @p service is looked up)
132 * is defined by _PATH_SERVICES in /usr/include/netdb.h. This is
133 * usually set to /etc/services.
134 * See RFC 1700 for more information on services.
135 *
136 * @param service the service name to listen on
137 * @param parent the parent QObject object
138 */
139 explicit KServerSocket(const QString& service, QObject* parent = 0L);
140
141 /**
142 * Construct this object specifying the node and service names to listen on.
143 *
144 * If the binding address isn't changed by setAddress, this socket will
145 * bind to the interface specified by @p node and the port specified by
146 * @p service. This is either a service name (e.g. 'www') or a port
147 * number (e.g. '80').
148 *
149 * The location of the services file (where @p service is looked up)
150 * is defined by _PATH_SERVICES in /usr/include/netdb.h. This is
151 * usually set to /etc/services.
152 * See RFC 1700 for more information on services.
153 *
154 * @param node the node to bind to
155 * @param service the service port to listen on
156 * @param parent the parent QObject object
157 */
158 KServerSocket(const QString& node, const QString& service,
159 QObject* parent = 0L);
160
161 /**
162 * Destructor. This will close the socket, if open.
163 *
164 * Note, however, that accepted sockets do not get closed when this
165 * object closes.
166 */
167 ~KServerSocket();
168
169protected:
170 /**
171 * Sets the socket options. Reimplemented from KSocketBase.
172 */
173 virtual bool setSocketOptions(int opts);
174
175public:
176 /**
177 * Returns the internal KResolver object used for
178 * looking up the host name and service.
179 *
180 * This can be used to set extra options to the
181 * lookup process other than the default values, as well
182 * as obtaining the error codes in case of lookup failure.
183 */
184 KResolver& resolver() const;
185
186 /**
187 * Returns the internal list of resolved results for the binding address.
188 */
189 const KResolverResults& resolverResults() const;
190
191 /**
192 * Enables or disables name resolution. If this flag is set to true,
193 * the bind() operation will trigger name lookup
194 * operations (i.e., converting a hostname into its binary form).
195 * If the flag is set to false, those operations will instead
196 * try to convert a string representation of an address without
197 * attempting name resolution.
198 *
199 * This is useful, for instance, when IP addresses are in
200 * their string representation (such as "1.2.3.4") or come
201 * from other sources like KSocketAddress.
202 *
203 * @param enable whether to enable
204 */
205 void setResolutionEnabled(bool enable);
206
207 /**
208 * Sets the allowed families for the resolutions.
209 *
210 * @param families the families that we want/accept
211 * @see KResolver::SocketFamilies for possible values
212 */
213 void setFamily(int families);
214
215 /**
216 * Sets the address on which we will listen. The port to listen on is given by
217 * @p service, and we will bind to all interfaces. To let the operating system choose a
218 * port, set the service to "0". @p service can either be a service name
219 * (e.g. 'www') or a port number (e.g. '80').
220 *
221 * The location of the services file (where @p service is looked up)
222 * is defined by _PATH_SERVICES in /usr/include/netdb.h. This is
223 * usually set to /etc/services.
224 * See RFC 1700 for more information on services.
225 *
226 * @param service the service name to listen on
227 */
228 void setAddress(const QString& service);
229
230 /**
231 * @overload
232 * Sets the address on which we will listen. This will cause the socket to listen
233 * only on the interface given by @p node and on the port given by @p service.
234 * @p service can either be a service name (e.g. 'www') or a port number
235 * (e.g. '80').
236 *
237 * The location of the services file (where @p service is looked up)
238 * is defined by _PATH_SERVICES in /usr/include/netdb.h. This is
239 * usually set to /etc/services.
240 * See RFC 1700 for more information on services.
241 *
242 * @param node the node to bind to
243 * @param service the service port to listen on
244 */
245 void setAddress(const QString& node, const QString& service);
246
247 /**
248 * Sets the timeout for accepting. When you call accept(),
249 * it will wait at most @p msecs milliseconds or return with an error
250 * (returning a NULL object).
251 *
252 * @param msecs the time in milliseconds to wait, 0 to wait forever
253 */
254 void setTimeout(int msecs);
255
256 /**
257 * Starts the lookup for peer and local hostnames as
258 * well as their services.
259 *
260 * If the blocking mode for this object is on, this function will
261 * wait for the lookup results to be available (by calling the
262 * KResolver::wait() method on the resolver objects).
263 *
264 * When the lookup is done, the signal hostFound() will be
265 * emitted (only once, even if we're doing a double lookup).
266 * If the lookup failed (for any of the two lookups) the
267 * gotError() signal will be emitted with the appropriate
268 * error condition (see KSocketBase::SocketError).
269 *
270 * This function returns true on success and false on error. Note that
271 * this is not the lookup result!
272 */
273 virtual bool lookup();
274
275 /**
276 * Binds this socket to the given nodename and service,
277 * or use the default ones if none are given.
278 *
279 * Upon successful binding, the bound() signal will be
280 * emitted. If an error is found, the gotError()
281 * signal will be emitted.
282 *
283 * This function returns true on success.
284 *
285 * @param node the nodename
286 * @param service the service
287 */
288 virtual bool bind(const QString& node, const QString& service);
289
290 /**
291 * Binds the socket to the given service name.
292 * @overload
293 *
294 * @param service the service
295 */
296 virtual bool bind(const QString& service);
297
298 /**
299 * Binds the socket to the addresses previously set with setAddress().
300 * @overload
301 *
302 */
303 virtual bool bind();
304
305 /**
306 * Connect this socket to this specific address. Reimplemented from KSocketBase.
307 *
308 * Unlike bind(const QString&, const QString&) above, this function
309 * really does bind the socket. No lookup is performed. The bound() signal
310 * will be emitted.
311 */
312 virtual bool bind(const KResolverEntry& address);
313
314 /**
315 * Puts this socket into listening mode. Reimplemented from KPassiveSocketBase.
316 *
317 * Placing a socket into listening mode means it will be able to receive incoming
318 * connections through the accept() method.
319 *
320 * If you do not call this method but call accept() directly, the socket will
321 * be placed into listening mode automatically.
322 *
323 * @param backlog the number of connection the system is to
324 * queue without accept() being called
325 * @returns true if the socket is now in listening mode.
326 */
327 virtual bool listen(int backlog = 5); // 5 is arbitrary
328
329 /**
330 * Closes this socket.
331 */
332 virtual void close();
333
334 /**
335 * Toggles whether the accepted socket will be buffered or not.
336 * That is, the accept() function will always return a KStreamSocket
337 * object or descended from it. If buffering is enabled, the class
338 * to be returned will be KBufferedSocket.
339 *
340 * By default, this flag is set to true.
341 *
342 * @param enable whether to set the accepted socket to
343 * buffered mode
344 */
345 void setAcceptBuffered(bool enable);
346
347 /**
348 * Accepts one incoming connection and return the associated, open
349 * socket.
350 *
351 * If this function cannot accept a new connection, it will return NULL.
352 * The specific object class returned by this function may vary according
353 * to the implementation: derived classes may return specialized objects
354 * descended from KStreamSocket.
355 *
356 * @sa KBufferedSocket
357 * @sa setAcceptBuffered
358 */
359 virtual KStreamSocket* accept();
360
361 /**
362 * Returns this socket's local address.
363 */
364 virtual KSocketAddress localAddress() const;
365
366 /**
367 * Returns this socket's externally-visible address if know.
368 */
369 virtual KSocketAddress externalAddress() const;
370
371private Q_SLOTS:
372 void lookupFinishedSlot();
373
374Q_SIGNALS:
375 /**
376 * This signal is emitted when this object finds an error.
377 * The @p code parameter contains the error code that can
378 * also be found by calling error().
379 */
380 void gotError(int code);
381
382 /**
383 * This signal is emitted when the lookup is successfully completed.
384 */
385 void hostFound();
386
387 /**
388 * This signal is emitted when the socket successfully binds
389 * to an address.
390 *
391 * @param local the local address we bound to
392 */
393 void bound(const KNetwork::KResolverEntry& local);
394
395 /**
396 * This signal is emitted when the socket completes the
397 * closing/shut down process.
398 */
399 void closed();
400
401 /**
402 * This signal is emitted whenever the socket is ready for
403 * accepting -- i.e., there is at least one connection waiting to
404 * be accepted.
405 */
406 void readyAccept();
407
408protected:
409 /**
410 * Convenience function to set this object's error code to match
411 * that of the socket device.
412 */
413 void copyError();
414
415private:
416 bool doBind();
417 bool doListen();
418
419private:
420 KServerSocket(const KServerSocket&);
421 KServerSocket& operator=(const KServerSocket&);
422
423 KServerSocketPrivate* const d;
424};
425
426} // namespace KNetwork
427
428#endif
429