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

Possible to derive QNetworkInterface from QAbstractSocket?



  • Hi all -

    I think the answer is "no," but in hopes I'm wrong: when I get a readyRead signal from a QUdpSocket, can I determine what QNetworkInterface the socket was opened on?

    If not, I'll just maintain a structure when the socket is created, storing such information.

    Any solution needs to work on Windows 7+, too.

    Thanks...


  • Lifetime Qt Champion

    Hi,

    Just a wild guess but if you use the local address from your socket and compare it to what you get from QNetworkInterface::addressEntries(), you might get what you want.



  • @SGaist I'm still experimenting, but I think this is on the right track.

    A current impediment is that I'm getting 2 addresses for each interface. This code:

    QList<QNetworkInterface> qniList;
    QList<QNetworkInterface>::iterator it_qni;
    QList<QNetworkAddressEntry> addrList;
    QNetworkAddressEntry addr;
    
    qniList = QNetworkInterface::allInterfaces();
    addrList = it_qni->addressEntries();
    for (int i = 0; i < addrList.count(); ++i)
    {
    	addr = addrList.at(i);
    	qDebug() << "address entry for" << it_qni->humanReadableName() << "is" << addr.ip().toString() << endl;
    }
    

    Produces this:

    address entry for "Ethernet 3" is "fe80::1c95:811:9e0f:11ce%ethernet_32774" 
    address entry for "Ethernet 3" is "10.0.1.36" 
    address entry for "Ethernet 2" is "fe80::7048:c341:d778:e156%ethernet_32776" 
    address entry for "Ethernet 2" is "192.168.70.37" 
    address entry for "VirtualBox Host-Only Network #2" is "fe80::2561:4b08:7c46:13ba%ethernet_32777" 
    address entry for "VirtualBox Host-Only Network #2" is "192.168.56.1" 
    address entry for "Npcap Loopback Adapter" is "fe80::249f:836c:cb98:fa1f%ethernet_32778" 
    address entry for "Npcap Loopback Adapter" is "169.254.250.31" 
    

    Is there a way for me to restrict what's returned to IPv4 addresses only?

    Also, when I receive something from one of my sockets, this code:

    QUdpSocket *sock;
    sock = qobject_cast<QUdpSocket *>(sender());
    QHostAddress qha = sock->localAddress();
    qDebug() << "responding socket has local address" << qha.toString();
    

    Produces this:

    responding socket has local address "0.0.0.0"
    

    Which doesn't match any of the addresses returned. Any idea what might be going on here?

    Thanks...


  • Lifetime Qt Champion

    @mzimmers said in Possible to derive QNetworkInterface from QAbstractSocket?:

    Is there a way for me to restrict what's returned to IPv4 addresses only?

    See the documentation.



  • This post is deleted!


  • @Christian-Ehrlicher ah, thank you, Christian. It took me a few minutes to connect the dots, but I now see that this will work:

    for (int i = 0; i < addrList.count(); ++i)
    {
    	addr = addrList.at(i);
    	QHostAddress qha = addr.ip();
    	if (qha.scopeId().isEmpty()) // empty scope ID means that it's IP4
    	{
    		qDebug() << "address entry for" << it_qni->humanReadableName() << "is" << addr.ip().toString();
    	}
    }
    

    If I may ask, as a networking neophyte, I don't understand why Qt provides both the QHostAddress class and the QNetworkAddressEntry class. Can you (or someone else) help me understand the distinction?

    Thanks...


  • Lifetime Qt Champion

    QHostAddress is the address of one machine, not necessarily yours.

    QNetworkAddressEntry Is one of the addresses associated with one of your network interface.



  • Thanks, SGaist.

    Moving to my other current issue: since this code:

    QUdpSocket *sock;
    sock = qobject_cast<QUdpSocket *>(sender());
    QHostAddress qha = sock->localAddress();
    qDebug() << "responding socket has local address" << qha.toString();
    

    is returning an address of 0.0.0.0 (for reasons I don't understand), I guess I need to keep a table of sockets, and the interfaces to which they're connected. I was going to use the socket as a key, but when I try this:

        QUdpSocket sock;
        QUdpSocket *pSock;
        sockList.push_back(new QUdpSocket);
        pSock = (sockList.last());
        sock = *pSock;
    

    I get a warning (from the last line). I don't understand why that isn't working, but is there a better approach anyway?

    Thanks...


  • Lifetime Qt Champion

    @mzimmers said in Possible to derive QNetworkInterface from QAbstractSocket?:

    I get a warning (from the last line). I don't understand why that isn't working

    Because you can't copy QObjects by value.

    And I meant https://doc.qt.io/qt-5/qhostaddress.html#protocol



  • @Christian-Ehrlicher thank you.

    To return to my original question, SGaist's suggestion works fine. Originally I was having trouble because my sockets were intended for UDP multicast, and as such were bound to AnyIPv4. Once I changed this (OK to do so since I'm controlling access to the interfaces myself), the addressed appeared just fine.

    Thanks to all who helped.


Log in to reply