Move support for socket binding from QUdpSocket upstream to QAbstractSocket.
This should be API-compatible with Qt 4, but is not ABI-compatible, due to removing the enum from QUdpSocket. Task-number: QTBUG-121 Change-Id: I967968c6cb6f96d3ab1d6300eadd5bde6154b300 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
3aa81c55e2
commit
03f852cb47
@ -291,10 +291,10 @@
|
|||||||
bytes).
|
bytes).
|
||||||
\value NetworkError An error occurred with the network (e.g., the
|
\value NetworkError An error occurred with the network (e.g., the
|
||||||
network cable was accidentally plugged out).
|
network cable was accidentally plugged out).
|
||||||
\value AddressInUseError The address specified to QUdpSocket::bind() is
|
\value AddressInUseError The address specified to QAbstractSocket::bind() is
|
||||||
already in use and was set to be exclusive.
|
already in use and was set to be exclusive.
|
||||||
\value SocketAddressNotAvailableError The address specified to
|
\value SocketAddressNotAvailableError The address specified to
|
||||||
QUdpSocket::bind() does not belong to the host.
|
QAbstractSocket::bind() does not belong to the host.
|
||||||
\value UnsupportedSocketOperationError The requested socket operation is
|
\value UnsupportedSocketOperationError The requested socket operation is
|
||||||
not supported by the local operating system (e.g., lack of
|
not supported by the local operating system (e.g., lack of
|
||||||
IPv6 support).
|
IPv6 support).
|
||||||
@ -329,7 +329,7 @@
|
|||||||
\value HostLookupState The socket is performing a host name lookup.
|
\value HostLookupState The socket is performing a host name lookup.
|
||||||
\value ConnectingState The socket has started establishing a connection.
|
\value ConnectingState The socket has started establishing a connection.
|
||||||
\value ConnectedState A connection is established.
|
\value ConnectedState A connection is established.
|
||||||
\value BoundState The socket is bound to an address and port (for servers).
|
\value BoundState The socket is bound to an address and port.
|
||||||
\value ClosingState The socket is about to close (data may still
|
\value ClosingState The socket is about to close (data may still
|
||||||
be waiting to be written).
|
be waiting to be written).
|
||||||
\value ListeningState For internal use only.
|
\value ListeningState For internal use only.
|
||||||
@ -363,6 +363,51 @@
|
|||||||
\sa QAbstractSocket::setSocketOption(), QAbstractSocket::socketOption()
|
\sa QAbstractSocket::setSocketOption(), QAbstractSocket::socketOption()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*! \enum QAbstractSocket::BindFlag
|
||||||
|
\since 5.0
|
||||||
|
|
||||||
|
This enum describes the different flags you can pass to modify the
|
||||||
|
behavior of QAbstractSocket::bind().
|
||||||
|
|
||||||
|
\note On Symbian OS bind flags behaviour depends on process capabilties.
|
||||||
|
If process has NetworkControl capability, the bind attempt with
|
||||||
|
ReuseAddressHint will always succeed even if the address and port is already
|
||||||
|
bound by another socket with any flags. If process does not have
|
||||||
|
NetworkControl capability, the bind attempt to address and port already
|
||||||
|
bound by another socket will always fail.
|
||||||
|
|
||||||
|
\value ShareAddress Allow other services to bind to the same address
|
||||||
|
and port. This is useful when multiple processes share
|
||||||
|
the load of a single service by listening to the same address and port
|
||||||
|
(e.g., a web server with several pre-forked listeners can greatly
|
||||||
|
improve response time). However, because any service is allowed to
|
||||||
|
rebind, this option is subject to certain security considerations.
|
||||||
|
Note that by combining this option with ReuseAddressHint, you will
|
||||||
|
also allow your service to rebind an existing shared address. On
|
||||||
|
Unix, this is equivalent to the SO_REUSEADDR socket option. On Windows,
|
||||||
|
this option is ignored.
|
||||||
|
|
||||||
|
\value DontShareAddress Bind the address and port exclusively, so that
|
||||||
|
no other services are allowed to rebind. By passing this option to
|
||||||
|
QAbstractSocket::bind(), you are guaranteed that on successs, your service
|
||||||
|
is the only one that listens to the address and port. No services are
|
||||||
|
allowed to rebind, even if they pass ReuseAddressHint. This option
|
||||||
|
provides more security than ShareAddress, but on certain operating
|
||||||
|
systems, it requires you to run the server with administrator privileges.
|
||||||
|
On Unix and Mac OS X, not sharing is the default behavior for binding
|
||||||
|
an address and port, so this option is ignored. On Windows, this
|
||||||
|
option uses the SO_EXCLUSIVEADDRUSE socket option.
|
||||||
|
|
||||||
|
\value ReuseAddressHint Provides a hint to QAbstractSocket that it should try
|
||||||
|
to rebind the service even if the address and port are already bound by
|
||||||
|
another socket. On Windows, this is equivalent to the SO_REUSEADDR
|
||||||
|
socket option. On Unix, this option is ignored.
|
||||||
|
|
||||||
|
\value DefaultForPlatform The default option for the current platform.
|
||||||
|
On Unix and Mac OS X, this is equivalent to (DontShareAddress
|
||||||
|
+ ReuseAddressHint), and on Windows, its equivalent to ShareAddress.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "qabstractsocket.h"
|
#include "qabstractsocket.h"
|
||||||
#include "qabstractsocket_p.h"
|
#include "qabstractsocket_p.h"
|
||||||
|
|
||||||
@ -1293,6 +1338,94 @@ QAbstractSocket::~QAbstractSocket()
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.0
|
||||||
|
|
||||||
|
Binds to \a address on port \a port, using the BindMode \a mode.
|
||||||
|
|
||||||
|
Binds this socket to the address \a address and the port \a port.
|
||||||
|
|
||||||
|
For UDP sockets, after binding, the signal QUdpSocket::readyRead() is emitted
|
||||||
|
whenever a UDP datagram arrives on the specified address and port.
|
||||||
|
Thus, This function is useful to write UDP servers.
|
||||||
|
|
||||||
|
For TCP sockets, this function may be used to specify which interface to use
|
||||||
|
for an outgoing connection, which is useful in case of multiple network
|
||||||
|
interfaces.
|
||||||
|
|
||||||
|
By default, the socket is bound using the DefaultForPlatform BindMode.
|
||||||
|
If a port is not specified, a random port is chosen.
|
||||||
|
|
||||||
|
On success, the functions returns true and the socket enters
|
||||||
|
BoundState; otherwise it returns false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
bool QAbstractSocket::bind(const QHostAddress &address, quint16 port, BindMode mode)
|
||||||
|
{
|
||||||
|
Q_D(QAbstractSocket);
|
||||||
|
|
||||||
|
// now check if the socket engine is initialized and to the right type
|
||||||
|
if (!d->socketEngine || !d->socketEngine->isValid()) {
|
||||||
|
QHostAddress nullAddress;
|
||||||
|
d->resolveProxy(nullAddress.toString(), port);
|
||||||
|
|
||||||
|
QAbstractSocket::NetworkLayerProtocol protocol = address.protocol();
|
||||||
|
if (protocol == QAbstractSocket::UnknownNetworkLayerProtocol)
|
||||||
|
protocol = nullAddress.protocol();
|
||||||
|
|
||||||
|
if (!d->initSocketLayer(protocol))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_UNIX
|
||||||
|
if ((mode & ShareAddress) || (mode & ReuseAddressHint))
|
||||||
|
d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 1);
|
||||||
|
else
|
||||||
|
d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 0);
|
||||||
|
#endif
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
if (mode & ReuseAddressHint)
|
||||||
|
d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 1);
|
||||||
|
else
|
||||||
|
d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 0);
|
||||||
|
if (mode & DontShareAddress)
|
||||||
|
d->socketEngine->setOption(QAbstractSocketEngine::BindExclusively, 1);
|
||||||
|
else
|
||||||
|
d->socketEngine->setOption(QAbstractSocketEngine::BindExclusively, 0);
|
||||||
|
#endif
|
||||||
|
bool result = d->socketEngine->bind(address, port);
|
||||||
|
d->cachedSocketDescriptor = d->socketEngine->socketDescriptor();
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
d->socketError = d->socketEngine->error();
|
||||||
|
setErrorString(d->socketEngine->errorString());
|
||||||
|
emit error(d->socketError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->state = BoundState;
|
||||||
|
d->localAddress = d->socketEngine->localAddress();
|
||||||
|
d->localPort = d->socketEngine->localPort();
|
||||||
|
|
||||||
|
emit stateChanged(d->state);
|
||||||
|
d->socketEngine->setReadNotificationEnabled(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 5.0
|
||||||
|
\overload
|
||||||
|
|
||||||
|
Binds to QHostAddress:Any on port \a port, using the BindMode \a mode.
|
||||||
|
|
||||||
|
By default, the socket is bound using the DefaultForPlatform BindMode.
|
||||||
|
If a port is not specified, a random port is chosen.
|
||||||
|
*/
|
||||||
|
bool QAbstractSocket::bind(quint16 port, BindMode mode)
|
||||||
|
{
|
||||||
|
return bind(QHostAddress::Any, port, mode);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns true if the socket is valid and ready for use; otherwise
|
Returns true if the socket is valid and ready for use; otherwise
|
||||||
returns false.
|
returns false.
|
||||||
@ -2345,7 +2478,7 @@ qint64 QAbstractSocket::writeData(const char *data, qint64 size)
|
|||||||
proxy connections for virtual connection settings.
|
proxy connections for virtual connection settings.
|
||||||
|
|
||||||
Note that this function does not bind the local port of the socket
|
Note that this function does not bind the local port of the socket
|
||||||
prior to a connection (e.g., QUdpSocket::bind()).
|
prior to a connection (e.g., QAbstractSocket::bind()).
|
||||||
|
|
||||||
\sa localAddress(), setLocalAddress(), setPeerPort()
|
\sa localAddress(), setLocalAddress(), setPeerPort()
|
||||||
*/
|
*/
|
||||||
@ -2367,7 +2500,7 @@ void QAbstractSocket::setLocalPort(quint16 port)
|
|||||||
proxy connections for virtual connection settings.
|
proxy connections for virtual connection settings.
|
||||||
|
|
||||||
Note that this function does not bind the local address of the socket
|
Note that this function does not bind the local address of the socket
|
||||||
prior to a connection (e.g., QUdpSocket::bind()).
|
prior to a connection (e.g., QAbstractSocket::bind()).
|
||||||
|
|
||||||
\sa localAddress(), setLocalPort(), setPeerAddress()
|
\sa localAddress(), setLocalPort(), setPeerAddress()
|
||||||
*/
|
*/
|
||||||
|
@ -115,10 +115,20 @@ public:
|
|||||||
MulticastTtlOption, // IP_MULTICAST_TTL
|
MulticastTtlOption, // IP_MULTICAST_TTL
|
||||||
MulticastLoopbackOption // IP_MULTICAST_LOOPBACK
|
MulticastLoopbackOption // IP_MULTICAST_LOOPBACK
|
||||||
};
|
};
|
||||||
|
enum BindFlag {
|
||||||
|
DefaultForPlatform = 0x0,
|
||||||
|
ShareAddress = 0x1,
|
||||||
|
DontShareAddress = 0x2,
|
||||||
|
ReuseAddressHint = 0x4
|
||||||
|
};
|
||||||
|
Q_DECLARE_FLAGS(BindMode, BindFlag)
|
||||||
|
|
||||||
QAbstractSocket(SocketType socketType, QObject *parent);
|
QAbstractSocket(SocketType socketType, QObject *parent);
|
||||||
virtual ~QAbstractSocket();
|
virtual ~QAbstractSocket();
|
||||||
|
|
||||||
|
bool bind(const QHostAddress &address, quint16 port = 0, BindMode mode = DefaultForPlatform);
|
||||||
|
bool bind(quint16 port = 0, BindMode mode = DefaultForPlatform);
|
||||||
|
|
||||||
// ### Qt 5: Make connectToHost() and disconnectFromHost() virtual.
|
// ### Qt 5: Make connectToHost() and disconnectFromHost() virtual.
|
||||||
void connectToHost(const QString &hostName, quint16 port, OpenMode mode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol);
|
void connectToHost(const QString &hostName, quint16 port, OpenMode mode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol);
|
||||||
void connectToHost(const QHostAddress &address, quint16 port, OpenMode mode = ReadWrite);
|
void connectToHost(const QHostAddress &address, quint16 port, OpenMode mode = ReadWrite);
|
||||||
@ -214,6 +224,9 @@ private:
|
|||||||
Q_PRIVATE_SLOT(d_func(), void _q_forceDisconnect())
|
Q_PRIVATE_SLOT(d_func(), void _q_forceDisconnect())
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractSocket::BindMode)
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
Q_NETWORK_EXPORT QDebug operator<<(QDebug, QAbstractSocket::SocketError);
|
Q_NETWORK_EXPORT QDebug operator<<(QDebug, QAbstractSocket::SocketError);
|
||||||
Q_NETWORK_EXPORT QDebug operator<<(QDebug, QAbstractSocket::SocketState);
|
Q_NETWORK_EXPORT QDebug operator<<(QDebug, QAbstractSocket::SocketState);
|
||||||
|
@ -108,51 +108,6 @@
|
|||||||
\sa QTcpSocket
|
\sa QTcpSocket
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \enum QUdpSocket::BindFlag
|
|
||||||
\since 4.1
|
|
||||||
|
|
||||||
This enum describes the different flags you can pass to modify the
|
|
||||||
behavior of QUdpSocket::bind().
|
|
||||||
|
|
||||||
\note On Symbian OS bind flags behaviour depends on process capabilties.
|
|
||||||
If process has NetworkControl capability, the bind attempt with
|
|
||||||
ReuseAddressHint will always succeed even if the address and port is already
|
|
||||||
bound by another socket with any flags. If process does not have
|
|
||||||
NetworkControl capability, the bind attempt to address and port already
|
|
||||||
bound by another socket will always fail.
|
|
||||||
|
|
||||||
\value ShareAddress Allow other services to bind to the same address
|
|
||||||
and port. This is useful when multiple processes share
|
|
||||||
the load of a single service by listening to the same address and port
|
|
||||||
(e.g., a web server with several pre-forked listeners can greatly
|
|
||||||
improve response time). However, because any service is allowed to
|
|
||||||
rebind, this option is subject to certain security considerations.
|
|
||||||
Note that by combining this option with ReuseAddressHint, you will
|
|
||||||
also allow your service to rebind an existing shared address. On
|
|
||||||
Unix, this is equivalent to the SO_REUSEADDR socket option. On Windows,
|
|
||||||
this option is ignored.
|
|
||||||
|
|
||||||
\value DontShareAddress Bind the address and port exclusively, so that
|
|
||||||
no other services are allowed to rebind. By passing this option to
|
|
||||||
QUdpSocket::bind(), you are guaranteed that on successs, your service
|
|
||||||
is the only one that listens to the address and port. No services are
|
|
||||||
allowed to rebind, even if they pass ReuseAddressHint. This option
|
|
||||||
provides more security than ShareAddress, but on certain operating
|
|
||||||
systems, it requires you to run the server with administrator privileges.
|
|
||||||
On Unix and Mac OS X, not sharing is the default behavior for binding
|
|
||||||
an address and port, so this option is ignored. On Windows, this
|
|
||||||
option uses the SO_EXCLUSIVEADDRUSE socket option.
|
|
||||||
|
|
||||||
\value ReuseAddressHint Provides a hint to QUdpSocket that it should try
|
|
||||||
to rebind the service even if the address and port are already bound by
|
|
||||||
another socket. On Windows, this is equivalent to the SO_REUSEADDR
|
|
||||||
socket option. On Unix, this option is ignored.
|
|
||||||
|
|
||||||
\value DefaultForPlatform The default option for the current platform.
|
|
||||||
On Unix and Mac OS X, this is equivalent to (DontShareAddress
|
|
||||||
+ ReuseAddressHint), and on Windows, its equivalent to ShareAddress.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "qhostaddress.h"
|
#include "qhostaddress.h"
|
||||||
#include "qnetworkinterface.h"
|
#include "qnetworkinterface.h"
|
||||||
#include "qabstractsocket_p.h"
|
#include "qabstractsocket_p.h"
|
||||||
@ -224,111 +179,6 @@ QUdpSocket::~QUdpSocket()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
Binds this socket to the address \a address and the port \a port.
|
|
||||||
When bound, the signal readyRead() is emitted whenever a UDP
|
|
||||||
datagram arrives on the specified address and port. This function
|
|
||||||
is useful to write UDP servers.
|
|
||||||
|
|
||||||
On success, the functions returns true and the socket enters
|
|
||||||
BoundState; otherwise it returns false.
|
|
||||||
|
|
||||||
The socket is bound using the DefaultForPlatform BindMode.
|
|
||||||
|
|
||||||
\sa readDatagram()
|
|
||||||
*/
|
|
||||||
bool QUdpSocket::bind(const QHostAddress &address, quint16 port)
|
|
||||||
{
|
|
||||||
Q_D(QUdpSocket);
|
|
||||||
if (!d->ensureInitialized(address, port))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
bool result = d_func()->socketEngine->bind(address, port);
|
|
||||||
d->cachedSocketDescriptor = d->socketEngine->socketDescriptor();
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
d->socketError = d_func()->socketEngine->error();
|
|
||||||
setErrorString(d_func()->socketEngine->errorString());
|
|
||||||
emit error(d_func()->socketError);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->state = BoundState;
|
|
||||||
d->localAddress = d->socketEngine->localAddress();
|
|
||||||
d->localPort = d->socketEngine->localPort();
|
|
||||||
|
|
||||||
emit stateChanged(d_func()->state);
|
|
||||||
d_func()->socketEngine->setReadNotificationEnabled(true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\since 4.1
|
|
||||||
\overload
|
|
||||||
|
|
||||||
Binds to \a address on port \a port, using the BindMode \a mode.
|
|
||||||
*/
|
|
||||||
bool QUdpSocket::bind(const QHostAddress &address, quint16 port, BindMode mode)
|
|
||||||
{
|
|
||||||
Q_D(QUdpSocket);
|
|
||||||
if (!d->ensureInitialized(address, port))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX
|
|
||||||
if ((mode & ShareAddress) || (mode & ReuseAddressHint))
|
|
||||||
d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 1);
|
|
||||||
else
|
|
||||||
d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 0);
|
|
||||||
#endif
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
if (mode & ReuseAddressHint)
|
|
||||||
d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 1);
|
|
||||||
else
|
|
||||||
d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 0);
|
|
||||||
if (mode & DontShareAddress)
|
|
||||||
d->socketEngine->setOption(QAbstractSocketEngine::BindExclusively, 1);
|
|
||||||
else
|
|
||||||
d->socketEngine->setOption(QAbstractSocketEngine::BindExclusively, 0);
|
|
||||||
#endif
|
|
||||||
bool result = d_func()->socketEngine->bind(address, port);
|
|
||||||
d->cachedSocketDescriptor = d->socketEngine->socketDescriptor();
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
d->socketError = d_func()->socketEngine->error();
|
|
||||||
setErrorString(d_func()->socketEngine->errorString());
|
|
||||||
emit error(d_func()->socketError);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->state = BoundState;
|
|
||||||
d->localAddress = d->socketEngine->localAddress();
|
|
||||||
d->localPort = d->socketEngine->localPort();
|
|
||||||
|
|
||||||
emit stateChanged(d_func()->state);
|
|
||||||
d_func()->socketEngine->setReadNotificationEnabled(true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \overload
|
|
||||||
|
|
||||||
Binds to QHostAddress:Any on port \a port.
|
|
||||||
*/
|
|
||||||
bool QUdpSocket::bind(quint16 port)
|
|
||||||
{
|
|
||||||
return bind(QHostAddress::Any, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\since 4.1
|
|
||||||
\overload
|
|
||||||
|
|
||||||
Binds to QHostAddress:Any on port \a port, using the BindMode \a mode.
|
|
||||||
*/
|
|
||||||
bool QUdpSocket::bind(quint16 port, BindMode mode)
|
|
||||||
{
|
|
||||||
return bind(QHostAddress::Any, port, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef QT_NO_NETWORKINTERFACE
|
#ifndef QT_NO_NETWORKINTERFACE
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -60,23 +60,9 @@ class Q_NETWORK_EXPORT QUdpSocket : public QAbstractSocket
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum BindFlag {
|
|
||||||
DefaultForPlatform = 0x0,
|
|
||||||
ShareAddress = 0x1,
|
|
||||||
DontShareAddress = 0x2,
|
|
||||||
ReuseAddressHint = 0x4
|
|
||||||
};
|
|
||||||
Q_DECLARE_FLAGS(BindMode, BindFlag)
|
|
||||||
|
|
||||||
explicit QUdpSocket(QObject *parent = 0);
|
explicit QUdpSocket(QObject *parent = 0);
|
||||||
virtual ~QUdpSocket();
|
virtual ~QUdpSocket();
|
||||||
|
|
||||||
bool bind(const QHostAddress &address, quint16 port);
|
|
||||||
bool bind(quint16 port = 0);
|
|
||||||
bool bind(const QHostAddress &address, quint16 port, BindMode mode);
|
|
||||||
bool bind(quint16 port, BindMode mode);
|
|
||||||
// ### Qt 5: Merge the bind functions
|
|
||||||
|
|
||||||
#ifndef QT_NO_NETWORKINTERFACE
|
#ifndef QT_NO_NETWORKINTERFACE
|
||||||
bool joinMulticastGroup(const QHostAddress &groupAddress);
|
bool joinMulticastGroup(const QHostAddress &groupAddress);
|
||||||
bool joinMulticastGroup(const QHostAddress &groupAddress,
|
bool joinMulticastGroup(const QHostAddress &groupAddress,
|
||||||
@ -101,8 +87,6 @@ private:
|
|||||||
Q_DECLARE_PRIVATE(QUdpSocket)
|
Q_DECLARE_PRIVATE(QUdpSocket)
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QUdpSocket::BindMode)
|
|
||||||
|
|
||||||
#endif // QT_NO_UDPSOCKET
|
#endif // QT_NO_UDPSOCKET
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -138,6 +138,8 @@ public slots:
|
|||||||
private slots:
|
private slots:
|
||||||
void socketsConstructedBeforeEventLoop();
|
void socketsConstructedBeforeEventLoop();
|
||||||
void constructing();
|
void constructing();
|
||||||
|
void bind_data();
|
||||||
|
void bind();
|
||||||
void setInvalidSocketDescriptor();
|
void setInvalidSocketDescriptor();
|
||||||
void setSocketDescriptor();
|
void setSocketDescriptor();
|
||||||
void socketDescriptor();
|
void socketDescriptor();
|
||||||
@ -479,6 +481,65 @@ void tst_QTcpSocket::constructing()
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void tst_QTcpSocket::bind_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QString>("stringAddr");
|
||||||
|
QTest::addColumn<bool>("successExpected");
|
||||||
|
QTest::addColumn<QString>("stringExpectedLocalAddress");
|
||||||
|
|
||||||
|
// iterate all interfaces, add all addresses on them as test data
|
||||||
|
QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
|
||||||
|
foreach (const QNetworkInterface &interface, interfaces) {
|
||||||
|
if (!interface.isValid())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (const QNetworkAddressEntry &entry, interface.addressEntries()) {
|
||||||
|
if (entry.ip().isInSubnet(QHostAddress::parseSubnet("fe80::/10")))
|
||||||
|
continue; // link-local bind will fail, at least on Linux, so skip it.
|
||||||
|
|
||||||
|
QString ip(entry.ip().toString());
|
||||||
|
QTest::newRow(ip.toLatin1().constData()) << ip << true << ip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// additionally, try bind to known-bad addresses, and make sure this doesn't work
|
||||||
|
// these ranges are guarenteed to be reserved for 'documentation purposes',
|
||||||
|
// and thus, should be unused in the real world. Not that I'm assuming the
|
||||||
|
// world is full of competent administrators, or anything.
|
||||||
|
QStringList knownBad;
|
||||||
|
knownBad << "198.51.100.1";
|
||||||
|
knownBad << "2001:0DB8::1";
|
||||||
|
foreach (const QString &badAddress, knownBad) {
|
||||||
|
QTest::newRow(badAddress.toLatin1().constData()) << badAddress << false << QString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QTcpSocket::bind()
|
||||||
|
{
|
||||||
|
QFETCH(QString, stringAddr);
|
||||||
|
QFETCH(bool, successExpected);
|
||||||
|
QFETCH(QString, stringExpectedLocalAddress);
|
||||||
|
|
||||||
|
QHostAddress addr(stringAddr);
|
||||||
|
QHostAddress expectedLocalAddress(stringExpectedLocalAddress);
|
||||||
|
|
||||||
|
QTcpSocket *socket = newSocket();
|
||||||
|
qDebug() << "Binding " << addr;
|
||||||
|
|
||||||
|
if (successExpected) {
|
||||||
|
QVERIFY2(socket->bind(addr), qPrintable(socket->errorString()));
|
||||||
|
} else {
|
||||||
|
QVERIFY(!socket->bind(addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
QCOMPARE(socket->localAddress(), expectedLocalAddress);
|
||||||
|
|
||||||
|
delete socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
void tst_QTcpSocket::setInvalidSocketDescriptor()
|
void tst_QTcpSocket::setInvalidSocketDescriptor()
|
||||||
{
|
{
|
||||||
QTcpSocket *socket = newSocket();
|
QTcpSocket *socket = newSocket();
|
||||||
|
Loading…
Reference in New Issue
Block a user