How to set SO_REUSEPORT option for QUdpSocket?
-
use BindMode and BindFlag in bind(..) method
-
I could not get this to work using the QUdpSocket::bind() functions and the BindFlag as dheerendra suggested. There doesn't seem to be a BindFlag for reusing ports, at least not in in Qt4 (what I use). I did look quickly at the Qt5 documentation and didn't see any appropriate BindFlag, either.
So I did it using Berkeley sockets. I'm using Linux, the same code might work with WinSock, if not something trivially similar will. The following code creates a QUdpSocket, provides it with a low-level socket descriptor that has been set for SO_REUSEPORT, then binds it to port 34567:
QUdpSocket *sock = new QUdpSocket; int sockfd = socket(AF_INET, SOCK_DGRAM, 0); int optval = 1; setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, (void *) &optval, sizeof(optval)); sock->setSocketDescriptor(sockfd, QUdpSocket::UnconnectedState); sock->bind(34567, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
-
https://stackoverflow.com/questions/47268023/how-to-set-so-reuseaddr-on-the-socket-used-by-qtcpserver takes the same approach as you do if required to access flags not available from Qt.
FYI though, have a careful read of https://bugreports.qt.io/browse/QTBUG-33419. At one point I see:
case QNativeSocketEngine::AddressReusable: #if defined(SO_REUSEPORT) // on OS X, SO_REUSEADDR isn't sufficient to allow multiple binds to the // same port (which is useful for multicast UDP). SO_REUSEPORT is, but // we most definitely do not want to use this for TCP. See QTBUG-6305. if (socketType == QAbstractSocket::UdpSocket) n = SO_REUSEPORT; else n = SO_REUSEADDR; #else n = SO_REUSEADDR; #endif
implying that code for
QNativeSocketEngine::AddressReusable
will useSO_REUSEPORT
forQAbstractSocket::UdpSocket
, provided available at compilation? -
@Xando On windows, this did not work for me, even fixing the socket options to the windows equivalent. What did work was:
udpSocket = new QUdpSocket(this); groupAddress4 = QHostAddress(multicastAddr); bool result = udpSocket->bind( QHostAddress::AnyIPv4, port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);