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

QUdpSocket: Picking a specific network interface



  • Hi guys,

    I'm using a QUdpSocket to receive and send packets. So far everything works well using the standard code below:

    Setting up incoming messages:

    QObject::connect(UDPSocket,&QUdpSocket::readyRead,this,&Server::processData);
    
    //Unbind the socket if currently bound
    if(UDPSocket->state() == QAbstractSocket::BoundState)
      UDPSocket->close();
    
    //Bind the socket to the specified input address and port
    UDPSocket->bind(inputIPAddress,inputPort);
    

    Sending messages:

    UDPSocket->writeDatagram(bytes,outputIPAddress,outputPort);
    

    I'm having a bit of trouble picking a specific network interface to use:

    UDPSocket->setMulticastInterface(networkAdapter);
    

    I create the input / output IP addresses from a QString and don't specify the subnet.

    What is the best way to specify a network interface?

    Cheers


  • Lifetime Qt Champion

    Hi,

    Why not use QNetworkInterface::allInterfaces and select the one matching your criteria ?



  • @SGaist That's what I'm doing at the moment, but it doesn't seem to work as expected. For example, if I'm using a a LAN connection and set the interface to Wi-Fi, packets still go through the wired connection



  • @rtavakko Try to get all the network interfaces available in the system and apply the matching criteria to get the required interface. and use that interface to set for the
    setMulticastInterface call.

    QList<QNetworkInterface> listofinterfaces =QNetworkInterface::allInterfaces();
    for(auto interface:listofinterfaces)
    {
    qDebug()<<interface.humanReadableName();
    }



  • @nagesh Thanks for replying. That's what I'm doing at the moment. I filter out VM and Bluetooth devices that way and set the interface but it seems that is ignored based on the IP settings.

    I'll put together a small QT project to better show what I'm having trouble with


  • Qt Champions 2017

        for (const QNetworkInterface & ifcurrent : QNetworkInterface::allInterfaces()) {
            if (!ifcurrent.flags().testFlag(QNetworkInterface::CanMulticast) || !ifcurrent.flags().testFlag(QNetworkInterface::IsUp))
                continue;
    
            QList<QNetworkAddressEntry> entries = ifcurrent.addressEntries();
            for (const QNetworkAddressEntry & entry : entries)  {
               if (!entry.ip().isGlobal())
                  continue;
    
                // Bind the address if you'd like to use this interface & this protocol (IPv4/IPv6)
            }
        }
    


  • @kshegunov Thanks for that. So you suggest to only specify an adapter and not the IP / port and pick those settings based on the adapter?

    I think that works for incoming settings but not for output IP / port.

    Here is a project I put together:

    https://github.com/rtavakko/MulticastServer

    It seems that even though you are able to set the interface to a specific one, your IP settings override that and messages are sent and received using the best suited interface.

    For example for outgoing messages I tried creating a packet like this:

    QNetworkDatagram datagram;
    
    datagram.setData(bytes);
    datagram.setInterfaceIndex(UDPSocket->multicastInterface().index());
    datagram.setDestination(outputIPAddress,outputPort);
    

    This would mean that your packet should be sent using the interface index you provide but it still picks whichever interface the IP and port are on instead of failing to send.


  • Qt Champions 2017

    I'm quoting from memory here, but I believe the interface is determined based on the IP you bound the socket to. So bind to the correct IP and it should be fine (I think).



  • @rtavakko is Application doing unicast reception and multicast transmission?

    Application is using single socket for reception and transmission.

    QUdpSocket* UDPSocket;
    

    initialize() function in your code binds the socket to the interface for the incoming connection (input IPAddress and Port) and same is being used for the transmission.

    Are you using multicast series for transmission ?



  • @nagesh I guess what I'm trying to do is multicast reception and unicast transmission. I thought that a single UDP socket can be bound to an input IP / port to receive messages and connect to a separate IP / port to send messages, is that not the case? What do you recommend as the best way to do this?



  • @rtavakko if sockets settings are different for sending and receiving, better to have TxSocket and RxSocket seperate.

    what I'm trying to do is multicast reception and unicast transmission
    

    In order receive multicast data joinMulticastGroup API call to be called with the multicast group address. (multicast series from 224.0.0.1 to 239.255.255.255)

    but your code doesn't contain any joinMulticastGroup call



  • @nagesh Good point. I tried making that call after I bound the socket in initialize() but it didn't make a difference in what adapter was picked. I'll try it again this week. Will I need a call to leave the multicast group when changing rx settings?



  • @rtavakko if Rx previous settings was called with joinMulticastGroup then while changing the settings good practice to call leaveMulticastGroup.



  • @nagesh Sounds good, I'll try that and update here