Qt获取网络流量(调用Windows API)----StateReader系列

因自己的笔记本没有带CapLock和NumLock的灯,导致某一次输入密码一直出错。之前也找过类似的软件,当到了下载的时候开始犹豫不决,怕当时的程序留了后台,偷偷获取我的按键信息。于是下决心写个取电脑按键状态的程序。——此为背景

借着此势,顺便想给这个程序开发些新功能,于是想到了这个。可是在网上找了很久都没有找到Qt相关获取网卡流量的内容。无意间找到了在用Windows API获取流量的例子。

因为需要隔一定时间读取一次流量,于是选择了平时没怎么用过的QThread(用QTimer也完全可以实现同样的功能)。读取的功能主要放在run() 里,其中GetIfTable(….)是程序的关键部分,MSDN中有介绍,说是获取本地系统网卡的信息。
(GetIfTable参见https://msdn.microsoft.com/zh-cn/aa365943)

知道了上面说到的那个很牛的API后,程序在实现上不是很难。
实现思路:获取本次的网络比特数d1,再读取下一时刻的网络比特数d2。于是可以算出它的网速:s = (d2-d1)/t。但这个函数读回来的数据没有360的准确,好像是360等公司是自己从NDI驱动上进行了修改并实现了读取。这方面对于我这个Qt小白就有些力不从心。

#include "winsock2.h" 
#include "windows.h"
#include "winsock.h"
#include "iphlpapi.h"

注意:上面的头文件一定需要,而且winsock2.h要放在上面,不信你可以试试。如果不写winsock2.h会出现很多错误:比如 “error: ‘ADDRESS_FAMILY’ does not name a type“。在解决这个问题的时候花了很多时间。

class NetInfoThread : public QThread
{
    void run();
}
void NetInfoThread::run()
{
    QString NetSpeedInfo;
    PMIB_IFTABLE    m_pTable = NULL;
    DWORD    m_dwAdapters = 0;
    ULONG    uRetCode = GetIfTable(m_pTable, &m_dwAdapters, TRUE);
    if (uRetCode == ERROR_NOT_SUPPORTED)
    {
        //return (-1);
        return;
    }

    if (uRetCode == ERROR_INSUFFICIENT_BUFFER)
    {
        m_pTable = (PMIB_IFTABLE)new BYTE[65535];   //假设端口数不超过65535个
    }

    DWORD   dwLastIn = 0;           //上一秒钟的接收字节数
    DWORD   dwLastOut = 0;          //上一秒钟的发送字节数
    DWORD   dwBandIn = 0;           //下载速度
    DWORD   dwBandOut = 0;          //上传速度

    while (!stopped)
    {
        NetSpeedInfo.clear();
        GetIfTable(m_pTable, &m_dwAdapters, TRUE);
        DWORD   dwInOctets = 0;
        DWORD   dwOutOctets = 0;

        //将所有端口的流量进行统计
        for (UINT i = 0; i < m_pTable->dwNumEntries; i++)
        {
            MIB_IFROW   Row = m_pTable->table[i];
            dwInOctets += Row.dwInOctets;
            dwOutOctets += Row.dwOutOctets;
        }

        dwBandIn = dwInOctets - dwLastIn;       //下载速度
        dwBandOut = dwOutOctets - dwLastOut;    //上床速速
        if (dwLastIn <= 0)
        {
            dwBandIn = 0;
        }
        else
        {
            dwBandIn = dwBandIn / 1024; //b转换成kb
        }

        if (dwLastOut <= 0)
        {
            dwBandOut = 0;
        }
        else
        {
            dwBandOut = dwBandOut / 1024;   //b转换成kb
        }

        dwLastIn = dwInOctets;
        dwLastOut = dwOutOctets;

//        printf("收到字节: %u bytes\n", dwLastIn);
//        printf("发送字节: %u bytes\n", dwLastOut);
//        printf("下行速度: %u KB\n", dwBandIn);
//        printf("上行速度: %u KB\n", dwBandOut);
//        printf("--------------------------\n");
        NetSpeedInfo = QString("收到字节: %1 bytes\r\n"
                               "发送字节: %2 bytes\r\n"
                               "下行速度: %3 Kb\r\n"
                               "上行速度: %4 kb\r\n")
                                .arg(dwLastIn)
                                .arg(dwLastOut)
                                .arg(dwBandIn)
                                .arg(dwBandOut);
        emit netspeedResult(NetSpeedInfo);
        sleep(1);       //休眠一秒钟
    }
    delete [] m_pTable;
}

上效果图:Qt获取网络流量(调用Windows API)----StateReader系列_第1张图片

你可能感兴趣的:(网络,qt,流量,WindowsApi)