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