src/network/socket/qtcpserver.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 //#define QTCPSERVER_DEBUG
       
    43 
       
    44 /*! \class QTcpServer
       
    45 
       
    46     \brief The QTcpServer class provides a TCP-based server.
       
    47 
       
    48     \reentrant
       
    49     \ingroup network
       
    50     \inmodule QtNetwork
       
    51 
       
    52     This class makes it possible to accept incoming TCP connections.
       
    53     You can specify the port or have QTcpServer pick one
       
    54     automatically. You can listen on a specific address or on all the
       
    55     machine's addresses.
       
    56 
       
    57     Call listen() to have the server listen for incoming connections.
       
    58     The newConnection() signal is then emitted each time a client
       
    59     connects to the server.
       
    60 
       
    61     Call nextPendingConnection() to accept the pending connection as
       
    62     a connected QTcpSocket. The function returns a pointer to a
       
    63     QTcpSocket in QAbstractSocket::ConnectedState that you can use for
       
    64     communicating with the client.
       
    65 
       
    66     If an error occurs, serverError() returns the type of error, and
       
    67     errorString() can be called to get a human readable description of
       
    68     what happened.
       
    69 
       
    70     When listening for connections, the address and port on which the
       
    71     server is listening are available as serverAddress() and
       
    72     serverPort().
       
    73 
       
    74     Calling close() makes QTcpServer stop listening for incoming
       
    75     connections.
       
    76 
       
    77     Although QTcpServer is mostly designed for use with an event
       
    78     loop, it's possible to use it without one. In that case, you must
       
    79     use waitForNewConnection(), which blocks until either a
       
    80     connection is available or a timeout expires.
       
    81 
       
    82     \sa QTcpSocket, {Fortune Server Example}, {Threaded Fortune Server Example},
       
    83         {Loopback Example}, {Torrent Example}
       
    84 */
       
    85 
       
    86 /*! \fn void QTcpServer::newConnection()
       
    87 
       
    88     This signal is emitted every time a new connection is available.
       
    89 
       
    90     \sa hasPendingConnections(), nextPendingConnection()
       
    91 */
       
    92 
       
    93 #include "private/qobject_p.h"
       
    94 #include "qalgorithms.h"
       
    95 #include "qhostaddress.h"
       
    96 #include "qlist.h"
       
    97 #include "qpointer.h"
       
    98 #include "qnativesocketengine_p.h"
       
    99 #include "qtcpserver.h"
       
   100 #include "qtcpsocket.h"
       
   101 #include "qnetworkproxy.h"
       
   102 
       
   103 QT_BEGIN_NAMESPACE
       
   104 
       
   105 #define Q_CHECK_SOCKETENGINE(returnValue) do { \
       
   106     if (!d->socketEngine) { \
       
   107         return returnValue; \
       
   108     } } while (0)
       
   109 
       
   110 class QTcpServerPrivate : public QObjectPrivate, public QAbstractSocketEngineReceiver
       
   111 {
       
   112     Q_DECLARE_PUBLIC(QTcpServer)
       
   113 public:
       
   114     QTcpServerPrivate();
       
   115     ~QTcpServerPrivate();
       
   116 
       
   117     QList<QTcpSocket *> pendingConnections;
       
   118 
       
   119     quint16 port;
       
   120     QHostAddress address;
       
   121 
       
   122     QAbstractSocket::SocketState state;
       
   123     QAbstractSocketEngine *socketEngine;
       
   124 
       
   125     QAbstractSocket::SocketError serverSocketError;
       
   126     QString serverSocketErrorString;
       
   127 
       
   128     int maxConnections;
       
   129 
       
   130 #ifndef QT_NO_NETWORKPROXY
       
   131     QNetworkProxy proxy;
       
   132     QNetworkProxy resolveProxy(const QHostAddress &address, quint16 port);
       
   133 #endif
       
   134 
       
   135     // from QAbstractSocketEngineReceiver
       
   136     void readNotification();
       
   137     inline void writeNotification() {}
       
   138     inline void exceptionNotification() {}
       
   139     inline void connectionNotification() {}
       
   140 #ifndef QT_NO_NETWORKPROXY
       
   141     inline void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *) {}
       
   142 #endif
       
   143 
       
   144 };
       
   145 
       
   146 /*! \internal
       
   147 */
       
   148 QTcpServerPrivate::QTcpServerPrivate()
       
   149  : port(0)
       
   150  , state(QAbstractSocket::UnconnectedState)
       
   151  , socketEngine(0)
       
   152  , serverSocketError(QAbstractSocket::UnknownSocketError)
       
   153  , maxConnections(30)
       
   154 {
       
   155 }
       
   156 
       
   157 /*! \internal
       
   158 */
       
   159 QTcpServerPrivate::~QTcpServerPrivate()
       
   160 {
       
   161 }
       
   162 
       
   163 #ifndef QT_NO_NETWORKPROXY
       
   164 /*! \internal
       
   165 
       
   166     Resolve the proxy to its final value.
       
   167 */
       
   168 QNetworkProxy QTcpServerPrivate::resolveProxy(const QHostAddress &address, quint16 port)
       
   169 {
       
   170     if (address == QHostAddress::LocalHost ||
       
   171         address == QHostAddress::LocalHostIPv6)
       
   172         return QNetworkProxy::NoProxy;
       
   173 
       
   174     QList<QNetworkProxy> proxies;
       
   175     if (proxy.type() != QNetworkProxy::DefaultProxy) {
       
   176         // a non-default proxy was set with setProxy
       
   177         proxies << proxy;
       
   178     } else {
       
   179         // try the application settings instead
       
   180         QNetworkProxyQuery query(port, QString(), QNetworkProxyQuery::TcpServer);
       
   181         proxies = QNetworkProxyFactory::proxyForQuery(query);
       
   182     }
       
   183 
       
   184     // return the first that we can use
       
   185     foreach (const QNetworkProxy &p, proxies) {
       
   186         if (p.capabilities() & QNetworkProxy::ListeningCapability)
       
   187             return p;
       
   188     }
       
   189 
       
   190     // no proxy found
       
   191     // DefaultProxy will raise an error
       
   192     return QNetworkProxy(QNetworkProxy::DefaultProxy);
       
   193 }
       
   194 #endif
       
   195 
       
   196 /*! \internal
       
   197 */
       
   198 void QTcpServerPrivate::readNotification()
       
   199 {
       
   200     Q_Q(QTcpServer);
       
   201     for (;;) {
       
   202         if (pendingConnections.count() >= maxConnections) {
       
   203 #if defined (QTCPSERVER_DEBUG)
       
   204             qDebug("QTcpServerPrivate::_q_processIncomingConnection() too many connections");
       
   205 #endif
       
   206             if (socketEngine->isReadNotificationEnabled())
       
   207                 socketEngine->setReadNotificationEnabled(false);
       
   208             return;
       
   209         }
       
   210 
       
   211         int descriptor = socketEngine->accept();
       
   212         if (descriptor == -1)
       
   213             break;
       
   214 #if defined (QTCPSERVER_DEBUG)
       
   215         qDebug("QTcpServerPrivate::_q_processIncomingConnection() accepted socket %i", descriptor);
       
   216 #endif
       
   217         q->incomingConnection(descriptor);
       
   218 
       
   219         QPointer<QTcpServer> that = q;
       
   220         emit q->newConnection();
       
   221         if (!that || !q->isListening())
       
   222             return;
       
   223     }
       
   224 }
       
   225 
       
   226 /*!
       
   227     Constructs a QTcpServer object.
       
   228 
       
   229     \a parent is passed to the QObject constructor.
       
   230 
       
   231     \sa listen(), setSocketDescriptor()
       
   232 */
       
   233 QTcpServer::QTcpServer(QObject *parent)
       
   234     : QObject(*new QTcpServerPrivate, parent)
       
   235 {
       
   236 }
       
   237 
       
   238 /*!
       
   239     Destroys the QTcpServer object. If the server is listening for
       
   240     connections, the socket is automatically closed.
       
   241 
       
   242     Any client \l{QTcpSocket}s that are still connected must either
       
   243     disconnect or be reparented before the server is deleted.
       
   244 
       
   245     \sa close()
       
   246 */
       
   247 QTcpServer::~QTcpServer()
       
   248 {
       
   249     close();
       
   250 }
       
   251 
       
   252 /*!
       
   253     Tells the server to listen for incoming connections on address \a
       
   254     address and port \a port. If \a port is 0, a port is chosen
       
   255     automatically. If \a address is QHostAddress::Any, the server
       
   256     will listen on all network interfaces.
       
   257 
       
   258     Returns true on success; otherwise returns false.
       
   259 
       
   260     \sa isListening()
       
   261 */
       
   262 bool QTcpServer::listen(const QHostAddress &address, quint16 port)
       
   263 {
       
   264     Q_D(QTcpServer);
       
   265     if (d->state == QAbstractSocket::ListeningState) {
       
   266         qWarning("QTcpServer::listen() called when already listening");
       
   267         return false;
       
   268     }
       
   269 
       
   270     QAbstractSocket::NetworkLayerProtocol proto = address.protocol();
       
   271 
       
   272 #ifdef QT_NO_NETWORKPROXY
       
   273     static const QNetworkProxy &proxy = *(QNetworkProxy *)0;
       
   274 #else
       
   275     QNetworkProxy proxy = d->resolveProxy(address, port);
       
   276 #endif
       
   277 
       
   278     delete d->socketEngine;
       
   279     d->socketEngine = QAbstractSocketEngine::createSocketEngine(QAbstractSocket::TcpSocket, proxy, this);
       
   280     if (!d->socketEngine) {
       
   281         d->serverSocketError = QAbstractSocket::UnsupportedSocketOperationError;
       
   282         d->serverSocketErrorString = tr("Operation on socket is not supported");
       
   283         return false;
       
   284     }
       
   285     if (!d->socketEngine->initialize(QAbstractSocket::TcpSocket, proto)) {
       
   286         d->serverSocketError = d->socketEngine->error();
       
   287         d->serverSocketErrorString = d->socketEngine->errorString();
       
   288         return false;
       
   289     }
       
   290 
       
   291 #if defined(Q_OS_UNIX)
       
   292     // Under Unix, we want to be able to bind to the port, even if a socket on
       
   293     // the same address-port is in TIME_WAIT. Under Windows this is possible
       
   294     // anyway -- furthermore, the meaning of reusable on Windows is different:
       
   295     // it means that you can use the same address-port for multiple listening
       
   296     // sockets.
       
   297     // Don't abort though if we can't set that option. For example the socks
       
   298     // engine doesn't support that option, but that shouldn't prevent us from
       
   299     // trying to bind/listen.
       
   300     d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 1);
       
   301 #endif
       
   302 
       
   303     if (!d->socketEngine->bind(address, port)) {
       
   304         d->serverSocketError = d->socketEngine->error();
       
   305         d->serverSocketErrorString = d->socketEngine->errorString();
       
   306         return false;
       
   307     }
       
   308 
       
   309     if (!d->socketEngine->listen()) {
       
   310         d->serverSocketError = d->socketEngine->error();
       
   311         d->serverSocketErrorString = d->socketEngine->errorString();
       
   312         return false;
       
   313     }
       
   314 
       
   315     d->socketEngine->setReceiver(d);
       
   316     d->socketEngine->setReadNotificationEnabled(true);
       
   317 
       
   318     d->state = QAbstractSocket::ListeningState;
       
   319     d->address = d->socketEngine->localAddress();
       
   320     d->port = d->socketEngine->localPort();
       
   321 
       
   322 #if defined (QTCPSERVER_DEBUG)
       
   323     qDebug("QTcpServer::listen(%i, \"%s\") == true (listening on port %i)", port,
       
   324            address.toString().toLatin1().constData(), d->socketEngine->localPort());
       
   325 #endif
       
   326     return true;
       
   327 }
       
   328 
       
   329 /*!
       
   330     Returns true if the server is currently listening for incoming
       
   331     connections; otherwise returns false.
       
   332 
       
   333     \sa listen()
       
   334 */
       
   335 bool QTcpServer::isListening() const
       
   336 {
       
   337     Q_D(const QTcpServer);
       
   338     Q_CHECK_SOCKETENGINE(false);
       
   339     return d->socketEngine->state() == QAbstractSocket::ListeningState;
       
   340 }
       
   341 
       
   342 /*!
       
   343     Closes the server. The server will no longer listen for incoming
       
   344     connections.
       
   345 
       
   346     \sa listen()
       
   347 */
       
   348 void QTcpServer::close()
       
   349 {
       
   350     Q_D(QTcpServer);
       
   351 
       
   352     qDeleteAll(d->pendingConnections);
       
   353     d->pendingConnections.clear();
       
   354 
       
   355     if (d->socketEngine) {
       
   356         d->socketEngine->close();
       
   357         QT_TRY {
       
   358             d->socketEngine->deleteLater();
       
   359         } QT_CATCH(const std::bad_alloc &) {
       
   360             // in out of memory situations, the socketEngine
       
   361             // will be deleted in ~QTcpServer (it's a child-object of this)
       
   362         }
       
   363         d->socketEngine = 0;
       
   364     }
       
   365 
       
   366     d->state = QAbstractSocket::UnconnectedState;
       
   367 }
       
   368 
       
   369 /*!
       
   370     Returns the native socket descriptor the server uses to listen
       
   371     for incoming instructions, or -1 if the server is not listening.
       
   372 
       
   373     If the server is using QNetworkProxy, the returned descriptor may
       
   374     not be usable with native socket functions.
       
   375 
       
   376     \sa setSocketDescriptor(), isListening()
       
   377 */
       
   378 int QTcpServer::socketDescriptor() const
       
   379 {
       
   380     Q_D(const QTcpServer);
       
   381     Q_CHECK_SOCKETENGINE(-1);
       
   382     return d->socketEngine->socketDescriptor();
       
   383 }
       
   384 
       
   385 /*!
       
   386     Sets the socket descriptor this server should use when listening
       
   387     for incoming connections to \a socketDescriptor. Returns true if
       
   388     the socket is set successfully; otherwise returns false.
       
   389 
       
   390     The socket is assumed to be in listening state.
       
   391 
       
   392     \sa socketDescriptor(), isListening()
       
   393 */
       
   394 bool QTcpServer::setSocketDescriptor(int socketDescriptor)
       
   395 {
       
   396     Q_D(QTcpServer);
       
   397     if (isListening()) {
       
   398         qWarning("QTcpServer::setSocketDescriptor() called when already listening");
       
   399         return false;
       
   400     }
       
   401 
       
   402     if (d->socketEngine)
       
   403         delete d->socketEngine;
       
   404     d->socketEngine = QAbstractSocketEngine::createSocketEngine(socketDescriptor, this);
       
   405     if (!d->socketEngine->initialize(socketDescriptor, QAbstractSocket::ListeningState)) {
       
   406         d->serverSocketError = d->socketEngine->error();
       
   407         d->serverSocketErrorString = d->socketEngine->errorString();
       
   408 #if defined (QTCPSERVER_DEBUG)
       
   409         qDebug("QTcpServer::setSocketDescriptor(%i) failed (%s)", socketDescriptor,
       
   410                d->serverSocketErrorString.toLatin1().constData());
       
   411 #endif
       
   412         return false;
       
   413     }
       
   414 
       
   415     d->socketEngine->setReceiver(d);
       
   416     d->socketEngine->setReadNotificationEnabled(true);
       
   417 
       
   418     d->state = d->socketEngine->state();
       
   419     d->address = d->socketEngine->localAddress();
       
   420     d->port = d->socketEngine->localPort();
       
   421 
       
   422 #if defined (QTCPSERVER_DEBUG)
       
   423     qDebug("QTcpServer::setSocketDescriptor(%i) succeeded.", socketDescriptor);
       
   424 #endif
       
   425     return true;
       
   426 }
       
   427 
       
   428 /*!
       
   429     Returns the server's port if the server is listening for
       
   430     connections; otherwise returns 0.
       
   431 
       
   432     \sa serverAddress(), listen()
       
   433 */
       
   434 quint16 QTcpServer::serverPort() const
       
   435 {
       
   436     Q_D(const QTcpServer);
       
   437     Q_CHECK_SOCKETENGINE(0);
       
   438     return d->socketEngine->localPort();
       
   439 }
       
   440 
       
   441 /*!
       
   442     Returns the server's address if the server is listening for
       
   443     connections; otherwise returns QHostAddress::Null.
       
   444 
       
   445     \sa serverPort(), listen()
       
   446 */
       
   447 QHostAddress QTcpServer::serverAddress() const
       
   448 {
       
   449     Q_D(const QTcpServer);
       
   450     Q_CHECK_SOCKETENGINE(QHostAddress(QHostAddress::Null));
       
   451     return d->socketEngine->localAddress();
       
   452 }
       
   453 
       
   454 /*!
       
   455     Waits for at most \a msec milliseconds or until an incoming
       
   456     connection is available. Returns true if a connection is
       
   457     available; otherwise returns false. If the operation timed out
       
   458     and \a timedOut is not 0, *\a timedOut will be set to true.
       
   459 
       
   460     This is a blocking function call. Its use is disadvised in a
       
   461     single-threaded GUI application, since the whole application will
       
   462     stop responding until the function returns.
       
   463     waitForNewConnection() is mostly useful when there is no event
       
   464     loop available.
       
   465 
       
   466     The non-blocking alternative is to connect to the newConnection()
       
   467     signal.
       
   468 
       
   469     If msec is -1, this function will not time out.
       
   470 
       
   471     \sa hasPendingConnections(), nextPendingConnection()
       
   472 */
       
   473 bool QTcpServer::waitForNewConnection(int msec, bool *timedOut)
       
   474 {
       
   475     Q_D(QTcpServer);
       
   476     if (d->state != QAbstractSocket::ListeningState)
       
   477         return false;
       
   478 
       
   479     if (!d->socketEngine->waitForRead(msec, timedOut)) {
       
   480         d->serverSocketError = d->socketEngine->error();
       
   481         d->serverSocketErrorString = d->socketEngine->errorString();
       
   482         return false;
       
   483     }
       
   484 
       
   485     if (timedOut && *timedOut)
       
   486         return false;
       
   487 
       
   488     d->readNotification();
       
   489 
       
   490     return true;
       
   491 }
       
   492 
       
   493 /*!
       
   494     Returns true if the server has a pending connection; otherwise
       
   495     returns false.
       
   496 
       
   497     \sa nextPendingConnection(), setMaxPendingConnections()
       
   498 */
       
   499 bool QTcpServer::hasPendingConnections() const
       
   500 {
       
   501     return !d_func()->pendingConnections.isEmpty();
       
   502 }
       
   503 
       
   504 /*!
       
   505     Returns the next pending connection as a connected QTcpSocket
       
   506     object.
       
   507 
       
   508     The socket is created as a child of the server, which means that
       
   509     it is automatically deleted when the QTcpServer object is
       
   510     destroyed. It is still a good idea to delete the object
       
   511     explicitly when you are done with it, to avoid wasting memory.
       
   512 
       
   513     0 is returned if this function is called when there are no pending
       
   514     connections.
       
   515 
       
   516     \sa hasPendingConnections()
       
   517 */
       
   518 QTcpSocket *QTcpServer::nextPendingConnection()
       
   519 {
       
   520     Q_D(QTcpServer);
       
   521     if (d->pendingConnections.isEmpty())
       
   522         return 0;
       
   523 
       
   524     if (!d->socketEngine->isReadNotificationEnabled())
       
   525         d->socketEngine->setReadNotificationEnabled(true);
       
   526 
       
   527     return d->pendingConnections.takeFirst();
       
   528 }
       
   529 
       
   530 /*!
       
   531     This virtual function is called by QTcpServer when a new
       
   532     connection is available. The \a socketDescriptor argument is the
       
   533     native socket descriptor for the accepted connection.
       
   534 
       
   535     The base implementation creates a QTcpSocket, sets the socket
       
   536     descriptor and then stores the QTcpSocket in an internal list of
       
   537     pending connections. Finally newConnection() is emitted.
       
   538 
       
   539     Reimplement this function to alter the server's behavior when a
       
   540     connection is available.
       
   541 
       
   542     If this server is using QNetworkProxy then the \a socketDescriptor
       
   543     may not be usable with native socket functions, and should only be
       
   544     used with QTcpSocket::setSocketDescriptor().
       
   545 
       
   546     \sa newConnection(), nextPendingConnection()
       
   547 */
       
   548 void QTcpServer::incomingConnection(int socketDescriptor)
       
   549 {
       
   550 #if defined (QTCPSERVER_DEBUG)
       
   551     qDebug("QTcpServer::incomingConnection(%i)", socketDescriptor);
       
   552 #endif
       
   553 
       
   554     QTcpSocket *socket = new QTcpSocket(this);
       
   555     socket->setSocketDescriptor(socketDescriptor);
       
   556     d_func()->pendingConnections.append(socket);
       
   557 }
       
   558 
       
   559 /*!
       
   560     Sets the maximum number of pending accepted connections to \a
       
   561     numConnections. QTcpServer will accept no more than \a
       
   562     numConnections incoming connections before
       
   563     nextPendingConnection() is called. By default, the limit is 30
       
   564     pending connections.
       
   565 
       
   566     Clients may still able to connect after the server has reached
       
   567     its maximum number of pending connections (i.e., QTcpSocket can
       
   568     still emit the connected() signal). QTcpServer will stop
       
   569     accepting the new connections, but the operating system may
       
   570     still keep them in queue.
       
   571 
       
   572     \sa maxPendingConnections(), hasPendingConnections()
       
   573 */
       
   574 void QTcpServer::setMaxPendingConnections(int numConnections)
       
   575 {
       
   576     d_func()->maxConnections = numConnections;
       
   577 }
       
   578 
       
   579 /*!
       
   580     Returns the maximum number of pending accepted connections. The
       
   581     default is 30.
       
   582 
       
   583     \sa setMaxPendingConnections(), hasPendingConnections()
       
   584 */
       
   585 int QTcpServer::maxPendingConnections() const
       
   586 {
       
   587     return d_func()->maxConnections;
       
   588 }
       
   589 
       
   590 /*!
       
   591     Returns an error code for the last error that occurred.
       
   592 
       
   593     \sa errorString()
       
   594 */
       
   595 QAbstractSocket::SocketError QTcpServer::serverError() const
       
   596 {
       
   597     return d_func()->serverSocketError;
       
   598 }
       
   599 
       
   600 /*!
       
   601     Returns a human readable description of the last error that
       
   602     occurred.
       
   603 
       
   604     \sa serverError()
       
   605 */
       
   606 QString QTcpServer::errorString() const
       
   607 {
       
   608     return d_func()->serverSocketErrorString;
       
   609 }
       
   610 
       
   611 #ifndef QT_NO_NETWORKPROXY
       
   612 /*!
       
   613     \since 4.1
       
   614 
       
   615     Sets the explicit network proxy for this socket to \a networkProxy.
       
   616 
       
   617     To disable the use of a proxy for this socket, use the
       
   618     QNetworkProxy::NoProxy proxy type:
       
   619 
       
   620     \snippet doc/src/snippets/code/src_network_socket_qtcpserver.cpp 0
       
   621 
       
   622     \sa proxy(), QNetworkProxy
       
   623 */
       
   624 void QTcpServer::setProxy(const QNetworkProxy &networkProxy)
       
   625 {
       
   626     Q_D(QTcpServer);
       
   627     d->proxy = networkProxy;
       
   628 }
       
   629 
       
   630 /*!
       
   631     \since 4.1
       
   632 
       
   633     Returns the network proxy for this socket.
       
   634     By default QNetworkProxy::DefaultProxy is used.
       
   635 
       
   636     \sa setProxy(), QNetworkProxy
       
   637 */
       
   638 QNetworkProxy QTcpServer::proxy() const
       
   639 {
       
   640     Q_D(const QTcpServer);
       
   641     return d->proxy;
       
   642 }
       
   643 #endif // QT_NO_NETWORKPROXY
       
   644 
       
   645 QT_END_NAMESPACE
       
   646 
       
   647 #include "moc_qtcpserver.cpp"
       
   648