Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

A UDP socket problem.



  • I have two cards on my PC connected to the same Access Point

    Wireless LAN adapter Wireless Network Connection 3:
    
       IPv4 Address. . . . . . . . . . . : 172.16.1.154
       Subnet Mask . . . . . . . . . . . : 255.255.255.0
       Default Gateway . . . . . . . . . : 172.16.1.1
    
    Ethernet adapter Local Area Connection 2:
    
       IPv4 Address. . . . . . . . . . . : 172.16.1.134
       Subnet Mask . . . . . . . . . . . : 255.255.255.0
       Default Gateway . . . . . . . . . : 172.16.1.1
    
    

    First a socket setup

    void MyUDP::Start(QString local_ip, quint16 local_port)
    {
        status = socket->bind(QHostAddress(local_ip), local_port);
        status = connect(socket, SIGNAL(readyRead()), this, SLOT(ReadyRead()));
    }
    

    local_ip = 172.16.1.154
    local_port = 7070

    On bind I get - false.
    On connect I get - true.

    Then I send a message to a sensor (172.16.1.105) connected to the same Access Point

    socket->writeDatagram(Data, QHostAddress(remote_ip), remote_port);
    

    remote_ip = 172.16.1.255 - broadcast
    remote_port = 1112 - sensor port

    The sensor gets a message but it sees it like from another source.

    Received packet of size 5 From 172.16.1.134:52723 To 172.16.1.255:1112
    

    And when it sends a response I'm not getting it.

    Why? Because the bind failed?

    P.S. Hercules sends and receives messages.


  • Lifetime Qt Champion



  • @jsulm
    I added

    connect_status = connect(socket, SIGNAL(errorOccurred()), this, SLOT(SocketError()));
    
    void MyUDP::SocketError(QAbstractSocket::SocketError socketError)
    {
        qDebug() << "Socket Error: " << socketError;
    }
    

    But I get - QObject::connect: No such signal QUdpSocket::errorOccurred() in udp.cpp:30

    I noticed on start up it prints in Application Output -
    QObject: Cannot create children for a parent that is in a different thread.
    (Parent is QUdpSocket(0x3de510), parent's thread is QThread(0x263437f0), current thread is QThread(0x22fcf0) QNativeSocketEngine::bind() was not called in QAbstractSocket::UnconnectedState



  • @jenya7 said in A UDP socket problem.:

    connect_status = connect(socket, SIGNAL(errorOccurred()), this, SLOT(SocketError()));

    Try

    connect_status = connect(socket, &QAbstractSocket::errorOccurred, this, &MyUDP::SocketError);
    

  • Lifetime Qt Champion

    @jenya7 said in A UDP socket problem.:

    connect_status = connect(socket, SIGNAL(errorOccurred()), this, SLOT(SocketError()));

    You forgot to mention the parameter types.
    But, as @mchinand pointed out, you should really switch to "new" Qt5 connect syntax.



  • @jsulm
    I replaced

    connect_status = connect(socket, &QUdpSocket::readyRead, this, &MyUDP::ReadyRead);
    

    but on this one

    connect_status = connect(socket, &QAbstractSocket::errorOccurred, this, &MyUDP::SocketError);
    

    I get - error: no member named 'errorOccurred' in 'QAbstractSocket'


  • Lifetime Qt Champion

    @jenya7 Ah, from the doc: "This function was introduced in Qt 5.15."
    What Qt version do you use?

    Try to call errorString() after calling bind().



  • @jsulm

    connect_status = socket->bind(QHostAddress(local_ip), local_port);
    
    QString err = socket->errorString();
    

    err = "Unknown error"


  • Lifetime Qt Champion

    @jenya7 What you also can do is: connect a slot to https://doc.qt.io/qt-5/qabstractsocket.html#stateChanged and print out the state and error string from errorString().



  • @jsulm
    Placed in constructor

    MyUDP::MyUDP(QObject *parent) : QObject(parent)
    {
        socket = new QUdpSocket(this);
    
        QObject::connect(socket, &QUdpSocket::readyRead, this, &MyUDP::ReadyRead);
    }
    

    Now it binds good.



  • what you are doing is generally a bad idea unless you are aggregating channels for redundancy or to increase badnwidth....in which case you'd have a bridge interface and do your bind() there.

    I don't understand why you are doing this in the first place since it complicates network routing, with minimal to no gain.

    I'm kind of breaking my own rule about not questioning the "reason" a person asks a question, but I'm at a loss as to why you think you need to do this.

    FWIW, you can assign multiple IPs to a single NIC is that is what you need.


Log in to reply