QUdpSocket bind problem
-
Hi
got a small problem with the bind functionm_UdpSocket = new QUdpSocket(); bool b; while(m_UdpSocket->state() != QAbstractSocket::BoundState) b = m_UdpSocket->bind(QHostAddress::Any, 55555);
while debugging it always return false and stays in the loop
in release mode work on first try and the socket is correctly binded and receive datagram send on that port
any idea why? -
I cannot answer your question about why it spins in the debugger, but I can tell you that the loop bothers me. First off, if you are creating a listenner then you will need to execute the bind regardless. The simpler design approach is right out of the Qt reference docs. Create your socket and bind it, checking if the bind fails. If it fails then either you don't have privilege to that port or something else is already bound there. No need for a loop.
I think checking if your new QUdpSocket succeeded is more important than the bind loop.
-
I cannot answer your question about why it spins in the debugger, but I can tell you that the loop bothers me. First off, if you are creating a listenner then you will need to execute the bind regardless. The simpler design approach is right out of the Qt reference docs. Create your socket and bind it, checking if the bind fails. If it fails then either you don't have privilege to that port or something else is already bound there. No need for a loop.
I think checking if your new QUdpSocket succeeded is more important than the bind loop.
@Kent-Dorfman Hi
I agree with you originatly there wasn't any loop
indeed I should check if the new succeed.
the loop was only for testing purpose
im certain the port isn't open at the moment and it does work if not executed by the debugger... -
you don't mention which debugger. I don't use the qt-creator stuff at all. maybe try it in a system debugger like gdb, or one of its front-ends. browsing other threads, the qt debugger seems to be a point of frustration with others as well.
-
Hi
im using qt creator 16 under windows 11, im pretty sure the debugger is GDB under the hood -
Hi
got a small problem with the bind functionm_UdpSocket = new QUdpSocket(); bool b; while(m_UdpSocket->state() != QAbstractSocket::BoundState) b = m_UdpSocket->bind(QHostAddress::Any, 55555);
while debugging it always return false and stays in the loop
in release mode work on first try and the socket is correctly binded and receive datagram send on that port
any idea why?@JulsPower You are blocking the Qt event loop with such a loop, not sure that is the issue here
-
@JulsPower Hi
Maybe you can check what the error value for m_UdpSocket->state() means first.
https://doc.qt.io/qt-6/qabstractsocket.html#SocketState-enum -
Ok I changed the init function to be more like it should be
ui->setupUi(this); m_UdpSocket = new QUdpSocket(this); bool b; b = m_UdpSocket->bind(QHostAddress::Any, 55555); auto state = m_UdpSocket->state(); QMessageBox::information(this, "info", QString(b?"true ":"false ") + QString::number(state)); connect(m_UdpSocket, &QUdpSocket::readyRead, this, &MainWindow::readPendingDatagrams); connect(m_UdpSocket, &QUdpSocket::errorOccurred, this, &MainWindow::errorOccurred);
if I debug the message box show false 0 (which is unconnected)
and if I run the debug version it shows true 4errorOccurred is never called
-
Ok I changed the init function to be more like it should be
ui->setupUi(this); m_UdpSocket = new QUdpSocket(this); bool b; b = m_UdpSocket->bind(QHostAddress::Any, 55555); auto state = m_UdpSocket->state(); QMessageBox::information(this, "info", QString(b?"true ":"false ") + QString::number(state)); connect(m_UdpSocket, &QUdpSocket::readyRead, this, &MainWindow::readPendingDatagrams); connect(m_UdpSocket, &QUdpSocket::errorOccurred, this, &MainWindow::errorOccurred);
if I debug the message box show false 0 (which is unconnected)
and if I run the debug version it shows true 4errorOccurred is never called
@JulsPower
You can now use error() or errorString() to see the actual error message.
https://doc.qt.io/qt-6/qabstractsocket.html#error
https://doc.qt.io/qt-6/qiodevice.html#errorString -
@JulsPower What is return value of error().
-
@JulsPower What is return value of error().
-
@JulsPower
I checked the relevant source code and I can see that the error code without an error message could be WSANOTINITIALISED, which stands for WSAStartup failed. I guess it could be a mismatch or missing winsock library in the debug environment.
https://learn.microsoft.com/zh-cn/windows/win32/winsock/windows-sockets-error-codes-2bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &a, quint16 port) { QHostAddress address = a; if (address.protocol() == QAbstractSocket::IPv4Protocol) { if ((address.toIPv4Address() & 0xffff0000) == 0xefff0000) { // binding to a multicast address address = QHostAddress(QHostAddress::AnyIPv4); } } qt_sockaddr aa; QT_SOCKLEN_T sockAddrSize = 0; setPortAndAddress(port, address, &aa, &sockAddrSize); if (aa.a.sa_family == AF_INET6) { // The default may change in future, so set it explicitly int ipv6only = 0; if (address.protocol() == QAbstractSocket::IPv6Protocol) ipv6only = 1; ::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only) ); } int bindResult = ::bind(socketDescriptor, &aa.a, sockAddrSize); if (bindResult == SOCKET_ERROR && WSAGetLastError() == WSAEAFNOSUPPORT && address.protocol() == QAbstractSocket::AnyIPProtocol) { // retry with v4 aa.a4.sin_family = AF_INET; aa.a4.sin_port = htons(port); aa.a4.sin_addr.s_addr = htonl(address.toIPv4Address()); sockAddrSize = sizeof(aa.a4); bindResult = ::bind(socketDescriptor, &aa.a, sockAddrSize); } if (bindResult == SOCKET_ERROR) { int err = WSAGetLastError(); WS_ERROR_DEBUG(err); switch (err) { case WSANOTINITIALISED: //### break; case WSAEADDRINUSE: case WSAEINVAL: setError(QAbstractSocket::AddressInUseError, AddressInuseErrorString); break; case WSAEACCES: setError(QAbstractSocket::SocketAccessError, AddressProtectedErrorString); break; case WSAEADDRNOTAVAIL: setError(QAbstractSocket::SocketAddressNotAvailableError, AddressNotAvailableErrorString); break; default: break; } #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == false (%s)", address.toString().toLatin1().constData(), port, socketErrorString.toLatin1().constData()); #endif return false; } #if defined (QNATIVESOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeBind(%s, %i) == true", address.toString().toLatin1().constData(), port); #endif socketState = QAbstractSocket::BoundState; return true; }
-
@JulsPower
You can try the following code before executing the bind() function#include <winsock2.h> #include <ws2tcpip.h> #pragma comment(lib, "ws2_32.lib") .... WSAData wsadata; int err = WSAStartup(MAKEWORD(2,0), &wsadata); if (err != 0) { qWarning("QTcpSocketAPI: WinSock v2.0 initialization failed."); } ....
-
@JulsPower
You can try the following code before executing the bind() function#include <winsock2.h> #include <ws2tcpip.h> #pragma comment(lib, "ws2_32.lib") .... WSAData wsadata; int err = WSAStartup(MAKEWORD(2,0), &wsadata); if (err != 0) { qWarning("QTcpSocketAPI: WinSock v2.0 initialization failed."); } ....
@Hanson said in QUdpSocket bind problem:
@JulsPower
You can try the following code before executing the bind() function#include <winsock2.h> #include <ws2tcpip.h> #pragma comment(lib, "ws2_32.lib") .... WSAData wsadata; int err = WSAStartup(MAKEWORD(2,0), &wsadata); if (err != 0) { qWarning("QTcpSocketAPI: WinSock v2.0 initialization failed."); } ....
WSAStartup return 0 so no error there
but the bind function continue to return false -
@JulsPower
emmm... I can't figure it out anymore :)
Or you can download the qt source code and debug it.