|
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 |