Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/network/socket/qtcpserver.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /**************************************************************************** | - | ||||||||||||
2 | ** | - | ||||||||||||
3 | ** Copyright (C) 2015 The Qt Company Ltd. | - | ||||||||||||
4 | ** Contact: http://www.qt.io/licensing/ | - | ||||||||||||
5 | ** | - | ||||||||||||
6 | ** This file is part of the QtNetwork module of the Qt Toolkit. | - | ||||||||||||
7 | ** | - | ||||||||||||
8 | ** $QT_BEGIN_LICENSE:LGPL21$ | - | ||||||||||||
9 | ** Commercial License Usage | - | ||||||||||||
10 | ** Licensees holding valid commercial Qt licenses may use this file in | - | ||||||||||||
11 | ** accordance with the commercial license agreement provided with the | - | ||||||||||||
12 | ** Software or, alternatively, in accordance with the terms contained in | - | ||||||||||||
13 | ** a written agreement between you and The Qt Company. For licensing terms | - | ||||||||||||
14 | ** and conditions see http://www.qt.io/terms-conditions. For further | - | ||||||||||||
15 | ** information use the contact form at http://www.qt.io/contact-us. | - | ||||||||||||
16 | ** | - | ||||||||||||
17 | ** GNU Lesser General Public License Usage | - | ||||||||||||
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | - | ||||||||||||
19 | ** General Public License version 2.1 or version 3 as published by the Free | - | ||||||||||||
20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and | - | ||||||||||||
21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the | - | ||||||||||||
22 | ** following information to ensure the GNU Lesser General Public License | - | ||||||||||||
23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and | - | ||||||||||||
24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | - | ||||||||||||
25 | ** | - | ||||||||||||
26 | ** As a special exception, The Qt Company gives you certain additional | - | ||||||||||||
27 | ** rights. These rights are described in The Qt Company LGPL Exception | - | ||||||||||||
28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | - | ||||||||||||
29 | ** | - | ||||||||||||
30 | ** $QT_END_LICENSE$ | - | ||||||||||||
31 | ** | - | ||||||||||||
32 | ****************************************************************************/ | - | ||||||||||||
33 | - | |||||||||||||
34 | //#define QTCPSERVER_DEBUG | - | ||||||||||||
35 | - | |||||||||||||
36 | /*! \class QTcpServer | - | ||||||||||||
37 | - | |||||||||||||
38 | \brief The QTcpServer class provides a TCP-based server. | - | ||||||||||||
39 | - | |||||||||||||
40 | \reentrant | - | ||||||||||||
41 | \ingroup network | - | ||||||||||||
42 | \inmodule QtNetwork | - | ||||||||||||
43 | - | |||||||||||||
44 | This class makes it possible to accept incoming TCP connections. | - | ||||||||||||
45 | You can specify the port or have QTcpServer pick one | - | ||||||||||||
46 | automatically. You can listen on a specific address or on all the | - | ||||||||||||
47 | machine's addresses. | - | ||||||||||||
48 | - | |||||||||||||
49 | Call listen() to have the server listen for incoming connections. | - | ||||||||||||
50 | The newConnection() signal is then emitted each time a client | - | ||||||||||||
51 | connects to the server. | - | ||||||||||||
52 | - | |||||||||||||
53 | Call nextPendingConnection() to accept the pending connection as | - | ||||||||||||
54 | a connected QTcpSocket. The function returns a pointer to a | - | ||||||||||||
55 | QTcpSocket in QAbstractSocket::ConnectedState that you can use for | - | ||||||||||||
56 | communicating with the client. | - | ||||||||||||
57 | - | |||||||||||||
58 | If an error occurs, serverError() returns the type of error, and | - | ||||||||||||
59 | errorString() can be called to get a human readable description of | - | ||||||||||||
60 | what happened. | - | ||||||||||||
61 | - | |||||||||||||
62 | When listening for connections, the address and port on which the | - | ||||||||||||
63 | server is listening are available as serverAddress() and | - | ||||||||||||
64 | serverPort(). | - | ||||||||||||
65 | - | |||||||||||||
66 | Calling close() makes QTcpServer stop listening for incoming | - | ||||||||||||
67 | connections. | - | ||||||||||||
68 | - | |||||||||||||
69 | Although QTcpServer is mostly designed for use with an event | - | ||||||||||||
70 | loop, it's possible to use it without one. In that case, you must | - | ||||||||||||
71 | use waitForNewConnection(), which blocks until either a | - | ||||||||||||
72 | connection is available or a timeout expires. | - | ||||||||||||
73 | - | |||||||||||||
74 | \sa QTcpSocket, {Fortune Server Example}, {Threaded Fortune Server Example}, | - | ||||||||||||
75 | {Loopback Example}, {Torrent Example} | - | ||||||||||||
76 | */ | - | ||||||||||||
77 | - | |||||||||||||
78 | /*! \fn void QTcpServer::newConnection() | - | ||||||||||||
79 | - | |||||||||||||
80 | This signal is emitted every time a new connection is available. | - | ||||||||||||
81 | - | |||||||||||||
82 | \sa hasPendingConnections(), nextPendingConnection() | - | ||||||||||||
83 | */ | - | ||||||||||||
84 | - | |||||||||||||
85 | /*! \fn void QTcpServer::acceptError(QAbstractSocket::SocketError socketError) | - | ||||||||||||
86 | \since 5.0 | - | ||||||||||||
87 | - | |||||||||||||
88 | This signal is emitted when accepting a new connection results in an error. | - | ||||||||||||
89 | The \a socketError parameter describes the type of error that occurred. | - | ||||||||||||
90 | - | |||||||||||||
91 | \sa pauseAccepting(), resumeAccepting() | - | ||||||||||||
92 | */ | - | ||||||||||||
93 | - | |||||||||||||
94 | #include "qtcpserver.h" | - | ||||||||||||
95 | #include "qtcpserver_p.h" | - | ||||||||||||
96 | - | |||||||||||||
97 | #include "qalgorithms.h" | - | ||||||||||||
98 | #include "qhostaddress.h" | - | ||||||||||||
99 | #include "qlist.h" | - | ||||||||||||
100 | #include "qpointer.h" | - | ||||||||||||
101 | #include "qabstractsocketengine_p.h" | - | ||||||||||||
102 | #include "qtcpsocket.h" | - | ||||||||||||
103 | #include "qnetworkproxy.h" | - | ||||||||||||
104 | - | |||||||||||||
105 | QT_BEGIN_NAMESPACE | - | ||||||||||||
106 | - | |||||||||||||
107 | #define Q_CHECK_SOCKETENGINE(returnValue) do { \ | - | ||||||||||||
108 | if (!d->socketEngine) { \ | - | ||||||||||||
109 | return returnValue; \ | - | ||||||||||||
110 | } } while (0) | - | ||||||||||||
111 | - | |||||||||||||
112 | /*! \internal | - | ||||||||||||
113 | */ | - | ||||||||||||
114 | QTcpServerPrivate::QTcpServerPrivate() | - | ||||||||||||
115 | : port(0) | - | ||||||||||||
116 | , state(QAbstractSocket::UnconnectedState) | - | ||||||||||||
117 | , socketEngine(0) | - | ||||||||||||
118 | , serverSocketError(QAbstractSocket::UnknownSocketError) | - | ||||||||||||
119 | , maxConnections(30) | - | ||||||||||||
120 | { | - | ||||||||||||
121 | } executed 1416 times by 18 tests: end of block Executed by:
| 1416 | ||||||||||||
122 | - | |||||||||||||
123 | /*! \internal | - | ||||||||||||
124 | */ | - | ||||||||||||
125 | QTcpServerPrivate::~QTcpServerPrivate() | - | ||||||||||||
126 | { | - | ||||||||||||
127 | } | - | ||||||||||||
128 | - | |||||||||||||
129 | #ifndef QT_NO_NETWORKPROXY | - | ||||||||||||
130 | /*! \internal | - | ||||||||||||
131 | - | |||||||||||||
132 | Resolve the proxy to its final value. | - | ||||||||||||
133 | */ | - | ||||||||||||
134 | QNetworkProxy QTcpServerPrivate::resolveProxy(const QHostAddress &address, quint16 port) | - | ||||||||||||
135 | { | - | ||||||||||||
136 | if (address.isLoopback())
| 71-686 | ||||||||||||
137 | return QNetworkProxy::NoProxy; executed 71 times by 11 tests: return QNetworkProxy::NoProxy; Executed by:
| 71 | ||||||||||||
138 | - | |||||||||||||
139 | QList<QNetworkProxy> proxies; | - | ||||||||||||
140 | if (proxy.type() != QNetworkProxy::DefaultProxy) {
| 10-676 | ||||||||||||
141 | // a non-default proxy was set with setProxy | - | ||||||||||||
142 | proxies << proxy; | - | ||||||||||||
143 | } else { executed 10 times by 2 tests: end of block Executed by:
| 10 | ||||||||||||
144 | // try the application settings instead | - | ||||||||||||
145 | QNetworkProxyQuery query(port, QString(), QNetworkProxyQuery::TcpServer); | - | ||||||||||||
146 | proxies = QNetworkProxyFactory::proxyForQuery(query); | - | ||||||||||||
147 | } executed 676 times by 11 tests: end of block Executed by:
| 676 | ||||||||||||
148 | - | |||||||||||||
149 | // return the first that we can use | - | ||||||||||||
150 | foreach (const QNetworkProxy &p, proxies) { | - | ||||||||||||
151 | if (p.capabilities() & QNetworkProxy::ListeningCapability)
| 10-680 | ||||||||||||
152 | return p; executed 680 times by 11 tests: return p; Executed by:
| 680 | ||||||||||||
153 | } executed 10 times by 1 test: end of block Executed by:
| 10 | ||||||||||||
154 | - | |||||||||||||
155 | // no proxy found | - | ||||||||||||
156 | // DefaultProxy will raise an error | - | ||||||||||||
157 | return QNetworkProxy(QNetworkProxy::DefaultProxy); executed 6 times by 1 test: return QNetworkProxy(QNetworkProxy::DefaultProxy); Executed by:
| 6 | ||||||||||||
158 | } | - | ||||||||||||
159 | #endif | - | ||||||||||||
160 | - | |||||||||||||
161 | /*! \internal | - | ||||||||||||
162 | */ | - | ||||||||||||
163 | void QTcpServerPrivate::configureCreatedSocket() | - | ||||||||||||
164 | { | - | ||||||||||||
165 | #if defined(Q_OS_UNIX) | - | ||||||||||||
166 | // Under Unix, we want to be able to bind to the port, even if a socket on | - | ||||||||||||
167 | // the same address-port is in TIME_WAIT. Under Windows this is possible | - | ||||||||||||
168 | // anyway -- furthermore, the meaning of reusable on Windows is different: | - | ||||||||||||
169 | // it means that you can use the same address-port for multiple listening | - | ||||||||||||
170 | // sockets. | - | ||||||||||||
171 | // Don't abort though if we can't set that option. For example the socks | - | ||||||||||||
172 | // engine doesn't support that option, but that shouldn't prevent us from | - | ||||||||||||
173 | // trying to bind/listen. | - | ||||||||||||
174 | socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 1); | - | ||||||||||||
175 | #endif | - | ||||||||||||
176 | } executed 751 times by 18 tests: end of block Executed by:
| 751 | ||||||||||||
177 | - | |||||||||||||
178 | /*! \internal | - | ||||||||||||
179 | */ | - | ||||||||||||
180 | void QTcpServerPrivate::readNotification() | - | ||||||||||||
181 | { | - | ||||||||||||
182 | Q_Q(QTcpServer); | - | ||||||||||||
183 | for (;;) { | - | ||||||||||||
184 | if (pendingConnections.count() >= maxConnections) {
| 1-1613 | ||||||||||||
185 | #if defined (QTCPSERVER_DEBUG) | - | ||||||||||||
186 | qDebug("QTcpServerPrivate::_q_processIncomingConnection() too many connections"); | - | ||||||||||||
187 | #endif | - | ||||||||||||
188 | if (socketEngine->isReadNotificationEnabled())
| 0-1 | ||||||||||||
189 | socketEngine->setReadNotificationEnabled(false); executed 1 time by 1 test: socketEngine->setReadNotificationEnabled(false); Executed by:
| 1 | ||||||||||||
190 | return; executed 1 time by 1 test: return; Executed by:
| 1 | ||||||||||||
191 | } | - | ||||||||||||
192 | - | |||||||||||||
193 | int descriptor = socketEngine->accept(); | - | ||||||||||||
194 | if (descriptor == -1) {
| 790-823 | ||||||||||||
195 | if (socketEngine->error() != QAbstractSocket::TemporaryError) {
| 0-790 | ||||||||||||
196 | q->pauseAccepting(); | - | ||||||||||||
197 | serverSocketError = socketEngine->error(); | - | ||||||||||||
198 | serverSocketErrorString = socketEngine->errorString(); | - | ||||||||||||
199 | emit q->acceptError(serverSocketError); | - | ||||||||||||
200 | } never executed: end of block | 0 | ||||||||||||
201 | break; executed 790 times by 15 tests: break; Executed by:
| 790 | ||||||||||||
202 | } | - | ||||||||||||
203 | #if defined (QTCPSERVER_DEBUG) | - | ||||||||||||
204 | qDebug("QTcpServerPrivate::_q_processIncomingConnection() accepted socket %i", descriptor); | - | ||||||||||||
205 | #endif | - | ||||||||||||
206 | q->incomingConnection(descriptor); | - | ||||||||||||
207 | - | |||||||||||||
208 | QPointer<QTcpServer> that = q; | - | ||||||||||||
209 | emit q->newConnection(); | - | ||||||||||||
210 | if (!that || !q->isListening())
| 0-823 | ||||||||||||
211 | return; executed 9 times by 2 tests: return; Executed by:
| 9 | ||||||||||||
212 | } executed 814 times by 15 tests: end of block Executed by:
| 814 | ||||||||||||
213 | } executed 790 times by 15 tests: end of block Executed by:
| 790 | ||||||||||||
214 | - | |||||||||||||
215 | /*! | - | ||||||||||||
216 | Constructs a QTcpServer object. | - | ||||||||||||
217 | - | |||||||||||||
218 | \a parent is passed to the QObject constructor. | - | ||||||||||||
219 | - | |||||||||||||
220 | \sa listen(), setSocketDescriptor() | - | ||||||||||||
221 | */ | - | ||||||||||||
222 | QTcpServer::QTcpServer(QObject *parent) | - | ||||||||||||
223 | : QObject(*new QTcpServerPrivate, parent) | - | ||||||||||||
224 | { | - | ||||||||||||
225 | #if defined(QTCPSERVER_DEBUG) | - | ||||||||||||
226 | qDebug("QTcpServer::QTcpServer(%p)", parent); | - | ||||||||||||
227 | #endif | - | ||||||||||||
228 | } executed 1416 times by 18 tests: end of block Executed by:
| 1416 | ||||||||||||
229 | - | |||||||||||||
230 | /*! | - | ||||||||||||
231 | Destroys the QTcpServer object. If the server is listening for | - | ||||||||||||
232 | connections, the socket is automatically closed. | - | ||||||||||||
233 | - | |||||||||||||
234 | Any client \l{QTcpSocket}s that are still connected must either | - | ||||||||||||
235 | disconnect or be reparented before the server is deleted. | - | ||||||||||||
236 | - | |||||||||||||
237 | \sa close() | - | ||||||||||||
238 | */ | - | ||||||||||||
239 | QTcpServer::~QTcpServer() | - | ||||||||||||
240 | { | - | ||||||||||||
241 | #if defined(QTCPSERVER_DEBUG) | - | ||||||||||||
242 | qDebug("QTcpServer::~QTcpServer()"); | - | ||||||||||||
243 | #endif | - | ||||||||||||
244 | close(); | - | ||||||||||||
245 | } executed 1413 times by 18 tests: end of block Executed by:
| 1413 | ||||||||||||
246 | - | |||||||||||||
247 | /*! \internal | - | ||||||||||||
248 | */ | - | ||||||||||||
249 | QTcpServer::QTcpServer(QTcpServerPrivate &dd, QObject *parent) | - | ||||||||||||
250 | : QObject(dd, parent) | - | ||||||||||||
251 | { | - | ||||||||||||
252 | #if defined(QTCPSERVER_DEBUG) | - | ||||||||||||
253 | qDebug("QTcpServer::QTcpServer(QTcpServerPrivate == %p, parent == %p)", &dd, parent); | - | ||||||||||||
254 | #endif | - | ||||||||||||
255 | } never executed: end of block | 0 | ||||||||||||
256 | - | |||||||||||||
257 | /*! | - | ||||||||||||
258 | Tells the server to listen for incoming connections on address \a | - | ||||||||||||
259 | address and port \a port. If \a port is 0, a port is chosen | - | ||||||||||||
260 | automatically. If \a address is QHostAddress::Any, the server | - | ||||||||||||
261 | will listen on all network interfaces. | - | ||||||||||||
262 | - | |||||||||||||
263 | Returns \c true on success; otherwise returns \c false. | - | ||||||||||||
264 | - | |||||||||||||
265 | \sa isListening() | - | ||||||||||||
266 | */ | - | ||||||||||||
267 | bool QTcpServer::listen(const QHostAddress &address, quint16 port) | - | ||||||||||||
268 | { | - | ||||||||||||
269 | Q_D(QTcpServer); | - | ||||||||||||
270 | if (d->state == QAbstractSocket::ListeningState) {
| 2-757 | ||||||||||||
271 | qWarning("QTcpServer::listen() called when already listening"); | - | ||||||||||||
272 | return false; executed 2 times by 1 test: return false; Executed by:
| 2 | ||||||||||||
273 | } | - | ||||||||||||
274 | - | |||||||||||||
275 | QAbstractSocket::NetworkLayerProtocol proto = address.protocol(); | - | ||||||||||||
276 | QHostAddress addr = address; | - | ||||||||||||
277 | - | |||||||||||||
278 | #ifdef QT_NO_NETWORKPROXY | - | ||||||||||||
279 | static const QNetworkProxy &proxy = *(QNetworkProxy *)0; | - | ||||||||||||
280 | #else | - | ||||||||||||
281 | QNetworkProxy proxy = d->resolveProxy(addr, port); | - | ||||||||||||
282 | #endif | - | ||||||||||||
283 | - | |||||||||||||
284 | delete d->socketEngine; | - | ||||||||||||
285 | d->socketEngine = QAbstractSocketEngine::createSocketEngine(QAbstractSocket::TcpSocket, proxy, this); | - | ||||||||||||
286 | if (!d->socketEngine) {
| 6-751 | ||||||||||||
287 | d->serverSocketError = QAbstractSocket::UnsupportedSocketOperationError; | - | ||||||||||||
288 | d->serverSocketErrorString = tr("Operation on socket is not supported"); | - | ||||||||||||
289 | return false; executed 6 times by 1 test: return false; Executed by:
| 6 | ||||||||||||
290 | } | - | ||||||||||||
291 | #ifndef QT_NO_BEARERMANAGEMENT | - | ||||||||||||
292 | //copy network session down to the socket engine (if it has been set) | - | ||||||||||||
293 | d->socketEngine->setProperty("_q_networksession", property("_q_networksession")); | - | ||||||||||||
294 | #endif | - | ||||||||||||
295 | if (!d->socketEngine->initialize(QAbstractSocket::TcpSocket, proto)) {
| 0-751 | ||||||||||||
296 | d->serverSocketError = d->socketEngine->error(); | - | ||||||||||||
297 | d->serverSocketErrorString = d->socketEngine->errorString(); | - | ||||||||||||
298 | return false; never executed: return false; | 0 | ||||||||||||
299 | } | - | ||||||||||||
300 | proto = d->socketEngine->protocol(); | - | ||||||||||||
301 | if (addr.protocol() == QAbstractSocket::AnyIPProtocol && proto == QAbstractSocket::IPv4Protocol)
| 0-500 | ||||||||||||
302 | addr = QHostAddress::AnyIPv4; never executed: addr = QHostAddress::AnyIPv4; | 0 | ||||||||||||
303 | - | |||||||||||||
304 | d->configureCreatedSocket(); | - | ||||||||||||
305 | - | |||||||||||||
306 | if (!d->socketEngine->bind(addr, port)) {
| 12-739 | ||||||||||||
307 | d->serverSocketError = d->socketEngine->error(); | - | ||||||||||||
308 | d->serverSocketErrorString = d->socketEngine->errorString(); | - | ||||||||||||
309 | return false; executed 12 times by 1 test: return false; Executed by:
| 12 | ||||||||||||
310 | } | - | ||||||||||||
311 | - | |||||||||||||
312 | if (!d->socketEngine->listen()) {
| 0-739 | ||||||||||||
313 | d->serverSocketError = d->socketEngine->error(); | - | ||||||||||||
314 | d->serverSocketErrorString = d->socketEngine->errorString(); | - | ||||||||||||
315 | return false; never executed: return false; | 0 | ||||||||||||
316 | } | - | ||||||||||||
317 | - | |||||||||||||
318 | d->socketEngine->setReceiver(d); | - | ||||||||||||
319 | d->socketEngine->setReadNotificationEnabled(true); | - | ||||||||||||
320 | - | |||||||||||||
321 | d->state = QAbstractSocket::ListeningState; | - | ||||||||||||
322 | d->address = d->socketEngine->localAddress(); | - | ||||||||||||
323 | d->port = d->socketEngine->localPort(); | - | ||||||||||||
324 | - | |||||||||||||
325 | #if defined (QTCPSERVER_DEBUG) | - | ||||||||||||
326 | qDebug("QTcpServer::listen(%i, \"%s\") == true (listening on port %i)", port, | - | ||||||||||||
327 | address.toString().toLatin1().constData(), d->socketEngine->localPort()); | - | ||||||||||||
328 | #endif | - | ||||||||||||
329 | return true; executed 739 times by 18 tests: return true; Executed by:
| 739 | ||||||||||||
330 | } | - | ||||||||||||
331 | - | |||||||||||||
332 | /*! | - | ||||||||||||
333 | Returns \c true if the server is currently listening for incoming | - | ||||||||||||
334 | connections; otherwise returns \c false. | - | ||||||||||||
335 | - | |||||||||||||
336 | \sa listen() | - | ||||||||||||
337 | */ | - | ||||||||||||
338 | bool QTcpServer::isListening() const | - | ||||||||||||
339 | { | - | ||||||||||||
340 | Q_D(const QTcpServer); | - | ||||||||||||
341 | Q_CHECK_SOCKETENGINE(false); executed 65 times by 3 tests: return false; Executed by:
| 65-819 | ||||||||||||
342 | return d->socketEngine->state() == QAbstractSocket::ListeningState; executed 819 times by 15 tests: return d->socketEngine->state() == QAbstractSocket::ListeningState; Executed by:
| 819 | ||||||||||||
343 | } | - | ||||||||||||
344 | - | |||||||||||||
345 | /*! | - | ||||||||||||
346 | Closes the server. The server will no longer listen for incoming | - | ||||||||||||
347 | connections. | - | ||||||||||||
348 | - | |||||||||||||
349 | \sa listen() | - | ||||||||||||
350 | */ | - | ||||||||||||
351 | void QTcpServer::close() | - | ||||||||||||
352 | { | - | ||||||||||||
353 | Q_D(QTcpServer); | - | ||||||||||||
354 | - | |||||||||||||
355 | qDeleteAll(d->pendingConnections); | - | ||||||||||||
356 | d->pendingConnections.clear(); | - | ||||||||||||
357 | - | |||||||||||||
358 | if (d->socketEngine) {
| 681-752 | ||||||||||||
359 | d->socketEngine->close(); | - | ||||||||||||
360 | QT_TRY { | - | ||||||||||||
361 | d->socketEngine->deleteLater(); | - | ||||||||||||
362 | } QT_CATCH(const std::bad_alloc &) { executed 752 times by 18 tests: end of block Executed by:
dead code: { } | - | ||||||||||||
363 | // in out of memory situations, the socketEngine dead code: { } | - | ||||||||||||
364 | // will be deleted in ~QTcpServer (it's a child-object of this) dead code: { } | - | ||||||||||||
365 | } dead code: { } | - | ||||||||||||
366 | d->socketEngine = 0; | - | ||||||||||||
367 | } executed 752 times by 18 tests: end of block Executed by:
| 752 | ||||||||||||
368 | - | |||||||||||||
369 | d->state = QAbstractSocket::UnconnectedState; | - | ||||||||||||
370 | } executed 1433 times by 18 tests: end of block Executed by:
| 1433 | ||||||||||||
371 | - | |||||||||||||
372 | /*! | - | ||||||||||||
373 | Returns the native socket descriptor the server uses to listen | - | ||||||||||||
374 | for incoming instructions, or -1 if the server is not listening. | - | ||||||||||||
375 | - | |||||||||||||
376 | If the server is using QNetworkProxy, the returned descriptor may | - | ||||||||||||
377 | not be usable with native socket functions. | - | ||||||||||||
378 | - | |||||||||||||
379 | \sa setSocketDescriptor(), isListening() | - | ||||||||||||
380 | */ | - | ||||||||||||
381 | qintptr QTcpServer::socketDescriptor() const | - | ||||||||||||
382 | { | - | ||||||||||||
383 | Q_D(const QTcpServer); | - | ||||||||||||
384 | Q_CHECK_SOCKETENGINE(-1); executed 2 times by 1 test: return -1; Executed by:
| 0-2 | ||||||||||||
385 | return d->socketEngine->socketDescriptor(); never executed: return d->socketEngine->socketDescriptor(); | 0 | ||||||||||||
386 | } | - | ||||||||||||
387 | - | |||||||||||||
388 | /*! | - | ||||||||||||
389 | Sets the socket descriptor this server should use when listening | - | ||||||||||||
390 | for incoming connections to \a socketDescriptor. Returns \c true if | - | ||||||||||||
391 | the socket is set successfully; otherwise returns \c false. | - | ||||||||||||
392 | - | |||||||||||||
393 | The socket is assumed to be in listening state. | - | ||||||||||||
394 | - | |||||||||||||
395 | \sa socketDescriptor(), isListening() | - | ||||||||||||
396 | */ | - | ||||||||||||
397 | bool QTcpServer::setSocketDescriptor(qintptr socketDescriptor) | - | ||||||||||||
398 | { | - | ||||||||||||
399 | Q_D(QTcpServer); | - | ||||||||||||
400 | if (isListening()) {
| 0-4 | ||||||||||||
401 | qWarning("QTcpServer::setSocketDescriptor() called when already listening"); | - | ||||||||||||
402 | return false; never executed: return false; | 0 | ||||||||||||
403 | } | - | ||||||||||||
404 | - | |||||||||||||
405 | if (d->socketEngine)
| 2 | ||||||||||||
406 | delete d->socketEngine; executed 2 times by 1 test: delete d->socketEngine; Executed by:
| 2 | ||||||||||||
407 | d->socketEngine = QAbstractSocketEngine::createSocketEngine(socketDescriptor, this); | - | ||||||||||||
408 | if (!d->socketEngine) {
| 0-4 | ||||||||||||
409 | d->serverSocketError = QAbstractSocket::UnsupportedSocketOperationError; | - | ||||||||||||
410 | d->serverSocketErrorString = tr("Operation on socket is not supported"); | - | ||||||||||||
411 | return false; never executed: return false; | 0 | ||||||||||||
412 | } | - | ||||||||||||
413 | #ifndef QT_NO_BEARERMANAGEMENT | - | ||||||||||||
414 | //copy network session down to the socket engine (if it has been set) | - | ||||||||||||
415 | d->socketEngine->setProperty("_q_networksession", property("_q_networksession")); | - | ||||||||||||
416 | #endif | - | ||||||||||||
417 | if (!d->socketEngine->initialize(socketDescriptor, QAbstractSocket::ListeningState)) {
| 2 | ||||||||||||
418 | d->serverSocketError = d->socketEngine->error(); | - | ||||||||||||
419 | d->serverSocketErrorString = d->socketEngine->errorString(); | - | ||||||||||||
420 | #if defined (QTCPSERVER_DEBUG) | - | ||||||||||||
421 | qDebug("QTcpServer::setSocketDescriptor(%i) failed (%s)", socketDescriptor, | - | ||||||||||||
422 | d->serverSocketErrorString.toLatin1().constData()); | - | ||||||||||||
423 | #endif | - | ||||||||||||
424 | return false; executed 2 times by 1 test: return false; Executed by:
| 2 | ||||||||||||
425 | } | - | ||||||||||||
426 | - | |||||||||||||
427 | d->socketEngine->setReceiver(d); | - | ||||||||||||
428 | d->socketEngine->setReadNotificationEnabled(true); | - | ||||||||||||
429 | - | |||||||||||||
430 | d->state = d->socketEngine->state(); | - | ||||||||||||
431 | d->address = d->socketEngine->localAddress(); | - | ||||||||||||
432 | d->port = d->socketEngine->localPort(); | - | ||||||||||||
433 | - | |||||||||||||
434 | #if defined (QTCPSERVER_DEBUG) | - | ||||||||||||
435 | qDebug("QTcpServer::setSocketDescriptor(%i) succeeded.", socketDescriptor); | - | ||||||||||||
436 | #endif | - | ||||||||||||
437 | return true; executed 2 times by 1 test: return true; Executed by:
| 2 | ||||||||||||
438 | } | - | ||||||||||||
439 | - | |||||||||||||
440 | /*! | - | ||||||||||||
441 | Returns the server's port if the server is listening for | - | ||||||||||||
442 | connections; otherwise returns 0. | - | ||||||||||||
443 | - | |||||||||||||
444 | \sa serverAddress(), listen() | - | ||||||||||||
445 | */ | - | ||||||||||||
446 | quint16 QTcpServer::serverPort() const | - | ||||||||||||
447 | { | - | ||||||||||||
448 | Q_D(const QTcpServer); | - | ||||||||||||
449 | Q_CHECK_SOCKETENGINE(0); executed 2 times by 1 test: return 0; Executed by:
| 2-756 | ||||||||||||
450 | return d->socketEngine->localPort(); executed 756 times by 15 tests: return d->socketEngine->localPort(); Executed by:
| 756 | ||||||||||||
451 | } | - | ||||||||||||
452 | - | |||||||||||||
453 | /*! | - | ||||||||||||
454 | Returns the server's address if the server is listening for | - | ||||||||||||
455 | connections; otherwise returns QHostAddress::Null. | - | ||||||||||||
456 | - | |||||||||||||
457 | \sa serverPort(), listen() | - | ||||||||||||
458 | */ | - | ||||||||||||
459 | QHostAddress QTcpServer::serverAddress() const | - | ||||||||||||
460 | { | - | ||||||||||||
461 | Q_D(const QTcpServer); | - | ||||||||||||
462 | Q_CHECK_SOCKETENGINE(QHostAddress(QHostAddress::Null)); executed 2 times by 1 test: return QHostAddress(QHostAddress::Null); Executed by:
| 2-52 | ||||||||||||
463 | return d->socketEngine->localAddress(); executed 52 times by 8 tests: return d->socketEngine->localAddress(); Executed by:
| 52 | ||||||||||||
464 | } | - | ||||||||||||
465 | - | |||||||||||||
466 | /*! | - | ||||||||||||
467 | Waits for at most \a msec milliseconds or until an incoming | - | ||||||||||||
468 | connection is available. Returns \c true if a connection is | - | ||||||||||||
469 | available; otherwise returns \c false. If the operation timed out | - | ||||||||||||
470 | and \a timedOut is not 0, *\a timedOut will be set to true. | - | ||||||||||||
471 | - | |||||||||||||
472 | This is a blocking function call. Its use is disadvised in a | - | ||||||||||||
473 | single-threaded GUI application, since the whole application will | - | ||||||||||||
474 | stop responding until the function returns. | - | ||||||||||||
475 | waitForNewConnection() is mostly useful when there is no event | - | ||||||||||||
476 | loop available. | - | ||||||||||||
477 | - | |||||||||||||
478 | The non-blocking alternative is to connect to the newConnection() | - | ||||||||||||
479 | signal. | - | ||||||||||||
480 | - | |||||||||||||
481 | If msec is -1, this function will not time out. | - | ||||||||||||
482 | - | |||||||||||||
483 | \sa hasPendingConnections(), nextPendingConnection() | - | ||||||||||||
484 | */ | - | ||||||||||||
485 | bool QTcpServer::waitForNewConnection(int msec, bool *timedOut) | - | ||||||||||||
486 | { | - | ||||||||||||
487 | Q_D(QTcpServer); | - | ||||||||||||
488 | if (d->state != QAbstractSocket::ListeningState)
| 0-395 | ||||||||||||
489 | return false; never executed: return false; | 0 | ||||||||||||
490 | - | |||||||||||||
491 | if (!d->socketEngine->waitForRead(msec, timedOut)) {
| 24-371 | ||||||||||||
492 | d->serverSocketError = d->socketEngine->error(); | - | ||||||||||||
493 | d->serverSocketErrorString = d->socketEngine->errorString(); | - | ||||||||||||
494 | return false; executed 24 times by 2 tests: return false; Executed by:
| 24 | ||||||||||||
495 | } | - | ||||||||||||
496 | - | |||||||||||||
497 | if (timedOut && *timedOut)
| 0-358 | ||||||||||||
498 | return false; never executed: return false; | 0 | ||||||||||||
499 | - | |||||||||||||
500 | d->readNotification(); | - | ||||||||||||
501 | - | |||||||||||||
502 | return true; executed 371 times by 7 tests: return true; Executed by:
| 371 | ||||||||||||
503 | } | - | ||||||||||||
504 | - | |||||||||||||
505 | /*! | - | ||||||||||||
506 | Returns \c true if the server has a pending connection; otherwise | - | ||||||||||||
507 | returns \c false. | - | ||||||||||||
508 | - | |||||||||||||
509 | \sa nextPendingConnection(), setMaxPendingConnections() | - | ||||||||||||
510 | */ | - | ||||||||||||
511 | bool QTcpServer::hasPendingConnections() const | - | ||||||||||||
512 | { | - | ||||||||||||
513 | return !d_func()->pendingConnections.isEmpty(); executed 48 times by 3 tests: return !d_func()->pendingConnections.isEmpty(); Executed by:
| 48 | ||||||||||||
514 | } | - | ||||||||||||
515 | - | |||||||||||||
516 | /*! | - | ||||||||||||
517 | Returns the next pending connection as a connected QTcpSocket | - | ||||||||||||
518 | object. | - | ||||||||||||
519 | - | |||||||||||||
520 | The socket is created as a child of the server, which means that | - | ||||||||||||
521 | it is automatically deleted when the QTcpServer object is | - | ||||||||||||
522 | destroyed. It is still a good idea to delete the object | - | ||||||||||||
523 | explicitly when you are done with it, to avoid wasting memory. | - | ||||||||||||
524 | - | |||||||||||||
525 | 0 is returned if this function is called when there are no pending | - | ||||||||||||
526 | connections. | - | ||||||||||||
527 | - | |||||||||||||
528 | \note The returned QTcpSocket object cannot be used from another | - | ||||||||||||
529 | thread. If you want to use an incoming connection from another thread, | - | ||||||||||||
530 | you need to override incomingConnection(). | - | ||||||||||||
531 | - | |||||||||||||
532 | \sa hasPendingConnections() | - | ||||||||||||
533 | */ | - | ||||||||||||
534 | QTcpSocket *QTcpServer::nextPendingConnection() | - | ||||||||||||
535 | { | - | ||||||||||||
536 | Q_D(QTcpServer); | - | ||||||||||||
537 | if (d->pendingConnections.isEmpty())
| 34-539 | ||||||||||||
538 | return 0; executed 34 times by 3 tests: return 0; Executed by:
| 34 | ||||||||||||
539 | - | |||||||||||||
540 | if (!d->socketEngine->isReadNotificationEnabled())
| 13-526 | ||||||||||||
541 | d->socketEngine->setReadNotificationEnabled(true); executed 13 times by 2 tests: d->socketEngine->setReadNotificationEnabled(true); Executed by:
| 13 | ||||||||||||
542 | - | |||||||||||||
543 | return d->pendingConnections.takeFirst(); executed 539 times by 15 tests: return d->pendingConnections.takeFirst(); Executed by:
| 539 | ||||||||||||
544 | } | - | ||||||||||||
545 | - | |||||||||||||
546 | /*! | - | ||||||||||||
547 | This virtual function is called by QTcpServer when a new | - | ||||||||||||
548 | connection is available. The \a socketDescriptor argument is the | - | ||||||||||||
549 | native socket descriptor for the accepted connection. | - | ||||||||||||
550 | - | |||||||||||||
551 | The base implementation creates a QTcpSocket, sets the socket | - | ||||||||||||
552 | descriptor and then stores the QTcpSocket in an internal list of | - | ||||||||||||
553 | pending connections. Finally newConnection() is emitted. | - | ||||||||||||
554 | - | |||||||||||||
555 | Reimplement this function to alter the server's behavior when a | - | ||||||||||||
556 | connection is available. | - | ||||||||||||
557 | - | |||||||||||||
558 | If this server is using QNetworkProxy then the \a socketDescriptor | - | ||||||||||||
559 | may not be usable with native socket functions, and should only be | - | ||||||||||||
560 | used with QTcpSocket::setSocketDescriptor(). | - | ||||||||||||
561 | - | |||||||||||||
562 | \note If another socket is created in the reimplementation | - | ||||||||||||
563 | of this method, it needs to be added to the Pending Connections mechanism | - | ||||||||||||
564 | by calling addPendingConnection(). | - | ||||||||||||
565 | - | |||||||||||||
566 | \note If you want to handle an incoming connection as a new QTcpSocket | - | ||||||||||||
567 | object in another thread you have to pass the socketDescriptor | - | ||||||||||||
568 | to the other thread and create the QTcpSocket object there and | - | ||||||||||||
569 | use its setSocketDescriptor() method. | - | ||||||||||||
570 | - | |||||||||||||
571 | \sa newConnection(), nextPendingConnection(), addPendingConnection() | - | ||||||||||||
572 | */ | - | ||||||||||||
573 | void QTcpServer::incomingConnection(qintptr socketDescriptor) | - | ||||||||||||
574 | { | - | ||||||||||||
575 | #if defined (QTCPSERVER_DEBUG) | - | ||||||||||||
576 | qDebug("QTcpServer::incomingConnection(%i)", socketDescriptor); | - | ||||||||||||
577 | #endif | - | ||||||||||||
578 | - | |||||||||||||
579 | QTcpSocket *socket = new QTcpSocket(this); | - | ||||||||||||
580 | socket->setSocketDescriptor(socketDescriptor); | - | ||||||||||||
581 | addPendingConnection(socket); | - | ||||||||||||
582 | } executed 545 times by 15 tests: end of block Executed by:
| 545 | ||||||||||||
583 | - | |||||||||||||
584 | /*! | - | ||||||||||||
585 | This function is called by QTcpServer::incomingConnection() | - | ||||||||||||
586 | to add the \a socket to the list of pending incoming connections. | - | ||||||||||||
587 | - | |||||||||||||
588 | \note Don't forget to call this member from reimplemented | - | ||||||||||||
589 | incomingConnection() if you do not want to break the | - | ||||||||||||
590 | Pending Connections mechanism. | - | ||||||||||||
591 | - | |||||||||||||
592 | \sa incomingConnection() | - | ||||||||||||
593 | \since 4.7 | - | ||||||||||||
594 | */ | - | ||||||||||||
595 | void QTcpServer::addPendingConnection(QTcpSocket* socket) | - | ||||||||||||
596 | { | - | ||||||||||||
597 | d_func()->pendingConnections.append(socket); | - | ||||||||||||
598 | } executed 545 times by 15 tests: end of block Executed by:
| 545 | ||||||||||||
599 | - | |||||||||||||
600 | /*! | - | ||||||||||||
601 | Sets the maximum number of pending accepted connections to \a | - | ||||||||||||
602 | numConnections. QTcpServer will accept no more than \a | - | ||||||||||||
603 | numConnections incoming connections before | - | ||||||||||||
604 | nextPendingConnection() is called. By default, the limit is 30 | - | ||||||||||||
605 | pending connections. | - | ||||||||||||
606 | - | |||||||||||||
607 | Clients may still able to connect after the server has reached | - | ||||||||||||
608 | its maximum number of pending connections (i.e., QTcpSocket can | - | ||||||||||||
609 | still emit the connected() signal). QTcpServer will stop | - | ||||||||||||
610 | accepting the new connections, but the operating system may | - | ||||||||||||
611 | still keep them in queue. | - | ||||||||||||
612 | - | |||||||||||||
613 | \sa maxPendingConnections(), hasPendingConnections() | - | ||||||||||||
614 | */ | - | ||||||||||||
615 | void QTcpServer::setMaxPendingConnections(int numConnections) | - | ||||||||||||
616 | { | - | ||||||||||||
617 | d_func()->maxConnections = numConnections; | - | ||||||||||||
618 | } executed 7 times by 1 test: end of block Executed by:
| 7 | ||||||||||||
619 | - | |||||||||||||
620 | /*! | - | ||||||||||||
621 | Returns the maximum number of pending accepted connections. The | - | ||||||||||||
622 | default is 30. | - | ||||||||||||
623 | - | |||||||||||||
624 | \sa setMaxPendingConnections(), hasPendingConnections() | - | ||||||||||||
625 | */ | - | ||||||||||||
626 | int QTcpServer::maxPendingConnections() const | - | ||||||||||||
627 | { | - | ||||||||||||
628 | return d_func()->maxConnections; executed 8 times by 1 test: return d_func()->maxConnections; Executed by:
| 8 | ||||||||||||
629 | } | - | ||||||||||||
630 | - | |||||||||||||
631 | /*! | - | ||||||||||||
632 | Returns an error code for the last error that occurred. | - | ||||||||||||
633 | - | |||||||||||||
634 | \sa errorString() | - | ||||||||||||
635 | */ | - | ||||||||||||
636 | QAbstractSocket::SocketError QTcpServer::serverError() const | - | ||||||||||||
637 | { | - | ||||||||||||
638 | return d_func()->serverSocketError; executed 17 times by 1 test: return d_func()->serverSocketError; Executed by:
| 17 | ||||||||||||
639 | } | - | ||||||||||||
640 | - | |||||||||||||
641 | /*! | - | ||||||||||||
642 | Returns a human readable description of the last error that | - | ||||||||||||
643 | occurred. | - | ||||||||||||
644 | - | |||||||||||||
645 | \sa serverError() | - | ||||||||||||
646 | */ | - | ||||||||||||
647 | QString QTcpServer::errorString() const | - | ||||||||||||
648 | { | - | ||||||||||||
649 | return d_func()->serverSocketErrorString; executed 21 times by 1 test: return d_func()->serverSocketErrorString; Executed by:
| 21 | ||||||||||||
650 | } | - | ||||||||||||
651 | - | |||||||||||||
652 | /*! | - | ||||||||||||
653 | \since 5.0 | - | ||||||||||||
654 | - | |||||||||||||
655 | Pauses accepting new connections. Queued connections will remain in queue. | - | ||||||||||||
656 | - | |||||||||||||
657 | \sa resumeAccepting() | - | ||||||||||||
658 | */ | - | ||||||||||||
659 | void QTcpServer::pauseAccepting() | - | ||||||||||||
660 | { | - | ||||||||||||
661 | d_func()->socketEngine->setReadNotificationEnabled(false); | - | ||||||||||||
662 | } never executed: end of block | 0 | ||||||||||||
663 | - | |||||||||||||
664 | /*! | - | ||||||||||||
665 | \since 5.0 | - | ||||||||||||
666 | - | |||||||||||||
667 | Resumes accepting new connections. | - | ||||||||||||
668 | - | |||||||||||||
669 | \sa pauseAccepting() | - | ||||||||||||
670 | */ | - | ||||||||||||
671 | void QTcpServer::resumeAccepting() | - | ||||||||||||
672 | { | - | ||||||||||||
673 | d_func()->socketEngine->setReadNotificationEnabled(true); | - | ||||||||||||
674 | } never executed: end of block | 0 | ||||||||||||
675 | - | |||||||||||||
676 | #ifndef QT_NO_NETWORKPROXY | - | ||||||||||||
677 | /*! | - | ||||||||||||
678 | \since 4.1 | - | ||||||||||||
679 | - | |||||||||||||
680 | Sets the explicit network proxy for this socket to \a networkProxy. | - | ||||||||||||
681 | - | |||||||||||||
682 | To disable the use of a proxy for this socket, use the | - | ||||||||||||
683 | QNetworkProxy::NoProxy proxy type: | - | ||||||||||||
684 | - | |||||||||||||
685 | \snippet code/src_network_socket_qtcpserver.cpp 0 | - | ||||||||||||
686 | - | |||||||||||||
687 | \sa proxy(), QNetworkProxy | - | ||||||||||||
688 | */ | - | ||||||||||||
689 | void QTcpServer::setProxy(const QNetworkProxy &networkProxy) | - | ||||||||||||
690 | { | - | ||||||||||||
691 | Q_D(QTcpServer); | - | ||||||||||||
692 | d->proxy = networkProxy; | - | ||||||||||||
693 | } executed 10 times by 2 tests: end of block Executed by:
| 10 | ||||||||||||
694 | - | |||||||||||||
695 | /*! | - | ||||||||||||
696 | \since 4.1 | - | ||||||||||||
697 | - | |||||||||||||
698 | Returns the network proxy for this socket. | - | ||||||||||||
699 | By default QNetworkProxy::DefaultProxy is used. | - | ||||||||||||
700 | - | |||||||||||||
701 | \sa setProxy(), QNetworkProxy | - | ||||||||||||
702 | */ | - | ||||||||||||
703 | QNetworkProxy QTcpServer::proxy() const | - | ||||||||||||
704 | { | - | ||||||||||||
705 | Q_D(const QTcpServer); | - | ||||||||||||
706 | return d->proxy; executed 668 times by 11 tests: return d->proxy; Executed by:
| 668 | ||||||||||||
707 | } | - | ||||||||||||
708 | #endif // QT_NO_NETWORKPROXY | - | ||||||||||||
709 | - | |||||||||||||
710 | QT_END_NAMESPACE | - | ||||||||||||
711 | - | |||||||||||||
712 | #include "moc_qtcpserver.cpp" | - | ||||||||||||
713 | - | |||||||||||||
Source code | Switch to Preprocessed file |