最近要写一个windows下的监控客户端,需要收集计算机的一些信息。

其中CPU使用率、可用物理内存(用于计算内存使用率)、上传/下载速率、磁盘读写速率,都需要实时的。各种资料查询之后,决定使用pdh性能计数器来做。

下面直接贴实现函数。需要注意的有几点:1、首先需要导入pdh的lib库;2、注意接收pdh函数的返回值,判断程序运行状态;3、需求是要收集实时值,所以开一个线程,每秒调用一次实现函数即可;4、在通过pdh函数获取数据时,需要延时,否则会导致数据不准确;5、网速的查询是特别的,因为查询语句中会带有网络适配器的名称,也就是网卡名,对于多张网卡的情况,需要自行确定走的是哪个网卡。而不同计算机名称都会不同,所以将该变量放在配置文件中,以保证代码的一致。

还有个疑问,不知道为什么PdhCollectQueryData()需要调用两次,调用一次收集会失败。

最后收集的数据放在结构体中,并压入队列,等待上传到服务端。目前实现是每收集到一组数据就上传一次,当然也可以通过链表长度和时间来控制上传频率。

由于数据最终是以二进制流的方式上传到服务端,所以结构体定义成了类的形式,带了打包、解包函数。如下:

//用于保存搜集的实时数据
class RealtimeData : public MY_OBJECT
{
public:int  iCPUUsage;          // CPU使用率double dbDownloadSpeed;        // 下载速率double   dbUploadSpeed;          // 上传速率int  iMemory;            // 可用内存(M)double    dbDiskRead;         // 磁盘读速率double  dbDiskWrite;            // 磁盘写速率INT64   time;               // 本次搜集的本机时间public://把内部结构打包成char*格式的扁平格式//外部需要自行delete它传出来的char*,用delete []来释放//参数 char * pDataBuf 如果不为 NULL, 则序列化后的结果会保存到这个缓冲指向的空间virtual char * Package_( char * pDataBuf = NULL ) const;//把Package打包的结果反打包,并还原到本类自身//返回处理的字节数,返回-1表示处理失败virtual int UnPackage_( const char * Stream );//获得Package打包后字节流的长度virtual int GetPackageLength_() const;
};//搜集的实时数据的链表,用于发送
class RealtimeDataList : public MY_OBJECT
{
public:CMyStdVector<RealtimeData> vtRealtimeDataList;public://把内部结构打包成char*格式的扁平格式//外部需要自行delete它传出来的char*,用delete []来释放//参数 char * pDataBuf 如果不为 NULL, 则序列化后的结果会保存到这个缓冲指向的空间virtual char * Package_( char * pDataBuf = NULL ) const;//把Package打包的结果反打包,并还原到本类自身//返回处理的字节数,返回-1表示处理失败virtual int UnPackage_( const char * Stream );//获得Package打包后字节流的长度virtual int GetPackageLength_() const;
};

PDH数据收集实现函数如下:

BOOL CMonitorClientWorkTread::GatherRealtimeData()
{HQUERY query;  double dbVal;long iVal;PDH_STATUS status = PdhOpenQuery(NULL, NULL, &query);  if (ERROR_SUCCESS != status)  {  printf("性能计数器查询,打开失败。");return FALSE;}HCOUNTER cntCPU, cntNetDownload, cntNetUpload;  HCOUNTER cntMemory, cntDiskRead, cntDiskWrite;char strNetWork[MAX_PATH];GetPrivateProfileString("data", "network", "", strNetWork, MAX_PATH, m_strConfigDir);  //从配置文件中获取网络适配器名称,用于拼接PDH查询字符串status = PdhAddCounter(query, _TEXT("\\Processor(_Total)\\% Processor Time"), NULL, &cntCPU); //%号和P之间要有空格char strNetReveive[MAX_PATH], strNetSent[MAX_PATH];sprintf_s(strNetReveive, "\\Network Interface(%s)\\Bytes Received/sec", strNetWork);sprintf_s(strNetSent, "\\Network Interface(%s)\\Bytes Sent/sec", strNetWork);status = PdhAddCounter(query, strNetReveive, NULL, &cntNetDownload);status = PdhAddCounter(query, strNetSent, NULL, &cntNetUpload);status = PdhAddCounter(query, _TEXT("\\Memory\\Available MBytes"), NULL, &cntMemory);status = PdhAddCounter(query, _TEXT("\\PhysicalDisk(_Total)\\Disk Read Bytes/sec"), NULL, &cntDiskRead);status = PdhAddCounter(query, _TEXT("\\PhysicalDisk(_Total)\\Disk Write Bytes/sec"), NULL, &cntDiskWrite);if (ERROR_SUCCESS != status)  {  printf("性能计数器查询,查询添加失败。");return FALSE;}  PdhCollectQueryData(query);        Sleep(500);                 //这里要有延时不然结果相当不准确  PdhCollectQueryData(query);  if(ERROR_SUCCESS != status)  {  printf("性能计数器查询,数据请求失败。");return FALSE; }  PDH_FMT_COUNTERVALUE pdhValue;       DWORD dwValue;  RealtimeData realtimeData;status = PdhGetFormattedCounterValue(cntCPU, PDH_FMT_DOUBLE, &dwValue, &pdhValue);  if(ERROR_SUCCESS != status)  {  printf("性能计数器查询,获取数据失败,CPU使用率。");return FALSE; }else{dbVal = pdhValue.doubleValue;  realtimeData.iCPUUsage = (int)(dbVal+0.5);}status = PdhGetFormattedCounterValue(cntNetDownload, PDH_FMT_DOUBLE, &dwValue, &pdhValue);if(ERROR_SUCCESS != status)  {  printf("性能计数器查询,获取数据失败,下载速率。");return FALSE;  }else{dbVal = pdhValue.doubleValue;  realtimeData.dbDownloadSpeed = (double)((dbVal/(1024*1.0f)));}status = PdhGetFormattedCounterValue(cntNetUpload, PDH_FMT_DOUBLE, &dwValue, &pdhValue);if(ERROR_SUCCESS != status)  {  printf("性能计数器查询,获取数据失败,上传速率。");return FALSE;  }else{dbVal = pdhValue.doubleValue;  realtimeData.dbUploadSpeed = (double)((dbVal/(1024*1.0f)));}status = PdhGetFormattedCounterValue(cntMemory, PDH_FMT_LONG, &dwValue, &pdhValue);if(ERROR_SUCCESS != status)  {  printf("性能计数器查询,获取数据失败,可用物理内存。");return FALSE;  }else{iVal = pdhValue.longValue;  realtimeData.iMemory = iVal;}status = PdhGetFormattedCounterValue(cntDiskRead, PDH_FMT_DOUBLE, &dwValue, &pdhValue);if(ERROR_SUCCESS != status)  {  printf("性能计数器查询,获取数据失败,磁盘读速率。");return FALSE;  }else{dbVal= pdhValue.doubleValue;  realtimeData.dbDiskRead = (double)((dbVal/(1024*1.0f)));}status = PdhGetFormattedCounterValue(cntDiskWrite, PDH_FMT_DOUBLE, &dwValue, &pdhValue);if(ERROR_SUCCESS != status)  {  printf("性能计数器查询,获取数据失败,磁盘写速率。");return FALSE;  }else{dbVal = pdhValue.doubleValue;  realtimeData.dbDiskWrite = (double)((dbVal/(1024*1.0f)));}PdhRemoveCounter(cntCPU);PdhRemoveCounter(cntNetDownload);PdhRemoveCounter(cntNetUpload);PdhCloseQuery(query);//将收集到的实时数据保存到链表中time (&realtimeData.time);/*struct tm *st;st = localtime(&realtimeData.time);*/m_realtimeDataList.vtRealtimeDataList.push_back(realtimeData);//将链表数据发送到服务端MsgHead head;head.nMsgLenght = m_realtimeDataList.GetPackageLength();head.nMsgType   = MT_REALTIMEDATA;CMessageItem * pItem = gMsgItemObtain.GetNewMsgItem(); pItem->SetMessageCode( HS_SEND_NETWORK_DATA );pItem->SetAutoReduceRefAfterMsgLoop( true );// 消息头pItem->SetData(&head,sizeof(head));char *p;p = m_realtimeDataList.Package();pItem->AppendDate(p,head.nMsgLenght);gGlobalEnvManager.PostMessage( HSDLL_THREAD_NAME, pItem );delete p;m_realtimeDataList.vtRealtimeDataList.pop_back();return TRUE;
}

使用PDH性能计数器(Windows)获取CPU使用率、可用物理内存、上传/下载速率、磁盘读写速率相关推荐

  1. Linux和windows下minio+springboot实现文件服务器上传下载和nginx反向代理

    1 minio服务器的安装 在下载minio.exe文件: windows安装minio服务器:MinIO | Code and downloads to create high performanc ...

  2. python采集修改原创_python应用系列教程——python中ftp操作:连接、登录、获取目录,重定向、上传下载,删除更改...

    python中ftp操作: ftp=FTP() #设置变量 ftp.set_debuglevel(2) #打开调试级别2,显示详细信息 ftp.connect("IP"," ...

  3. ssm上传文件获取路径_SSM实现图片上传下载功能

    0. 基本步骤框架搭建 实现带图片上传的注册功能 实现下载功能 1. 框架搭建 Step1 创建开发项目 创建基础MVC包结构:controller.service.mapper.pojo Step2 ...

  4. python应用系列教程——python中ftp操作:连接、登录、获取目录,重定向、上传下载,删除更改

    全栈工程师开发手册 (作者:栾鹏) python教程全解 python中ftp操作: ftp=FTP() #设置变量 ftp.set_debuglevel(2) #打开调试级别2,显示详细信息 ftp ...

  5. 使用PSFTP进行Windows与Linux远程服务器的上传下载

    1.下载: 2.使用 2.1 双击即可使用 2.2 使用规范 我说点常用的,我们用PSFTP主要也就是上传和下载.PSFTP是PuTTY SFTP客户端,用于本地与服务器间安全传输文件(使用SSH连接 ...

  6. Windows获取CPU、内存和磁盘使用率脚本

    获取CPU使用率脚本(vbs),另存为cpu.vbs: On Error Resume Next Set objProc = GetObject("winmgmts:\\.\root\cim ...

  7. java获取网络带宽_Linux Java 获取CPU使用率,内存使用率,磁盘IO,网络带宽使用率等等...

    /** * 获取带宽上传下载速度 * @return */ public String getNetWorkSpeed() { boolean result = false; String detai ...

  8. Qt linux获取cpu使用率、内存、网络收发速度、磁盘读写速度、磁盘剩余空间等

    Qt linux获取cpu使用率.内存.网络收发速度.磁盘读写速度.磁盘剩余空间等,实际上大部分都和qt无关的,用其他语言也可以获取. code: .h #ifndef RESOURCE_MINITO ...

  9. ios android cpu占用率,iPhone-iOS-从应用程序获取CPU使用率

    iPhone-iOS-从应用程序获取CPU使用率 有谁知道如何获取应用程序的CPU使用率? 绝对有可能,因为应用商店中有一些可以显示它的应用程序(活动监视器触摸). 3个解决方案 74 votes 更 ...

最新文章

  1. IJCAI 2021 医药AI必读论文推荐
  2. 推荐一个妹子,播报汽车新闻
  3. 同事操作两个数据源保持事务一致_「微服务架构」微服务架构中的数据一致性...
  4. 5g时代计算机网络过时,5g云电脑 取代主机(5g时代云电脑会普及吗)
  5. 北航计算机组成原理课程设计-2020秋 PreProject-Logisim-Logisim仿真与调试应用与挑战
  6. linux下codeblock使用注意事项 (deepin)
  7. 2011年上半年国内优秀初创企业产品汇总
  8. Youtube油管视频类别标签列表
  9. fanuc机器人四边形编程_FANUC机器人编程与操作
  10. SpringIOC和DI简单总结
  11. xcode8 上传app到appStore 遇到 error ITMS90096
  12. 国际赛事证书,220G数据集开放下载|ACCV2022国际细粒度图像分析挑战赛开赛
  13. R配对样本t检验(PAIRED T-TEST​​​​​​​)
  14. python计算AUC、Accuracy、Recall、Precision和PPV
  15. 软件测试之测试用例设计(三)
  16. C语言3067答案,教师招聘《小学教育心理学》通关试题每日练(2020年03月03日-3067)...
  17. [统计学理论基础] 方差 协方差 标准差
  18. 再生核希尔伯特空间(RKHS)
  19. Element Ui之利用sort-change事件及sortable属性实现Table表格指定列的排序
  20. tvos 刷新焦点_如何为大型团队设置可扩展的iOS / tvOS / watchOS Xcode项目,并避免代码冲突?...

热门文章

  1. Python中的幸存者实体提取和网络图
  2. 《Java SE实战指南》05:词法结构(Lexical Structure)
  3. 哈希算法、哈希表的作用与原理
  4. Linux的用户及权限管理
  5. 运动蓝牙耳机什么牌子的好,跑步运动耳机推荐
  6. AXI 总线学习记录
  7. jsp用idea打war包,部署阿里云ecs
  8. 一入鸿蒙深似海,从此Spring是路人:开篇
  9. getenforce setenforce
  10. 螺旋矩阵java_Java 实现螺旋矩阵的方法