Qt 4.8
qudpsocket.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtNetwork module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 //#define QUDPSOCKET_DEBUG
43 
162 #include "qhostaddress.h"
163 #include "qnetworkinterface.h"
164 #include "qabstractsocket_p.h"
165 #include "qudpsocket.h"
166 
168 
169 #ifndef QT_NO_UDPSOCKET
170 
171 #define QT_CHECK_BOUND(function, a) do { \
172  if (!isValid()) { \
173  qWarning(function" called on a QUdpSocket when not in QUdpSocket::BoundState"); \
174  return (a); \
175  } } while (0)
176 
178 {
180 
181  bool doEnsureInitialized(const QHostAddress &bindAddress, quint16 bindPort,
182  const QHostAddress &remoteAddress);
183 public:
184  inline bool ensureInitialized(const QHostAddress &bindAddress, quint16 bindPort)
185  { return doEnsureInitialized(bindAddress, bindPort, QHostAddress()); }
186 
187  inline bool ensureInitialized(const QHostAddress &remoteAddress)
188  { return doEnsureInitialized(QHostAddress(), 0, remoteAddress); }
189 };
190 
192  const QHostAddress &remoteAddress)
193 {
194  const QHostAddress *address = &bindAddress;
197  address = &remoteAddress;
198  proto = address->protocol();
199  }
200 
201 #if defined(QT_NO_IPV6)
202  Q_Q(QUdpSocket);
203  if (proto == QUdpSocket::IPv6Protocol) {
205  q->setErrorString(QUdpSocket::tr("This platform does not support IPv6"));
206  return false;
207  }
208 #endif
209 
210  // now check if the socket engine is initialized and to the right type
211  if (!socketEngine || !socketEngine->isValid()) {
212  resolveProxy(remoteAddress.toString(), bindPort);
213  if (!initSocketLayer(address->protocol()))
214  return false;
215  }
216 
217  return true;
218 }
219 
228  : QAbstractSocket(UdpSocket, *new QUdpSocketPrivate, parent)
229 {
230  d_func()->isBuffered = false;
231 }
232 
239 {
240 }
241 
255 bool QUdpSocket::bind(const QHostAddress &address, quint16 port)
256 {
257  Q_D(QUdpSocket);
258  if (!d->ensureInitialized(address, port))
259  return false;
260 
261  bool result = d_func()->socketEngine->bind(address, port);
262  d->cachedSocketDescriptor = d->socketEngine->socketDescriptor();
263 
264  if (!result) {
265  d->socketError = d_func()->socketEngine->error();
266  setErrorString(d_func()->socketEngine->errorString());
267  emit error(d_func()->socketError);
268  return false;
269  }
270 
271  d->state = BoundState;
272  d->localAddress = d->socketEngine->localAddress();
273  d->localPort = d->socketEngine->localPort();
274 
275  emit stateChanged(d_func()->state);
276  d_func()->socketEngine->setReadNotificationEnabled(true);
277  return true;
278 }
279 
289 bool QUdpSocket::bind(const QHostAddress &address, quint16 port, BindMode mode)
290 {
291  Q_D(QUdpSocket);
292  if (!d->ensureInitialized(address, port))
293  return false;
294 
295 #ifdef Q_OS_UNIX
296  if ((mode & ShareAddress) || (mode & ReuseAddressHint))
297  d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 1);
298  else
299  d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 0);
300 #endif
301 #ifdef Q_OS_WIN
302  if (mode & ReuseAddressHint)
303  d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 1);
304  else
305  d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 0);
306  if (mode & DontShareAddress)
307  d->socketEngine->setOption(QAbstractSocketEngine::BindExclusively, 1);
308  else
309  d->socketEngine->setOption(QAbstractSocketEngine::BindExclusively, 0);
310 #endif
311  bool result = d_func()->socketEngine->bind(address, port);
312  d->cachedSocketDescriptor = d->socketEngine->socketDescriptor();
313 
314  if (!result) {
315  d->socketError = d_func()->socketEngine->error();
316  setErrorString(d_func()->socketEngine->errorString());
317  emit error(d_func()->socketError);
318  return false;
319  }
320 
321  d->state = BoundState;
322  d->localAddress = d->socketEngine->localAddress();
323  d->localPort = d->socketEngine->localPort();
324 
325  emit stateChanged(d_func()->state);
326  d_func()->socketEngine->setReadNotificationEnabled(true);
327  return true;
328 }
329 
338 {
339  return bind(QHostAddress::Any, port);
340 }
341 
351 bool QUdpSocket::bind(quint16 port, BindMode mode)
352 {
353  return bind(QHostAddress::Any, port, mode);
354 }
355 
356 #ifndef QT_NO_NETWORKINTERFACE
357 
374 {
375  return joinMulticastGroup(groupAddress, QNetworkInterface());
376 }
377 
391  const QNetworkInterface &iface)
392 {
393  Q_D(QUdpSocket);
394  QT_CHECK_BOUND("QUdpSocket::joinMulticastGroup()", false);
395  return d->socketEngine->joinMulticastGroup(groupAddress, iface);
396 }
397 
414 {
415  return leaveMulticastGroup(groupAddress, QNetworkInterface());
416 }
417 
431  const QNetworkInterface &iface)
432 {
433  QT_CHECK_BOUND("QUdpSocket::leaveMulticastGroup()", false);
434  return d_func()->socketEngine->leaveMulticastGroup(groupAddress, iface);
435 }
436 
453 {
454  Q_D(const QUdpSocket);
455  QT_CHECK_BOUND("QUdpSocket::multicastInterface()", QNetworkInterface());
456  return d->socketEngine->multicastInterface();
457 }
458 
473 {
474  Q_D(QUdpSocket);
475  if (!isValid()) {
476  qWarning("QUdpSocket::setMulticastInterface() called on a QUdpSocket when not in QUdpSocket::BoundState");
477  return;
478  }
479  d->socketEngine->setMulticastInterface(iface);
480 }
481 
482 #endif // QT_NO_NETWORKINTERFACE
483 
491 {
492  QT_CHECK_BOUND("QUdpSocket::hasPendingDatagrams()", false);
493  return d_func()->socketEngine->hasPendingDatagrams();
494 }
495 
503 {
504  QT_CHECK_BOUND("QUdpSocket::pendingDatagramSize()", -1);
505  return d_func()->socketEngine->pendingDatagramSize();
506 }
507 
533  quint16 port)
534 {
535  Q_D(QUdpSocket);
536 #if defined QUDPSOCKET_DEBUG
537  qDebug("QUdpSocket::writeDatagram(%p, %llu, \"%s\", %i)", data, size,
538  address.toString().toLatin1().constData(), port);
539 #endif
540  if (!d->ensureInitialized(address))
541  return -1;
542 
543  qint64 sent = d->socketEngine->writeDatagram(data, size, address, port);
544  d->cachedSocketDescriptor = d->socketEngine->socketDescriptor();
545 
546  if (sent >= 0) {
547  emit bytesWritten(sent);
548  } else {
549  d->socketError = d->socketEngine->error();
550  setErrorString(d->socketEngine->errorString());
551  emit error(d->socketError);
552  }
553  return sent;
554 }
555 
584  quint16 *port)
585 {
586  Q_D(QUdpSocket);
587 
588 #if defined QUDPSOCKET_DEBUG
589  qDebug("QUdpSocket::readDatagram(%p, %llu, %p, %p)", data, maxSize, address, port);
590 #endif
591  QT_CHECK_BOUND("QUdpSocket::readDatagram()", -1);
592  qint64 readBytes = d->socketEngine->readDatagram(data, maxSize, address, port);
593  d_func()->socketEngine->setReadNotificationEnabled(true);
594  if (readBytes < 0) {
595  d->socketError = d->socketEngine->error();
596  setErrorString(d->socketEngine->errorString());
597  emit error(d->socketError);
598  }
599  return readBytes;
600 }
601 #endif // QT_NO_UDPSOCKET
602 
double d
Definition: qnumeric_p.h:62
virtual ~QUdpSocket()
Destroys the socket, closing the connection if necessary.
Definition: qudpsocket.cpp:238
virtual qint64 size() const
For open random-access devices, this function returns the size of the device.
Definition: qiodevice.cpp:642
The QUdpSocket class provides a UDP socket.
Definition: qudpsocket.h:59
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QUdpSocket(QObject *parent=0)
Creates a QUdpSocket object.
Definition: qudpsocket.cpp:227
static QString tr(const char *sourceText, const char *comment=0, int n=-1)
void bytesWritten(qint64 bytes)
This signal is emitted every time a payload of data has been written to the device.
NetworkLayerProtocol
This enum describes the network layer protocol values used in Qt.
bool hasPendingDatagrams() const
Returns true if at least one datagram is waiting to be read; otherwise returns false.
Definition: qudpsocket.cpp:490
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
#define Q_D(Class)
Definition: qglobal.h:2482
qint64 pendingDatagramSize() const
Returns the size of the first pending UDP datagram.
Definition: qudpsocket.cpp:502
#define QT_CHECK_BOUND(function, a)
Definition: qudpsocket.cpp:171
bool bind(const QHostAddress &address, quint16 port)
Binds this socket to the address address and the port port.
Definition: qudpsocket.cpp:255
#define Q_Q(Class)
Definition: qglobal.h:2483
Q_CORE_EXPORT void qDebug(const char *,...)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
bool ensureInitialized(const QHostAddress &bindAddress, quint16 bindPort)
Definition: qudpsocket.cpp:184
#define emit
Definition: qobjectdefs.h:76
unsigned short quint16
Definition: qglobal.h:936
Q_CORE_EXPORT void qWarning(const char *,...)
QAbstractSocket::SocketError socketError
static const char * data(const QByteArray &arr)
QString toString() const
Returns the address as a string.
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
bool ensureInitialized(const QHostAddress &remoteAddress)
Definition: qudpsocket.cpp:187
__int64 qint64
Definition: qglobal.h:942
bool joinMulticastGroup(const QHostAddress &groupAddress)
Joins the the multicast group specified by groupAddress on the default interface chosen by the operat...
Definition: qudpsocket.cpp:373
qint64 writeDatagram(const char *data, qint64 len, const QHostAddress &host, quint16 port)
Sends the datagram at data of size size to the host address address at port port. ...
Definition: qudpsocket.cpp:532
bool doEnsureInitialized(const QHostAddress &bindAddress, quint16 bindPort, const QHostAddress &remoteAddress)
Definition: qudpsocket.cpp:191
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
#define Q_DECLARE_PUBLIC(Class)
Definition: qglobal.h:2477
QAbstractSocket::NetworkLayerProtocol protocol() const
Returns the network layer protocol of the host address.
void setMulticastInterface(const QNetworkInterface &iface)
Sets the outgoing interface for multicast datagrams to the interface iface.
Definition: qudpsocket.cpp:472
void setErrorString(const QString &errorString)
Sets the human readable description of the last device error that occurred to str.
Definition: qiodevice.cpp:1660
QAbstractSocketEngine * socketEngine
QNetworkInterface multicastInterface() const
Returns the interface for the outgoing interface for multicast datagrams.
Definition: qudpsocket.cpp:452
bool leaveMulticastGroup(const QHostAddress &groupAddress)
Leaves the multicast group specified by groupAddress on the default interface chosen by the operating...
Definition: qudpsocket.cpp:413
QObject * parent
Definition: qobject.h:92
void stateChanged(QAbstractSocket::SocketState)
This signal is emitted whenever QAbstractSocket&#39;s state changes.
bool initSocketLayer(QAbstractSocket::NetworkLayerProtocol protocol)
Initializes the socket layer to by of type type, using the network layer protocol protocol...
void resolveProxy(const QString &hostName, quint16 port)
Resolve the proxy to its final value.
virtual bool isValid() const =0
The QNetworkInterface class provides a listing of the host&#39;s IP addresses and network interfaces...
The QHostAddress class provides an IP address.
Definition: qhostaddress.h:70
SocketError error() const
Returns the type of error that last occurred.
The QAbstractSocket class provides the base functionality common to all socket types.
qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *host=0, quint16 *port=0)
Receives a datagram no larger than maxSize bytes and stores it in data.
Definition: qudpsocket.cpp:583
SocketState state() const
Returns the state of the socket.
bool isValid() const
Returns true if the socket is valid and ready for use; otherwise returns false.