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

Qt学习笔记 专栏收录该内容
13 篇文章 0 订阅

因自己的笔记本没有带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;
}

上效果图:流量实时速度

  • 2
    点赞
  • 2
    评论
  • 6
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

Win10 VS2013 ************************************************ * BOOL GetDiskSpaceInfo(LPCSTR pszDrive * 功能 根据输入的驱动器,获取磁盘总容量 * 空闲空间、簇数量等磁盘信息 * 参数 驱动器根路径,比如“D:\”。 ************************************************ * void GetTime() * 功能 获取并显示本地与系统时间 ************************************************ * void GetLang() * 功能 获取并显示系统的默认语言 ************************************************ * void ShowVersionInfo() * 功能 获取并显示系统版本信息 ************************************************ * void ShowSystemInfo() * 功能 获取并显示硬件相关信息 ************************************************ *void GetFolders() * 功能 获取系统目录等信息 ************************************************ *void WINAPI EnumProcess1() * 功能 调用EnumProcess遍历进程 * 并调用ListProcessModules1函数和 * ListProcessThreads函数列举模块 * 和线程 ************************************************ * VOID ListProcessModules1( DWORD dwPID ) * 功能 调用EnumProcessModules函数 * 列举和显示进程加载的模块 * * 参数 DWORD dwPID 进程PID ************************************************ * VOID ListProcessThreads( DWORD dwPID ) * 功能 调用Thread32First和Thread32Next * 显示一个进程的线程 * * 参数 DWORD dwPID 进程PID ************************************************ * VOID PrintError( LPTSTR msg ) * 功能 打印出错信息 * * 参数 LPTSTR msg ************************************************ * void GetDriveInfo( LPCTSTR lpRootPath) * 功能 返 回 指 定 驱 动 器 的 类 型。 * * 参数 lpRootPathName ************************************************ * void GetSystemMetric(int nIndex) * 功能 返 回 显 示 器 分 辨 率。 * * 参数 ************************************************ * void GetKeyboardInfo() * 功能 返回键盘类型。 * * 参数 *************************************************
©️2021 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值