src/network/socket/qlocalserver.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtNetwork module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qlocalserver.h"
       
    43 #include "qlocalserver_p.h"
       
    44 #include "qlocalsocket.h"
       
    45 
       
    46 QT_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  */
       
    89 QLocalServer::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  */
       
   105 QLocalServer::~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  */
       
   117 void 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  */
       
   138 QString 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  */
       
   150 bool 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  */
       
   171 void 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  */
       
   186 bool 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  */
       
   213 bool 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  */
       
   244 int 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  */
       
   271 QLocalSocket *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 */
       
   305 bool 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  */
       
   316 QString 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  */
       
   329 QString 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  */
       
   340 QAbstractSocket::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  */
       
   359 void 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  */
       
   382 bool 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 
       
   398 QT_END_NAMESPACE
       
   399 
       
   400 #include "moc_qlocalserver.cpp"
       
   401