Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 1

Qt-interest Archive, April 2008
Re: get ip QT c++


Message 1 in thread

try QHostInfo::lookupHost 
 
-------------- Original message ----------------------
From: Mystical Groovy <djzet1@xxxxxxxxx>
> Hello
> 
> Id like to get the ip of my machine (linux) via C++, is it possible to 
> do this with Qt?.
> If you want you get send some code snippets to study, ive searched on 
> google but ive confused by the search results.
> 
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with 
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
> 

--
 [ signature omitted ] 

Message 2 in thread

Hello

Id like to get the ip of my machine (linux) via C++, is it possible to 
do this with Qt?.
If you want you get send some code snippets to study, ive searched on 
google but ive confused by the search results.

--
 [ signature omitted ] 

Message 3 in thread

Hi,

This [1] query doesn't help you?

André

[1] 
http://www.google.com/search?hl=en&sitesearch=lists.trolltech.com%2Fqt-interest&q=get+ip+address&btnG=Search

"Mystical Groovy" <djzet1@xxxxxxxxx> wrote in message 
news:47F250E1.9060305@xxxxxxxxxxxx
> Hello
>
> Id like to get the ip of my machine (linux) via C++, is it possible to do 
> this with Qt?.
> If you want you get send some code snippets to study, ive searched on 
> google but ive confused by the search results.
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with 
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/ 

--
 [ signature omitted ] 

Message 4 in thread

Mystical Groovy wrote:
>Hello
>
>Id like to get the ip of my machine (linux) via C++, is it possible to
>do this with Qt?.
>If you want you get send some code snippets to study, ive searched on
>google but ive confused by the search results.

http://doc.trolltech.com/4.3/qnetworkinterface.html#allAddresses
http://doc.trolltech.com/4.3/qhostinfo.html#localHostName

You decide which one fits your needs better.

-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: This is a digitally signed message part.


Message 5 in thread

Thank you for your anwsers, Ill try them now :)

--
 [ signature omitted ] 

Message 6 in thread

On Tuesday 01 April 2008 17:12:33 Mystical Groovy wrote:
> Hello
>
> Id like to get the ip of my machine (linux) via C++, is it possible to
> do this with Qt?.
> If you want you get send some code snippets to study, ive searched on
> google but ive confused by the search results.

I agree with other people here to use QNetworkInterface/QHostInfo. However, if 
you want to do it by hand on Linux, here is a snipped, for your only 
pleasure: ;-)

-----------------------------------
static QString posixGetMAC( const QString & deviceName )
{
    int s = socket ( AF_INET,SOCK_DGRAM, 0 );
    struct ifreq ifr;
    strcpy( ifr.ifr_name, deviceName.toLocal8Bit().constData() );
    if ( ioctl( s, SIOCGIFHWADDR, &ifr ) < 0 ) {
        qWarning( "posixGetMAC: Can't retrive MAC address. Using 
00:11:22:33:44:55" );
        return "00:11:22:33:44:55";
    }
    char st[17];
    for ( int i = 0; i < 6; i++ )
        sprintf( &st[i*3], "%02X%s", (ifr.ifr_hwaddr.sa_data[i] & 0xFF), 
i<5?":":"" );
    return QLatin1String( st );
}

static void posixGetNetwork( QString & _ip, QString & _mask, QString & _gw, 
QStringList & _dns )
{
    QString ipAddrRegExp("([0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]
{1,3})");

    // 1. parse the "ifconfig" command
    QProcess ifconfig;
    ifconfig.start( "/sbin/ifconfig eth0" );
    if(!ifconfig.waitForStarted() ) {
        qWarning( "posixGetNetwork: error starting 'ifconfig'" );
    } else {
        if(!ifconfig.waitForFinished()) {
            qWarning( "posixGetNetwork: ifconfig exited with error" );
        } else {
            QByteArray array = ifconfig.readAll();
            QRegExp  ip( "inet addr:" + ipAddrRegExp );
            int pos = ip.indexIn( array );
            if (pos > -1) {
                _ip = ip.cap(1);
            } else
                qWarning( "posixGetNetwork: error parsing 'inet addr' 
in '%s'", array.constData() );

            /*QRegExp  bcast( "Bcast:" + ipAddrRegExp );
            pos = bcast.indexIn( array );
            if (pos > -1) {
                p->netBcast = bcast.cap(1);
            } else {
                qWarning( "posixGetNetwork: error parsing 'Bcast' in '%s'", 
array.constData() );
                return false;
            }*/

            QRegExp  mask( "Mask:" + ipAddrRegExp );
            pos = mask.indexIn( array );
            if (pos > -1) {
                _mask = mask.cap(1);
            }  else
                qWarning( "posixGetNetwork: error parsing 'Mask' in '%s'", 
array.constData() );
        }
    }

    // 2. parse the "route -n" command
    QProcess route;
    route.start("/sbin/route -n ");
    if ( !route.waitForStarted() ) {
        qWarning( "posixGetNetwork: error starting 'route -n'" );
    } else {
        if (!route.waitForFinished()) {
            qWarning( "posixGetNetwork: route exited with error" );
        } else {
            // look for the gateway in each line
            _gw = QString();
            while ( route.canReadLine() ) {
                QByteArray array = route.readLine();
                if ( !array.startsWith( "0.0.0.0" ) )
                    continue;
                array = array.mid( 7 );
                QRegExp gw( ipAddrRegExp );
                int pos = gw.indexIn( array );
                if ( pos > -1 ) {
                    _gw = gw.cap( 1 );
                    break;
                }
            }
            if ( _gw.isEmpty() )
                qWarning( "posixGetNetwork: error parsing 'route -n'" );
        }
    }

    // 3. parse the DNSes
    _dns.clear();
    QFile dnsFile( "/etc/resolv.conf" );
    if ( !dnsFile.exists() ) {
        qWarning( "posixGetNetwork: error opening file /etc/resolv.conf" );
    } else {
        dnsFile.open( QIODevice::ReadOnly );
        QByteArray array = dnsFile.readAll();
        dnsFile.close();

        QString ipAddrRegExp("^[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]
{1,3}$");
        QRegExp  nameserver("nameserver[\\s]+"+ipAddrRegExp );
        int pos = nameserver.indexIn(array);
        while ((pos = nameserver.indexIn(array, pos)) != -1) {
            _dns << nameserver.cap(1);
            pos += nameserver.matchedLength();
        }
    }
}
-----------------------------------

If you want I have the routines to setup the network too.

Regards,
-- 
 [ signature omitted ] 

Message 7 in thread

Enrico Ros wrote:
>I agree with other people here to use QNetworkInterface/QHostInfo.
> However, if you want to do it by hand on Linux, here is a snipped, for
> your only pleasure: ;-)

Thank you for your contribution, but I feel I must point out that your 
code is too fragile to be used outside controlled conditions. 
QNetworkInterface has no such problems and is completely cross-platform.

>-----------------------------------
>static QString posixGetMAC( const QString & deviceName )
>{
>    int s = socket ( AF_INET,SOCK_DGRAM, 0 );
>    struct ifreq ifr;
>    strcpy( ifr.ifr_name, deviceName.toLocal8Bit().constData() );
>    if ( ioctl( s, SIOCGIFHWADDR, &ifr ) < 0 ) {
>        qWarning( "posixGetMAC: Can't retrive MAC address. Using
>00:11:22:33:44:55" );
>        return "00:11:22:33:44:55";
>    }
>    char st[17];
>    for ( int i = 0; i < 6; i++ )
>        sprintf( &st[i*3], "%02X%s", (ifr.ifr_hwaddr.sa_data[i] & 0xFF),
>i<5?":":"" );
>    return QLatin1String( st );
>}

If you're going to return a broken address, you should return 
00:00:00:00:00:00, or you should at least turn the non-universal bit on, 
to indicate it's not a permanent address.

You also forgot to tell us which header declares AF_INET, SOCK_DGRAM and 
SIOCGIFHWADDR.

There's also a possibility for buffer overrun in the strcpy at the 
beginning.

>static void posixGetNetwork( QString & _ip, QString & _mask, QString &
> _gw, QStringList & _dns )
>{
>    QString ipAddrRegExp("([0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]
>{1,3})");

This regexp matches things like "333.999.256.555". Granted, the commands 
below will not contain any such broken addresses, but if you're not 
validating anyways, why not go with the simpler regexp?

	([0-9.]+)

>
>    // 1. parse the "ifconfig" command
>    QProcess ifconfig;
>    ifconfig.start( "/sbin/ifconfig eth0" );

At this point, there are already a few problems:
1) you did not set LC_ALL to "C" so that you get English output from 
ifconfig. Your code breaks on my system (LANG=pt_BR.UTF-8) which has 
output like:

          inet end.: 10.3.5.19  Bcast:10.3.5.255  Masc:255.255.254.0

2) "eth0" is a Linux name. Your function is not POSIX at all, so it's a 
misnomer.

3) what happens for people without eth0? Like people on dial-ups, or on 
WiFi networks only? How about for people with more than one network card, 
which is very common on today's laptops (2 or 3 interfaces is very 
common)?

>    if(!ifconfig.waitForStarted() ) {
>        qWarning( "posixGetNetwork: error starting 'ifconfig'" );
>    } else {
>        if(!ifconfig.waitForFinished()) {
>            qWarning( "posixGetNetwork: ifconfig exited with error" );
>        } else {

waitForFinished() returns false if the process crashed. If it exited 
normally but with error, the function returns true. You're not handling 
that case.

That would happen if the system has no "eth0".

>            QByteArray array = ifconfig.readAll();
>            QRegExp  ip( "inet addr:" + ipAddrRegExp );

See above for localisation problems.

>            int pos = ip.indexIn( array );
>            if (pos > -1) {
>                _ip = ip.cap(1);
>            } else
>                qWarning( "posixGetNetwork: error parsing 'inet addr'
>in '%s'", array.constData() );

What happens if eth0 has more than one address? This is a known problem 
with ifconfig: it only shows one address. Your code is completely missing 
all other addresses.

>
>            /*QRegExp  bcast( "Bcast:" + ipAddrRegExp );
>            pos = bcast.indexIn( array );
>            if (pos > -1) {
>                p->netBcast = bcast.cap(1);
>            } else {
>                qWarning( "posixGetNetwork: error parsing 'Bcast' in
> '%s'", array.constData() );
>                return false;
>            }*/
>
>            QRegExp  mask( "Mask:" + ipAddrRegExp );

And here again.

>            pos = mask.indexIn( array );
>            if (pos > -1) {
>                _mask = mask.cap(1);
>            }  else
>                qWarning( "posixGetNetwork: error parsing 'Mask' in
> '%s'", array.constData() );
>        }
>    }
>
>    // 2. parse the "route -n" command
>    QProcess route;
>    route.start("/sbin/route -n ");
>    if ( !route.waitForStarted() ) {
>        qWarning( "posixGetNetwork: error starting 'route -n'" );
>    } else {
>        if (!route.waitForFinished()) {
>            qWarning( "posixGetNetwork: route exited with error" );
>        } else {

See above notice for waitForFinished().

>            // look for the gateway in each line
>            _gw = QString();
>            while ( route.canReadLine() ) {
>                QByteArray array = route.readLine();
>                if ( !array.startsWith( "0.0.0.0" ) )
>                    continue;
>                array = array.mid( 7 );
>                QRegExp gw( ipAddrRegExp );
>                int pos = gw.indexIn( array );
>                if ( pos > -1 ) {
>                    _gw = gw.cap( 1 );
>                    break;
>                }
>            }
>            if ( _gw.isEmpty() )
>                qWarning( "posixGetNetwork: error parsing 'route -n'" );
>        }
>    }

You're not handling cases where a system has more than one default route. 
In those cases, it usually happens that the one with the lowest metric 
will be picked up. If there's a metric match, there are other route 
resolution mechanisms that are available only to the kernel. This is not 
so far-fatched: many VPN systems will add a new default route to your 
computer.

It also prints a warning in systems without a default gateway (think of 
dial-up computers that are not connected to the Internet).

I have to question why a cross-platform application would need to know the 
default gateway.

>    // 3. parse the DNSes
>    _dns.clear();
>    QFile dnsFile( "/etc/resolv.conf" );
>    if ( !dnsFile.exists() ) {
>        qWarning( "posixGetNetwork: error opening file /etc/resolv.conf"
> ); } else {
>        dnsFile.open( QIODevice::ReadOnly );
>        QByteArray array = dnsFile.readAll();
>        dnsFile.close();
>
>        QString
> ipAddrRegExp("^[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}$");

Why are you redefining ipAddrRegExp here?

>        QRegExp  nameserver("nameserver[\\s]+"+ipAddrRegExp );
>        int pos = nameserver.indexIn(array);
>        while ((pos = nameserver.indexIn(array, pos)) != -1) {
>            _dns << nameserver.cap(1);
>            pos += nameserver.matchedLength();
>        }
>    }
>}
>-----------------------------------

Thankfully, you won't be running this code in a tight loop. But, as an 
advice, try to stay away from QRegExp. You could do all of the parsing in 
your routine without it.

Unlike your function, QNetworkInterface does not give you the default 
gateway or DNS server addresses.

-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: This is a digitally signed message part.


Message 8 in thread

On Wednesday 02 April 2008 10:56:21 Thiago Macieira wrote:
> Enrico Ros wrote:
> >I agree with other people here to use QNetworkInterface/QHostInfo.
> > However, if you want to do it by hand on Linux, here is a snipped, for
> > your only pleasure: ;-)
>
> Thank you for your contribution, but I feel I must point out that your
> code is too fragile to be used outside controlled conditions.
> QNetworkInterface has no such problems and is completely cross-platform.

Thanks Thiago, that was a very instructive post! ;-)
All the advices you wrote will help me make better code. (btw: that routine 
just worked (and maybe, *only worked* :-) on a popularm ARM family we work 
on).

Thanks for 'peer reviewing' ;-)
Regards,
-- 
 [ signature omitted ] 

Message 9 in thread

Enrico,

If you would like to do it Linux-only way and don't want to use 
QNetworkInterface (I strictly recommend to use it under QT)  - it  quite 
easier just read /proc/net/arp

Code to support other *NIX is completely different ...


Enrico Ros wrote:
> On Tuesday 01 April 2008 17:12:33 Mystical Groovy wrote:
>> Hello
>>
>> Id like to get the ip of my machine (linux) via C++, is it possible to
>> do this with Qt?.
>> If you want you get send some code snippets to study, ive searched on
>> google but ive confused by the search results.
> 
> I agree with other people here to use QNetworkInterface/QHostInfo. However, if 
> you want to do it by hand on Linux, here is a snipped, for your only 
> pleasure: ;-)
> 
> -----------------------------------
> static QString posixGetMAC( const QString & deviceName )
> {
>     int s = socket ( AF_INET,SOCK_DGRAM, 0 );
>     struct ifreq ifr;
>     strcpy( ifr.ifr_name, deviceName.toLocal8Bit().constData() );
>     if ( ioctl( s, SIOCGIFHWADDR, &ifr ) < 0 ) {
>         qWarning( "posixGetMAC: Can't retrive MAC address. Using 
> 00:11:22:33:44:55" );
>         return "00:11:22:33:44:55";
>     }
>     char st[17];
>     for ( int i = 0; i < 6; i++ )
>         sprintf( &st[i*3], "%02X%s", (ifr.ifr_hwaddr.sa_data[i] & 0xFF), 
> i<5?":":"" );
>     return QLatin1String( st );
> }
> 
> static void posixGetNetwork( QString & _ip, QString & _mask, QString & _gw, 
> QStringList & _dns )
> {
>     QString ipAddrRegExp("([0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]
> {1,3})");
> 
>     // 1. parse the "ifconfig" command
>     QProcess ifconfig;
>     ifconfig.start( "/sbin/ifconfig eth0" );
>     if(!ifconfig.waitForStarted() ) {
>         qWarning( "posixGetNetwork: error starting 'ifconfig'" );
>     } else {
>         if(!ifconfig.waitForFinished()) {
>             qWarning( "posixGetNetwork: ifconfig exited with error" );
>         } else {
>             QByteArray array = ifconfig.readAll();
>             QRegExp  ip( "inet addr:" + ipAddrRegExp );
>             int pos = ip.indexIn( array );
>             if (pos > -1) {
>                 _ip = ip.cap(1);
>             } else
>                 qWarning( "posixGetNetwork: error parsing 'inet addr' 
> in '%s'", array.constData() );
> 
>             /*QRegExp  bcast( "Bcast:" + ipAddrRegExp );
>             pos = bcast.indexIn( array );
>             if (pos > -1) {
>                 p->netBcast = bcast.cap(1);
>             } else {
>                 qWarning( "posixGetNetwork: error parsing 'Bcast' in '%s'", 
> array.constData() );
>                 return false;
>             }*/
> 
>             QRegExp  mask( "Mask:" + ipAddrRegExp );
>             pos = mask.indexIn( array );
>             if (pos > -1) {
>                 _mask = mask.cap(1);
>             }  else
>                 qWarning( "posixGetNetwork: error parsing 'Mask' in '%s'", 
> array.constData() );
>         }
>     }
> 
>     // 2. parse the "route -n" command
>     QProcess route;
>     route.start("/sbin/route -n ");
>     if ( !route.waitForStarted() ) {
>         qWarning( "posixGetNetwork: error starting 'route -n'" );
>     } else {
>         if (!route.waitForFinished()) {
>             qWarning( "posixGetNetwork: route exited with error" );
>         } else {
>             // look for the gateway in each line
>             _gw = QString();
>             while ( route.canReadLine() ) {
>                 QByteArray array = route.readLine();
>                 if ( !array.startsWith( "0.0.0.0" ) )
>                     continue;
>                 array = array.mid( 7 );
>                 QRegExp gw( ipAddrRegExp );
>                 int pos = gw.indexIn( array );
>                 if ( pos > -1 ) {
>                     _gw = gw.cap( 1 );
>                     break;
>                 }
>             }
>             if ( _gw.isEmpty() )
>                 qWarning( "posixGetNetwork: error parsing 'route -n'" );
>         }
>     }
> 
>     // 3. parse the DNSes
>     _dns.clear();
>     QFile dnsFile( "/etc/resolv.conf" );
>     if ( !dnsFile.exists() ) {
>         qWarning( "posixGetNetwork: error opening file /etc/resolv.conf" );
>     } else {
>         dnsFile.open( QIODevice::ReadOnly );
>         QByteArray array = dnsFile.readAll();
>         dnsFile.close();
> 
>         QString ipAddrRegExp("^[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]
> {1,3}$");
>         QRegExp  nameserver("nameserver[\\s]+"+ipAddrRegExp );
>         int pos = nameserver.indexIn(array);
>         while ((pos = nameserver.indexIn(array, pos)) != -1) {
>             _dns << nameserver.cap(1);
>             pos += nameserver.matchedLength();
>         }
>     }
> }
> -----------------------------------
> 
> If you want I have the routines to setup the network too.
> 
> Regards,


-- 
 [ signature omitted ] 

Message 10 in thread

Guyz it seems I have a huge problem!.

To use QHostInfo I must use Qt4,
so I download and install Qt4, but using Kdevelop 3.5.1 I cant compile 
the project, It says me "qhostinfo.h" no such file or dir.
In Project->Project Options->C++ Support->Qt Options,

I have the following setup:

-Qt version, directory and QMake binary:
--Qt3, Qt4 --> I choose Qt4
--QMake binary: "/usr/local/Trolltech/Qt-4.3.2/bin/qmake

--Qt include syntax
-Qt3 style (#include <qwidget.h>) -->I choose Qt3 style
-Qt4 style (#include <QWidget>)

--UI Designer intergration
-Use kdevelop's embedded designer <- disabled
-Run kdevelop's designer as a separate application <- also disabled
-Run qt designer <-- i choose this
-Designer binary: "/usr/local/Trolltech/Qt-4.3.2/bin/designer"

then I click OK close and open again the project but I cant get it 
compiled!!!!
Please help me, thank you :)

--
 [ signature omitted ] 

Message 11 in thread

Mystical Groovy wrote:
>so I download and install Qt4, but using Kdevelop 3.5.1 I cant compile
>the project, It says me "qhostinfo.h" no such file or dir.

Make sure your .pro file says:

QT += network
-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: This is a digitally signed message part.


Message 12 in thread

Stay on QT3 and read /proc/net/arp as usual file if Linux-only solution 
is enough for you.

If you need cross-platform solution - let me know.


Mystical Groovy wrote:
> Guyz it seems I have a huge problem!.
> 
> To use QHostInfo I must use Qt4,
> so I download and install Qt4, but using Kdevelop 3.5.1 I cant compile 
> the project, It says me "qhostinfo.h" no such file or dir.
> In Project->Project Options->C++ Support->Qt Options,
> 
> I have the following setup:
> 
> -Qt version, directory and QMake binary:
> --Qt3, Qt4 --> I choose Qt4
> --QMake binary: "/usr/local/Trolltech/Qt-4.3.2/bin/qmake
> 
> --Qt include syntax
> -Qt3 style (#include <qwidget.h>) -->I choose Qt3 style
> -Qt4 style (#include <QWidget>)
> 
> --UI Designer intergration
> -Use kdevelop's embedded designer <- disabled
> -Run kdevelop's designer as a separate application <- also disabled
> -Run qt designer <-- i choose this
> -Designer binary: "/usr/local/Trolltech/Qt-4.3.2/bin/designer"
> 
> then I click OK close and open again the project but I cant get it 
> compiled!!!!
> Please help me, thank you :)
> 
> -- 
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with 
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
> 

--
 [ signature omitted ]