summaryrefslogtreecommitdiffstats
path: root/src/network/socket
diff options
context:
space:
mode:
authorRobin Burchell <robin.burchell@collabora.com>2011-10-23 20:04:52 +0200
committerSergio Ahumada <sergio.ahumada@nokia.com>2011-10-31 20:25:12 +0100
commit03f852cb47d508d98aa90f501e9b7f4214e8ad8b (patch)
tree1df4fbdc4076205a306d9c3d89d68510e5ad035a /src/network/socket
parent3aa81c55e2f42389341feb77b1d9840e6c9b61a2 (diff)
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>
Diffstat (limited to 'src/network/socket')
-rw-r--r--src/network/socket/qabstractsocket.cpp143
-rw-r--r--src/network/socket/qabstractsocket.h13
-rw-r--r--src/network/socket/qudpsocket.cpp150
-rw-r--r--src/network/socket/qudpsocket.h16
4 files changed, 151 insertions, 171 deletions
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index e5bb72f36a..4d80ba259a 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -291,10 +291,10 @@
bytes).
\value NetworkError An error occurred with the network (e.g., the
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.
\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
not supported by the local operating system (e.g., lack of
IPv6 support).
@@ -329,7 +329,7 @@
\value HostLookupState The socket is performing a host name lookup.
\value ConnectingState The socket has started establishing a connection.
\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
be waiting to be written).
\value ListeningState For internal use only.
@@ -363,6 +363,51 @@
\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_p.h"
@@ -1294,6 +1339,94 @@ QAbstractSocket::~QAbstractSocket()
}
/*!
+ \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 false.
@@ -2345,7 +2478,7 @@ qint64 QAbstractSocket::writeData(const char *data, qint64 size)
proxy connections for virtual connection settings.
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()
*/
@@ -2367,7 +2500,7 @@ void QAbstractSocket::setLocalPort(quint16 port)
proxy connections for virtual connection settings.
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()
*/
diff --git a/src/network/socket/qabstractsocket.h b/src/network/socket/qabstractsocket.h
index b757092915..ee910e3b33 100644
--- a/src/network/socket/qabstractsocket.h
+++ b/src/network/socket/qabstractsocket.h
@@ -115,10 +115,20 @@ public:
MulticastTtlOption, // IP_MULTICAST_TTL
MulticastLoopbackOption // IP_MULTICAST_LOOPBACK
};
+ enum BindFlag {
+ DefaultForPlatform = 0x0,
+ ShareAddress = 0x1,
+ DontShareAddress = 0x2,
+ ReuseAddressHint = 0x4
+ };
+ Q_DECLARE_FLAGS(BindMode, BindFlag)
QAbstractSocket(SocketType socketType, QObject *parent);
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.
void connectToHost(const QString &hostName, quint16 port, OpenMode mode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol);
void connectToHost(const QHostAddress &address, quint16 port, OpenMode mode = ReadWrite);
@@ -214,6 +224,9 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_forceDisconnect())
};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractSocket::BindMode)
+
#ifndef QT_NO_DEBUG_STREAM
Q_NETWORK_EXPORT QDebug operator<<(QDebug, QAbstractSocket::SocketError);
Q_NETWORK_EXPORT QDebug operator<<(QDebug, QAbstractSocket::SocketState);
diff --git a/src/network/socket/qudpsocket.cpp b/src/network/socket/qudpsocket.cpp
index 009ce92d8e..79083e489a 100644
--- a/src/network/socket/qudpsocket.cpp
+++ b/src/network/socket/qudpsocket.cpp
@@ -108,51 +108,6 @@
\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 "qnetworkinterface.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
/*!
diff --git a/src/network/socket/qudpsocket.h b/src/network/socket/qudpsocket.h
index c477abd07e..068c20b9c4 100644
--- a/src/network/socket/qudpsocket.h
+++ b/src/network/socket/qudpsocket.h
@@ -60,23 +60,9 @@ class Q_NETWORK_EXPORT QUdpSocket : public QAbstractSocket
{
Q_OBJECT
public:
- enum BindFlag {
- DefaultForPlatform = 0x0,
- ShareAddress = 0x1,
- DontShareAddress = 0x2,
- ReuseAddressHint = 0x4
- };
- Q_DECLARE_FLAGS(BindMode, BindFlag)
-
explicit QUdpSocket(QObject *parent = 0);
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
bool joinMulticastGroup(const QHostAddress &groupAddress);
bool joinMulticastGroup(const QHostAddress &groupAddress,
@@ -101,8 +87,6 @@ private:
Q_DECLARE_PRIVATE(QUdpSocket)
};
-Q_DECLARE_OPERATORS_FOR_FLAGS(QUdpSocket::BindMode)
-
#endif // QT_NO_UDPSOCKET
QT_END_NAMESPACE