How to get current net speed of all connections



  • Hi :) My name is Bohdan and I'm new in Qt an C++ at all. There is a some programm for windows called networx. It shows a live internet speed of all connections on your computer. So as I am using Ubuntu I'v decided to write something like that. First my dissapointment was that I can't make my programm as indicator. Then I began with learning QNetwork module. And my second dissapointment was that I couldn't find any ways to get system traffic statistic to calculate current internet speed. Can anyone help me with ideas or links?



  • Welcome to DevNet,

    What do you mean "make program as an indicator"?
    Do you mean a "system tray":http://qt-project.org/doc/qt-5/QSystemTrayIcon.html#details or something else.

    For network information check out "Bearer Management":http://qt-project.org/doc/qt-5/bearer-management.html it may contain some data.



  • andreyc, thank you for a reply :) Indicator is a somekind of system tray icon for Ubuntu. But system tray icon can't display dynamic text wich is need for my programm.
    I've read Bearer Managment and could find only how to get received bytes in session wich I'v just open in programm. But I need a whole connections on my computer.



  • [quote]But system tray icon can’t display dynamic text wich is need for my programm.[/quote]
    I think you can display dynamic text and images. Take a look on "systray example":http://qt-project.org/doc/qt-4.8/all-examples.html

    [quote]But I need a whole connections on my computer.[/quote]
    I don't think that Qt provides such info. You may need to use OS specific calls to determine that. Something like "this":http://man7.org/linux/man-pages/man3/getifaddrs.3.html



  • andeyc,your advice is really great ! :) I'm started to learn ifaddrs.h library. Past you this code:
    @int main(int argc, char *argv[])
    {
    QGuiApplication app(argc, argv);

    struct ifaddrs *ifaddr, *ifa;
    int family, n;
    
    if (getifaddrs(&ifaddr) == -1) {
    qDebug() << "Error getting ifaddrs";
    }
    for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
      if (ifa->ifa_addr == NULL)
         continue;
     family = ifa->ifa_addr->sa_family;
    
     if (family == AF_PACKET && ifa->ifa_data != NULL) {
              struct rtnl_link_stats *stats = ifa->ifa_data;
         qDebug() << "Downloaded bytes:"<< stats->tx_bytes << "Uploaded bytes:" << stats->rx_bytes;
     qDebug() << "Netinterface name is" << ifa->ifa_name;
     }
    
    }@
    

    and when I exec it I get an error:
    @/home/bohdan/qt_tut/NetSpeedQML/main.cpp:23: error: invalid conversion from 'void*' to 'rtnl_link_stats*' [-fpermissive]
    struct rtnl_link_stats *stats = ifa->ifa_data;@
    I took this piece of code from an example from link that you gave me.
    Any suggestions?



  • try to cast the pointers.
    @
    struct rtnl_link_stats stats = static_cast<struct rtnl_link_stats>(ifa->ifa_data);
    @



  • Thanks ! :) It works ^_^ Know I need to find a way how get sent/received bytes per second but not total bytes for all time



  • I understood how to do that :)
    Upd: New code:
    @ if (getifaddrs(&ifaddr) == -1) {
    qDebug() << "Error getting ifaddrs";
    }
    for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
    if (ifa->ifa_addr == NULL)
    continue;
    family = ifa->ifa_addr->sa_family;

     if ((family == AF_PACKET) && (ifa->ifa_data != NULL)) {
         struct rtnl_link_stats *stats = static_cast<struct rtnl_link_stats*>(ifa->ifa_data);
         currentB += stats->rx_bytes;
         qDebug()  << "Recieved bytes:" << stats->rx_bytes;
     qDebug() << "Netinterface name is" << ifa->ifa_name;
     }
    
    }
    speed = (currentB - previousB) / 1024;
    if(speed > 1000)
    {
        speed = speed / 1024;
        if(speed > 1000)
        {
            speed = speed / 1024;
            qDebug()<< "Downloaded speed is " << speed <<"MB/s";
        }
        else{
            qDebug()<< "Downloaded speed is " << speed <<"KB/s";
        }
    }
    else{
        qDebug()<< "Downloaded speed is " << speed <<"B/s";
    }
    previousB = currentB;
    freeifaddrs(ifaddr);
    timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()),this,SLOT(updateData()));
    timer->start(1000);@
    

    And output:
    @Recieved bytes: 135873
    Netinterface name is lo
    Recieved bytes: 0
    Netinterface name is eth0
    Recieved bytes: 277375800
    Netinterface name is wlan0
    Downloaded speed is 264.655 KB/s
    Recieved bytes: 135873
    Netinterface name is lo
    Recieved bytes: 0
    Netinterface name is eth0
    Recieved bytes: 277647542
    Netinterface name is wlan0
    Current Bytes: 555295088 Previous bytes: 277511673 Speed: 277783415
    Downloaded speed is 264.914 KB/s
    Recieved bytes: 135873
    Netinterface name is lo
    Recieved bytes: 0
    Netinterface name is eth0
    Recieved bytes: 277892743
    Netinterface name is wlan0
    Current Bytes: 833323704 Previous bytes: 555295088 Speed: 278028616
    Downloaded speed is 265.148 KB/s@
    As you can see speed changes slow and only to higher value. By the way, this speed isn't as real speed(I was watching when was downloading a file). What I'm doing wrong?
    Upd: I forget to null currentB :) Now it works fine



  • So, QSystemTrayIcon can only show dynamic text as notification. But I actually need dynamic text in place of icon. Besides, QSystemTrayIcon bad works in ubuntu - icon is not in the tray, it somewhere else on the left top. Now I'm found some articles how combine qt+Gtk+ to make an indicator, but I think it is a bad idea.


  • Lifetime Qt Champion

    Hi,

    Just a quick idea but you could create your own icon using a QImage where you write the text on and then update the current QSystemTrayIcon icon.

    Are you using ubuntu's Qt or your own ? They are know to patch Qt to make it work with Ubuntu.

    Hope it helps



  • SGaist, thank you for reply. I also had idea to make QImage with text, but it can embed text only when saving an image. It will slow a programm. I use own Qt because in ubuntu's was an old QTCreator and old version of QT(5.2.1). I tried to do next thing:
    @QImage *icon;
    QSystemTrayIcon *sysicon;
    icon = new QImage(150,100,QImage::Format_ARGB32);
    icon->fill(qRgba(0,0,0,0));
    icon->setText("Speed","124KB/s");
    QPixmap *pxm = new QPixmap(100,25);
    QPainter *paint = new QPainter(pxm);
    paint->setPen(Qt::blue);
    paint->setFont(QFont("Arial", 30));
    paint->drawText(0,0,QString("125 Kb/s"));
    sysicon = new QSystemTrayIcon(parent);
    sysicon->setIcon(QIcon(*pxm));
    sysicon->show();
    sysicon->setVisible(true);
    @
    And when I running it I see only a small rectangle in the left top corner. I don't know how to make QSystemTrayIcon work in Ubuntu.


  • Lifetime Qt Champion

    QImage can be painted the same way as QPixmap.

    You misunderstood the usage of setText, it won't draw anything.

    Also, you are creating a memory leak here. There's no need to allocate everything on the heap.



  • Ok, look at this code and screenshot:
    @
    icon = QImage(150,100,QImage::Format_ARGB32);
    //icon->fill(qRgba(0,0,0,0));
    icon->fill(Qt::red);
    //QPixmap *pxm = new QPixmap(100,25);
    //QPainter *paint = new QPainter(pxm);
    QPainter *paint = new QPainter(icon);
    paint->setPen(Qt::blue);
    paint->setFont(QFont("Ubuntu", 30));
    paint->drawText(0,0,QString("125 Kb/s"));
    sysicon = QSystemTrayIcon(parent);
    sysicon->setIcon(QIcon(QPixmap::fromImage(&icon)));
    sysicon->show();
    sysicon->setVisible(true);
    setWindowIcon(QIcon(QPixmap::fromImage(&icon)));
    @
    Look at top left corner - this is a tray icon.
    !http://s52.radikal.ru/i137/1407/0b/3cf6f93c51be.png(screen)!
    About Ubuntu's plugin - it can only make a programm with qml code, but not as a widget-base programm. As you know QSystemTrayIcon is a part of QWidgets so I can't use it in qml


  • Lifetime Qt Champion

    @
    icon = QImage(150,100,QImage::Format_ARGB32);
    //icon->fill(qRgba(0,0,0,0));
    icon->fill(Qt::red);
    //QPixmap *pxm = new QPixmap(100,25);
    //QPainter *paint = new QPainter(pxm);
    QPainter *paint = new QPainter(icon); << Why new ?
    paint->setPen(Qt::blue);
    paint->setFont(QFont("Ubuntu", 30));
    paint->drawText(0,0,QString("125 Kb/s"));
    // you are missing a call to end
    sysicon = QSystemTrayIcon(parent);
    sysicon->setIcon(QIcon(QPixmap::fromImage(&icon))); << why the & ?
    sysicon->show();
    sysicon->setVisible(true);
    setWindowIcon(QIcon(QPixmap::fromImage(&icon))); << same question
    @

    There's nothing stoping you from combing both.



  • I was discovering Ubuntu SDK(ubuntu plugin for qt creator) and realised ubuntu sdk helps developing only for mobile and tablet. So there is nothing that helps me with my problem.
    Now about QSystemTrayIcon:
    I found that icon has a fixed size(about 22x22 px and it's a square),so it can not be changed. If I try a bigger size icon it only resize it according to fixed size. But I actually need a rectangle for a text of speed. And problem #2: how can I move my icon from left top corner to right top corner where are the other icons?
    !http://s008.radikal.ru/i304/1407/4d/ab8433b5149d.png(img)!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.