source: trunk/src/network/socket/qlocalserver.cpp@ 651

Last change on this file since 651 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 11.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtNetwork module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qlocalserver.h"
43#include "qlocalserver_p.h"
44#include "qlocalsocket.h"
45
46QT_BEGIN_NAMESPACE
47
48#ifndef QT_NO_LOCALSERVER
49
50/*!
51 \class QLocalServer
52 \since 4.4
53
54 \brief The QLocalServer class provides a local socket based server.
55
56 This class makes it possible to accept incoming local socket
57 connections.
58
59 Call listen() to have the server start listening
60 for incoming connections on a specified key. The
61 newConnection() signal is then emitted each time a client
62 connects to the server.
63
64 Call nextPendingConnection() to accept the pending connection
65 as a connected QLocalSocket. The function returns a pointer to a
66 QLocalSocket that can be used for communicating with the client.
67
68 If an error occurs, serverError() returns the type of error, and
69 errorString() can be called to get a human readable description
70 of what happened.
71
72 When listening for connections, the name which the server is
73 listening on is available through serverName().
74
75 Calling close() makes QLocalServer stop listening for incoming connections.
76
77 Although QLocalServer is designed for use with an event loop, it's possible
78 to use it without one. In that case, you must use waitForNewConnection(),
79 which blocks until either a connection is available or a timeout expires.
80
81 \sa QLocalSocket, QTcpServer
82*/
83
84/*!
85 Create a new local socket server with the given \a parent.
86
87 \sa listen()
88 */
89QLocalServer::QLocalServer(QObject *parent)
90 : QObject(*new QLocalServerPrivate, parent)
91{
92 Q_D(QLocalServer);
93 d->init();
94}
95
96/*!
97 Destroys the QLocalServer object. If the server is listening for
98 connections, it is automatically closed.
99
100 Any client QLocalSockets that are still connected must either
101 disconnect or be reparented before the server is deleted.
102
103 \sa close()
104 */
105QLocalServer::~QLocalServer()
106{
107 if (isListening())
108 close();
109}
110
111/*!
112 Stop listening for incoming connections. Existing connections are not
113 effected, but any new connections will be refused.
114
115 \sa isListening(), listen()
116 */
117void QLocalServer::close()
118{
119 Q_D(QLocalServer);
120 if (!isListening())
121 return;
122 qDeleteAll(d->pendingConnections);
123 d->pendingConnections.clear();
124 d->closeServer();
125 d->serverName = QString();
126 d->fullServerName = QString();
127 d->errorString = QString();
128 d->error = QAbstractSocket::UnknownSocketError;
129}
130
131/*!
132 Returns the human-readable message appropriate to the current error
133 reported by serverError(). If no suitable string is available, an empty
134 string is returned.
135
136 \sa serverError()
137 */
138QString QLocalServer::errorString() const
139{
140 Q_D(const QLocalServer);
141 return d->errorString;
142}
143
144/*!
145 Returns true if the server has a pending connection; otherwise
146 returns false.
147
148 \sa nextPendingConnection(), setMaxPendingConnections()
149 */
150bool QLocalServer::hasPendingConnections() const
151{
152 Q_D(const QLocalServer);
153 return !(d->pendingConnections.isEmpty());
154}
155
156/*!
157 This virtual function is called by QLocalServer when a new connection
158 is available. \a socketDescriptor is the native socket descriptor for
159 the accepted connection.
160
161 The base implementation creates a QLocalSocket, sets the socket descriptor
162 and then stores the QLocalSocket in an internal list of pending
163 connections. Finally newConnection() is emitted.
164
165 Reimplement this function to alter the server's behavior
166 when a connection is available.
167
168 \sa newConnection(), nextPendingConnection(),
169 QLocalSocket::setSocketDescriptor()
170 */
171void QLocalServer::incomingConnection(quintptr socketDescriptor)
172{
173 Q_D(QLocalServer);
174 QLocalSocket *socket = new QLocalSocket(this);
175 socket->setSocketDescriptor(socketDescriptor);
176 d->pendingConnections.enqueue(socket);
177 emit newConnection();
178}
179
180/*!
181 Returns true if the server is listening for incoming connections
182 otherwise false.
183
184 \sa listen(), close()
185 */
186bool QLocalServer::isListening() const
187{
188 Q_D(const QLocalServer);
189 return !(d->serverName.isEmpty());
190}
191
192/*!
193 Tells the server to listen for incoming connections on \a name.
194 If the server is currently listening then it will return false.
195 Return true on success otherwise false.
196
197 \a name can be a single name and QLocalServer will determine
198 the correct platform specific path. serverName() will return
199 the name that is passed into listen.
200
201 Usually you would just pass in a name like "foo", but on Unix this
202 could also be a path such as "/tmp/foo" and on Windows this could
203 be a pipe path such as "\\\\.\\pipe\\foo"
204
205 Note:
206 On Unix if the server crashes without closing listen will fail
207 with AddressInUseError. To create a new server the file should be removed.
208 On Windows two local servers can listen to the same pipe at the same
209 time, but any connections will go to one of the server.
210
211 \sa serverName(), isListening(), close()
212 */
213bool QLocalServer::listen(const QString &name)
214{
215 Q_D(QLocalServer);
216 if (isListening()) {
217 qWarning("QLocalServer::listen() called when already listening");
218 return false;
219 }
220
221 if (name.isEmpty()) {
222 d->error = QAbstractSocket::HostNotFoundError;
223 QString function = QLatin1String("QLocalServer::listen");
224 d->errorString = tr("%1: Name error").arg(function);
225 return false;
226 }
227
228 if (!d->listen(name)) {
229 d->serverName = QString();
230 d->fullServerName = QString();
231 return false;
232 }
233
234 d->serverName = name;
235 return true;
236}
237
238/*!
239 Returns the maximum number of pending accepted connections.
240 The default is 30.
241
242 \sa setMaxPendingConnections(), hasPendingConnections()
243 */
244int QLocalServer::maxPendingConnections() const
245{
246 Q_D(const QLocalServer);
247 return d->maxPendingConnections;
248}
249
250/*!
251 \fn void QLocalServer::newConnection()
252
253 This signal is emitted every time a new connection is available.
254
255 \sa hasPendingConnections(), nextPendingConnection()
256*/
257
258/*!
259 Returns the next pending connection as a connected QLocalSocket object.
260
261 The socket is created as a child of the server, which means that it is
262 automatically deleted when the QLocalServer object is destroyed. It is
263 still a good idea to delete the object explicitly when you are done with
264 it, to avoid wasting memory.
265
266 0 is returned if this function is called when there are no pending
267 connections.
268
269 \sa hasPendingConnections(), newConnection(), incomingConnection()
270 */
271QLocalSocket *QLocalServer::nextPendingConnection()
272{
273 Q_D(QLocalServer);
274 if (d->pendingConnections.isEmpty())
275 return 0;
276 QLocalSocket *nextSocket = d->pendingConnections.dequeue();
277#ifdef Q_OS_SYMBIAN
278 if(!d->socketNotifier)
279 return nextSocket;
280#endif
281#ifndef QT_LOCALSOCKET_TCP
282 if (d->pendingConnections.size() <= d->maxPendingConnections)
283#ifndef Q_OS_WIN
284 d->socketNotifier->setEnabled(true);
285#else
286 d->connectionEventNotifier->setEnabled(true);
287#endif
288#endif
289 return nextSocket;
290}
291
292/*!
293 \since 4.5
294
295 Removes any server instance that might cause a call to listen() to fail
296 and returns true if successful; otherwise returns false.
297 This function is meant to recover from a crash, when the previous server
298 instance has not been cleaned up.
299
300 On Windows, this function does nothing; on Unix, it removes the socket file
301 given by \a name.
302
303 \warning Be careful to avoid removing sockets of running instances.
304*/
305bool QLocalServer::removeServer(const QString &name)
306{
307 return QLocalServerPrivate::removeServer(name);
308}
309
310/*!
311 Returns the server name if the server is listening for connections;
312 otherwise returns QString()
313
314 \sa listen(), fullServerName()
315 */
316QString QLocalServer::serverName() const
317{
318 Q_D(const QLocalServer);
319 return d->serverName;
320}
321
322/*!
323 Returns the full path that the server is listening on.
324
325 Note: This is platform specific
326
327 \sa listen(), serverName()
328 */
329QString QLocalServer::fullServerName() const
330{
331 Q_D(const QLocalServer);
332 return d->fullServerName;
333}
334
335/*!
336 Returns the type of error that occurred last or NoError.
337
338 \sa errorString()
339 */
340QAbstractSocket::SocketError QLocalServer::serverError() const
341{
342 Q_D(const QLocalServer);
343 return d->error;
344}
345
346/*!
347 Sets the maximum number of pending accepted connections to
348 \a numConnections. QLocalServer will accept no more than
349 \a numConnections incoming connections before nextPendingConnection()
350 is called.
351
352 Note: Even though QLocalServer will stop accepting new connections
353 after it has reached its maximum number of pending connections,
354 the operating system may still keep them in queue which will result
355 in clients signaling that it is connected.
356
357 \sa maxPendingConnections(), hasPendingConnections()
358 */
359void QLocalServer::setMaxPendingConnections(int numConnections)
360{
361 Q_D(QLocalServer);
362 d->maxPendingConnections = numConnections;
363}
364
365/*!
366 Waits for at most \a msec milliseconds or until an incoming connection
367 is available. Returns true if a connection is available; otherwise
368 returns false. If the operation timed out and \a timedOut is not 0,
369 *timedOut will be set to true.
370
371 This is a blocking function call. Its use is ill-advised in a
372 single-threaded GUI application, since the whole application will stop
373 responding until the function returns. waitForNewConnection() is mostly
374 useful when there is no event loop available.
375
376 The non-blocking alternative is to connect to the newConnection() signal.
377
378 If msec is -1, this function will not time out.
379
380 \sa hasPendingConnections(), nextPendingConnection()
381 */
382bool QLocalServer::waitForNewConnection(int msec, bool *timedOut)
383{
384 Q_D(QLocalServer);
385 if (timedOut)
386 *timedOut = false;
387
388 if (!isListening())
389 return false;
390
391 d->waitForNewConnection(msec, timedOut);
392
393 return !d->pendingConnections.isEmpty();
394}
395
396#endif
397
398QT_END_NAMESPACE
399
400#include "moc_qlocalserver.cpp"
401
Note: See TracBrowser for help on using the repository browser.