qudpsocket.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/network/socket/qudpsocket.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
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 QUDPSOCKET_DEBUG-
35-
36/*! \class QUdpSocket-
37-
38 \reentrant-
39 \brief The QUdpSocket class provides a UDP socket.-
40-
41 \ingroup network-
42 \inmodule QtNetwork-
43-
44 UDP (User Datagram Protocol) is a lightweight, unreliable,-
45 datagram-oriented, connectionless protocol. It can be used when-
46 reliability isn't important. QUdpSocket is a subclass of-
47 QAbstractSocket that allows you to send and receive UDP-
48 datagrams.-
49-
50 The most common way to use this class is to bind to an address and port-
51 using bind(), then call writeDatagram() and readDatagram() to transfer-
52 data. If you want to use the standard QIODevice functions read(),-
53 readLine(), write(), etc., you must first connect the socket directly to a-
54 peer by calling connectToHost().-
55-
56 The socket emits the bytesWritten() signal every time a datagram-
57 is written to the network. If you just want to send datagrams,-
58 you don't need to call bind().-
59-
60 The readyRead() signal is emitted whenever datagrams arrive. In-
61 that case, hasPendingDatagrams() returns \c true. Call-
62 pendingDatagramSize() to obtain the size of the first pending-
63 datagram, and readDatagram() to read it.-
64-
65 \note An incoming datagram should be read when you receive the readyRead()-
66 signal, otherwise this signal will not be emitted for the next datagram.-
67-
68 Example:-
69-
70 \snippet code/src_network_socket_qudpsocket.cpp 0-
71-
72 QUdpSocket also supports UDP multicast. Use joinMulticastGroup() and-
73 leaveMulticastGroup() to control group membership, and-
74 QAbstractSocket::MulticastTtlOption and-
75 QAbstractSocket::MulticastLoopbackOption to set the TTL and loopback socket-
76 options. Use setMulticastInterface() to control the outgoing interface for-
77 multicast datagrams, and multicastInterface() to query it.-
78-
79 With QUdpSocket, you can also establish a virtual connection to a-
80 UDP server using connectToHost() and then use read() and write()-
81 to exchange datagrams without specifying the receiver for each-
82 datagram.-
83-
84 The \l{broadcastsender}{Broadcast Sender},-
85 \l{broadcastreceiver}{Broadcast Receiver},-
86 \l{multicastsender}{Multicast Sender}, and-
87 \l{multicastreceiver}{Multicast Receiver} examples illustrate how-
88 to use QUdpSocket in applications.-
89-
90 \sa QTcpSocket-
91*/-
92-
93#include "qudpsocket.h"-
94#include "qhostaddress.h"-
95#include "qnetworkinterface.h"-
96#include "qabstractsocket_p.h"-
97-
98QT_BEGIN_NAMESPACE-
99-
100#ifndef QT_NO_UDPSOCKET-
101-
102#define QT_CHECK_BOUND(function, a) do { \-
103 if (!isValid()) { \-
104 qWarning(function" called on a QUdpSocket when not in QUdpSocket::BoundState"); \-
105 return (a); \-
106 } } while (0)-
107-
108class QUdpSocketPrivate : public QAbstractSocketPrivate-
109{-
110 Q_DECLARE_PUBLIC(QUdpSocket)-
111-
112 bool doEnsureInitialized(const QHostAddress &bindAddress, quint16 bindPort,-
113 const QHostAddress &remoteAddress);-
114public:-
115 inline bool ensureInitialized(const QHostAddress &bindAddress, quint16 bindPort)-
116 { return doEnsureInitialized(bindAddress, bindPort, QHostAddress()); }
never executed: return doEnsureInitialized(bindAddress, bindPort, QHostAddress());
0
117-
118 inline bool ensureInitialized(const QHostAddress &remoteAddress)-
119 { return doEnsureInitialized(QHostAddress(), 0, remoteAddress); }
never executed: return doEnsureInitialized(QHostAddress(), 0, remoteAddress);
0
120};-
121-
122bool QUdpSocketPrivate::doEnsureInitialized(const QHostAddress &bindAddress, quint16 bindPort,-
123 const QHostAddress &remoteAddress)-
124{-
125 const QHostAddress *address = &bindAddress;-
126 QAbstractSocket::NetworkLayerProtocol proto = address->protocol();-
127 if (proto == QUdpSocket::UnknownNetworkLayerProtocol) {
proto == QUdpS...kLayerProtocolDescription
TRUEnever evaluated
FALSEevaluated 635 times by 3 tests
Evaluated by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
  • tst_qsocks5socketengine - unknown status
0-635
128 address = &remoteAddress;-
129 proto = address->protocol();-
130 }
never executed: end of block
0
131-
132 // now check if the socket engine is initialized and to the right type-
133 if (!socketEngine || !socketEngine->isValid()) {
!socketEngineDescription
TRUEevaluated 14 times by 2 tests
Evaluated by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
FALSEevaluated 621 times by 3 tests
Evaluated by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
  • tst_qsocks5socketengine - unknown status
!socketEngine->isValid()Description
TRUEnever evaluated
FALSEevaluated 621 times by 3 tests
Evaluated by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
  • tst_qsocks5socketengine - unknown status
0-621
134 resolveProxy(remoteAddress.toString(), bindPort);-
135 if (!initSocketLayer(address->protocol()))
!initSocketLay...s->protocol())Description
TRUEnever evaluated
FALSEevaluated 14 times by 2 tests
Evaluated by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
0-14
136 return false;
never executed: return false;
0
137 }
executed 14 times by 2 tests: end of block
Executed by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
14
138-
139 return true;
executed 635 times by 3 tests: return true;
Executed by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
  • tst_qsocks5socketengine - unknown status
635
140}-
141-
142/*!-
143 Creates a QUdpSocket object.-
144-
145 \a parent is passed to the QObject constructor.-
146-
147 \sa socketType()-
148*/-
149QUdpSocket::QUdpSocket(QObject *parent)-
150 : QAbstractSocket(UdpSocket, *new QUdpSocketPrivate, parent)-
151{-
152 d_func()->isBuffered = false;-
153}
executed 137 times by 3 tests: end of block
Executed by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
  • tst_qsocks5socketengine - unknown status
137
154-
155/*!-
156 Destroys the socket, closing the connection if necessary.-
157-
158 \sa close()-
159*/-
160QUdpSocket::~QUdpSocket()-
161{-
162}-
163-
164#ifndef QT_NO_NETWORKINTERFACE-
165-
166/*!-
167 \since 4.8-
168-
169 Joins the multicast group specified by \a groupAddress on the default-
170 interface chosen by the operating system. The socket must be in BoundState,-
171 otherwise an error occurs.-
172-
173 Note that if you are attempting to join an IPv4 group, your socket must not-
174 be bound using IPv6 (or in dual mode, using QHostAddress::Any). You must use-
175 QHostAddress::AnyIPv4 instead.-
176-
177 This function returns \c true if successful; otherwise it returns \c false-
178 and sets the socket error accordingly.-
179-
180 \sa leaveMulticastGroup()-
181*/-
182bool QUdpSocket::joinMulticastGroup(const QHostAddress &groupAddress)-
183{-
184 return joinMulticastGroup(groupAddress, QNetworkInterface());
executed 13 times by 1 test: return joinMulticastGroup(groupAddress, QNetworkInterface());
Executed by:
  • tst_QUdpSocket
13
185}-
186-
187/*!-
188 \since 4.8-
189 \overload-
190-
191 Joins the multicast group address \a groupAddress on the interface \a-
192 iface.-
193-
194 \sa leaveMulticastGroup()-
195*/-
196bool QUdpSocket::joinMulticastGroup(const QHostAddress &groupAddress,-
197 const QNetworkInterface &iface)-
198{-
199 Q_D(QUdpSocket);-
200 QT_CHECK_BOUND("QUdpSocket::joinMulticastGroup()", false);
executed 4 times by 1 test: return (false);
Executed by:
  • tst_QUdpSocket
!isValid()Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tst_QUdpSocket
FALSEevaluated 9 times by 1 test
Evaluated by:
  • tst_QUdpSocket
4-9
201 return d->socketEngine->joinMulticastGroup(groupAddress, iface);
executed 9 times by 1 test: return d->socketEngine->joinMulticastGroup(groupAddress, iface);
Executed by:
  • tst_QUdpSocket
9
202}-
203-
204/*!-
205 \since 4.8-
206-
207 Leaves the multicast group specified by \a groupAddress on the default-
208 interface chosen by the operating system. The socket must be in BoundState,-
209 otherwise an error occurs.-
210-
211 This function returns \c true if successful; otherwise it returns \c false and-
212 sets the socket error accordingly.-
213-
214 \sa joinMulticastGroup()-
215*/-
216bool QUdpSocket::leaveMulticastGroup(const QHostAddress &groupAddress)-
217{-
218 return leaveMulticastGroup(groupAddress, QNetworkInterface());
executed 6 times by 1 test: return leaveMulticastGroup(groupAddress, QNetworkInterface());
Executed by:
  • tst_QUdpSocket
6
219}-
220-
221/*!-
222 \since 4.8-
223 \overload-
224-
225 Leaves the multicast group specified by \a groupAddress on the interface \a-
226 iface.-
227-
228 \sa joinMulticastGroup()-
229*/-
230bool QUdpSocket::leaveMulticastGroup(const QHostAddress &groupAddress,-
231 const QNetworkInterface &iface)-
232{-
233 QT_CHECK_BOUND("QUdpSocket::leaveMulticastGroup()", false);
executed 2 times by 1 test: return (false);
Executed by:
  • tst_QUdpSocket
!isValid()Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tst_QUdpSocket
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tst_QUdpSocket
2-4
234 return d_func()->socketEngine->leaveMulticastGroup(groupAddress, iface);
executed 4 times by 1 test: return d_func()->socketEngine->leaveMulticastGroup(groupAddress, iface);
Executed by:
  • tst_QUdpSocket
4
235}-
236-
237/*!-
238 \since 4.8-
239-
240 Returns the interface for the outgoing interface for multicast datagrams.-
241 This corresponds to the IP_MULTICAST_IF socket option for IPv4 sockets and-
242 the IPV6_MULTICAST_IF socket option for IPv6 sockets. If no interface has-
243 been previously set, this function returns an invalid QNetworkInterface.-
244 The socket must be in BoundState, otherwise an invalid QNetworkInterface is-
245 returned.-
246-
247 \sa setMulticastInterface()-
248*/-
249QNetworkInterface QUdpSocket::multicastInterface() const-
250{-
251 Q_D(const QUdpSocket);-
252 QT_CHECK_BOUND("QUdpSocket::multicastInterface()", QNetworkInterface());
never executed: return (QNetworkInterface());
!isValid()Description
TRUEnever evaluated
FALSEevaluated 6 times by 1 test
Evaluated by:
  • tst_QUdpSocket
0-6
253 return d->socketEngine->multicastInterface();
executed 6 times by 1 test: return d->socketEngine->multicastInterface();
Executed by:
  • tst_QUdpSocket
6
254}-
255-
256/*!-
257 \since 4.8-
258-
259 Sets the outgoing interface for multicast datagrams to the interface \a-
260 iface. This corresponds to the IP_MULTICAST_IF socket option for IPv4-
261 sockets and the IPV6_MULTICAST_IF socket option for IPv6 sockets. The-
262 socket must be in BoundState, otherwise this function does nothing.-
263-
264 \sa multicastInterface(), joinMulticastGroup(), leaveMulticastGroup()-
265*/-
266void QUdpSocket::setMulticastInterface(const QNetworkInterface &iface)-
267{-
268 Q_D(QUdpSocket);-
269 if (!isValid()) {
!isValid()Description
TRUEnever evaluated
FALSEevaluated 6 times by 1 test
Evaluated by:
  • tst_QUdpSocket
0-6
270 qWarning("QUdpSocket::setMulticastInterface() called on a QUdpSocket when not in QUdpSocket::BoundState");-
271 return;
never executed: return;
0
272 }-
273 d->socketEngine->setMulticastInterface(iface);-
274}
executed 6 times by 1 test: end of block
Executed by:
  • tst_QUdpSocket
6
275-
276#endif // QT_NO_NETWORKINTERFACE-
277-
278/*!-
279 Returns \c true if at least one datagram is waiting to be read;-
280 otherwise returns \c false.-
281-
282 \sa pendingDatagramSize(), readDatagram()-
283*/-
284bool QUdpSocket::hasPendingDatagrams() const-
285{-
286 QT_CHECK_BOUND("QUdpSocket::hasPendingDatagrams()", false);
never executed: return (false);
!isValid()Description
TRUEnever evaluated
FALSEevaluated 662403 times by 2 tests
Evaluated by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
0-662403
287 return d_func()->socketEngine->hasPendingDatagrams();
executed 662403 times by 2 tests: return d_func()->socketEngine->hasPendingDatagrams();
Executed by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
662403
288}-
289-
290/*!-
291 Returns the size of the first pending UDP datagram. If there is-
292 no datagram available, this function returns -1.-
293-
294 \sa hasPendingDatagrams(), readDatagram()-
295*/-
296qint64 QUdpSocket::pendingDatagramSize() const-
297{-
298 QT_CHECK_BOUND("QUdpSocket::pendingDatagramSize()", -1);
never executed: return (-1);
!isValid()Description
TRUEnever evaluated
FALSEevaluated 592 times by 2 tests
Evaluated by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
0-592
299 return d_func()->socketEngine->pendingDatagramSize();
executed 592 times by 2 tests: return d_func()->socketEngine->pendingDatagramSize();
Executed by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
592
300}-
301-
302/*!-
303 Sends the datagram at \a data of size \a size to the host-
304 address \a address at port \a port. Returns the number of-
305 bytes sent on success; otherwise returns -1.-
306-
307 Datagrams are always written as one block. The maximum size of a-
308 datagram is highly platform-dependent, but can be as low as 8192-
309 bytes. If the datagram is too large, this function will return -1-
310 and error() will return DatagramTooLargeError.-
311-
312 Sending datagrams larger than 512 bytes is in general disadvised,-
313 as even if they are sent successfully, they are likely to be-
314 fragmented by the IP layer before arriving at their final-
315 destination.-
316-
317 \warning Calling this function on a connected UDP socket may-
318 result in an error and no packet being sent. If you are using a-
319 connected socket, use write() to send datagrams.-
320-
321 \sa readDatagram(), write()-
322*/-
323qint64 QUdpSocket::writeDatagram(const char *data, qint64 size, const QHostAddress &address,-
324 quint16 port)-
325{-
326 Q_D(QUdpSocket);-
327#if defined QUDPSOCKET_DEBUG-
328 qDebug("QUdpSocket::writeDatagram(%p, %llu, \"%s\", %i)", data, size,-
329 address.toString().toLatin1().constData(), port);-
330#endif-
331 if (!d->doEnsureInitialized(QHostAddress::Any, 0, address))
!d->doEnsureIn...y, 0, address)Description
TRUEnever evaluated
FALSEevaluated 635 times by 3 tests
Evaluated by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
  • tst_qsocks5socketengine - unknown status
0-635
332 return -1;
never executed: return -1;
0
333 if (state() == UnconnectedState)
state() == UnconnectedStateDescription
TRUEevaluated 14 times by 2 tests
Evaluated by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
FALSEevaluated 621 times by 3 tests
Evaluated by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
  • tst_qsocks5socketengine - unknown status
14-621
334 bind();
executed 14 times by 2 tests: bind();
Executed by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
14
335-
336 qint64 sent = d->socketEngine->writeDatagram(data, size, QIpPacketHeader(address, port));-
337 d->cachedSocketDescriptor = d->socketEngine->socketDescriptor();-
338-
339 if (sent >= 0) {
sent >= 0Description
TRUEevaluated 634 times by 3 tests
Evaluated by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
  • tst_qsocks5socketengine - unknown status
FALSEevaluated 1 time by 1 test
Evaluated by:
  • tst_QUdpSocket
1-634
340 emit bytesWritten(sent);-
341 } else {
executed 634 times by 3 tests: end of block
Executed by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
  • tst_qsocks5socketengine - unknown status
634
342 d->setErrorAndEmit(d->socketEngine->error(), d->socketEngine->errorString());-
343 }
executed 1 time by 1 test: end of block
Executed by:
  • tst_QUdpSocket
1
344 return sent;
executed 635 times by 3 tests: return sent;
Executed by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
  • tst_qsocks5socketengine - unknown status
635
345}-
346-
347/*!-
348 \fn qint64 QUdpSocket::writeDatagram(const QByteArray &datagram,-
349 const QHostAddress &host, quint16 port)-
350 \overload-
351-
352 Sends the datagram \a datagram to the host address \a host and at-
353 port \a port.-
354*/-
355-
356/*!-
357 Receives a datagram no larger than \a maxSize bytes and stores-
358 it in \a data. The sender's host address and port is stored in-
359 *\a address and *\a port (unless the pointers are 0).-
360-
361 Returns the size of the datagram on success; otherwise returns-
362 -1.-
363-
364 If \a maxSize is too small, the rest of the datagram will be-
365 lost. To avoid loss of data, call pendingDatagramSize() to-
366 determine the size of the pending datagram before attempting to-
367 read it. If \a maxSize is 0, the datagram will be discarded.-
368-
369 \sa writeDatagram(), hasPendingDatagrams(), pendingDatagramSize()-
370*/-
371qint64 QUdpSocket::readDatagram(char *data, qint64 maxSize, QHostAddress *address,-
372 quint16 *port)-
373{-
374 Q_D(QUdpSocket);-
375-
376#if defined QUDPSOCKET_DEBUG-
377 qDebug("QUdpSocket::readDatagram(%p, %llu, %p, %p)", data, maxSize, address, port);-
378#endif-
379 QT_CHECK_BOUND("QUdpSocket::readDatagram()", -1);
never executed: return (-1);
!isValid()Description
TRUEnever evaluated
FALSEevaluated 662427 times by 3 tests
Evaluated by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
  • tst_qsocks5socketengine - unknown status
0-662427
380-
381 qint64 readBytes;-
382 if (address || port) {
addressDescription
TRUEevaluated 507 times by 2 tests
Evaluated by:
  • tst_QUdpSocket
  • tst_qsocks5socketengine - unknown status
FALSEevaluated 661920 times by 2 tests
Evaluated by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
portDescription
TRUEnever evaluated
FALSEevaluated 661920 times by 2 tests
Evaluated by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
0-661920
383 QIpPacketHeader header;-
384 readBytes = d->socketEngine->readDatagram(data, maxSize, &header,-
385 QAbstractSocketEngine::WantDatagramSender);-
386 if (address)
addressDescription
TRUEevaluated 507 times by 2 tests
Evaluated by:
  • tst_QUdpSocket
  • tst_qsocks5socketengine - unknown status
FALSEnever evaluated
0-507
387 *address = header.senderAddress;
executed 507 times by 2 tests: *address = header.senderAddress;
Executed by:
  • tst_QUdpSocket
  • tst_qsocks5socketengine - unknown status
507
388 if (port)
portDescription
TRUEevaluated 507 times by 2 tests
Evaluated by:
  • tst_QUdpSocket
  • tst_qsocks5socketengine - unknown status
FALSEnever evaluated
0-507
389 *port = header.senderPort;
executed 507 times by 2 tests: *port = header.senderPort;
Executed by:
  • tst_QUdpSocket
  • tst_qsocks5socketengine - unknown status
507
390 } else {
executed 507 times by 2 tests: end of block
Executed by:
  • tst_QUdpSocket
  • tst_qsocks5socketengine - unknown status
507
391 readBytes = d->socketEngine->readDatagram(data, maxSize);-
392 }
executed 661920 times by 2 tests: end of block
Executed by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
661920
393-
394 d_func()->socketEngine->setReadNotificationEnabled(true);-
395 if (readBytes < 0)
readBytes < 0Description
TRUEnever evaluated
FALSEevaluated 662427 times by 3 tests
Evaluated by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
  • tst_qsocks5socketengine - unknown status
0-662427
396 d->setErrorAndEmit(d->socketEngine->error(), d->socketEngine->errorString());
never executed: d->setErrorAndEmit(d->socketEngine->error(), d->socketEngine->errorString());
0
397 return readBytes;
executed 662427 times by 3 tests: return readBytes;
Executed by:
  • tst_QUdpSocket
  • tst_qsocketnotifier - unknown status
  • tst_qsocks5socketengine - unknown status
662427
398}-
399#endif // QT_NO_UDPSOCKET-
400-
401QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9