一个Window/Linux(Fedora测试平台)的CPU,磁盘,内存,PC,进程相关信息采集功能
Posted 篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个Window/Linux(Fedora测试平台)的CPU,磁盘,内存,PC,进程相关信息采集功能相关的知识,希望对你有一定的参考价值。 说明:采用的是Multi-Byte Character Set,不支持Unicode。 Peer2PeerData.h .h .cpp 以上是关于一个Window/Linux(Fedora测试平台)的CPU,磁盘,内存,PC,进程相关信息采集功能的主要内容,如果未能解决你的问题,请参考以下文章 Fedora 25 (linux平台)开源的PDF文件编辑工具——PDF mod Fedora 25文件对比目录对比工具——Meld——Linux平台的对比工具#ifndef _PEER_2_PEER_DATA_H
#define _PEER_2_PEER_DATA_H
#include <cstring>
/* unsigned long long */
typedef unsigned long long ULLong;
#define ELAPSEDSECONDS 10000000
#define ADAYTOTALSECONDS (1 * 24 * 60 * 60)
#define RECEIVED_BUFFER_LENGTH (1024 * 4)
#define QUERY_SLEEP_TIMESTAMP_MS 1024
#define MESSAGEMAXLENGGTH (1024 * 1024 * 128)
#define HEADER 0x02
#define PACKHEADERLENGTH (1 + sizeof(int))
#define TYPE_CPUUSAGE 1
#define TYPE_MEMORYUSAGE 2
#define TYPE_DRIVEUSAGE 3
#define TYPE_RUNTHEFILE 4
#define TYPE_PROCESSINFO 5
#define TYPE_CMD_CURRENT 20
#define TYPE_CMD_AVERAGE 702
#define TYPE_CMD_APPOINT 888
#define TYPE_CMD_RESERVE 999
#define CMD_CALC_UNIT_MINUTES 101
#define CMD_CALC_UNIT_HOURS 45
#define UNIT_VALUE_ONE 1
#define UNIT_VALUE_THREE 3
#define UNIT_VALUE_SIX 6
#define UNIT_VALUE_TEN 10
#define UNIT_VALUE_TWELVE 12
#define UNIT_VALUE_TWENTYFOUR 24
#define UNIT_VALUE_THIRTY 30
#define UNIT_VALUE_SIXTY 60
/* 磁盘/挂载/盘符容量信息 */
struct CapacityInfo
{
/* 总值(kB) */
ULLong m_nTotal;
/* 空闲值(kB) */
ULLong m_nFree;
/* 磁盘/挂载/盘符名称 */
char m_szName[128];
CapacityInfo() : m_nTotal(0), m_nFree(0)
{
memset(m_szName, 0, sizeof(m_szName));
}
};
/* 进程信息 */
struct ProcessInfo
{
/* Start-Time Year */
unsigned short m_nStartTime_Year;
/* Start-Time Month */
unsigned short m_nStartTime_Month;
/* Start-Time Day */
unsigned short m_nStartTime_Day;
/* Start-Time Hour */
unsigned short m_nStartTime_Hour;
/* Start-Time Minute */
unsigned short m_nStartTime_Minute;
/* Start-Time Second */
unsigned short m_nStartTime_Second;
/* Pid */
unsigned short m_nPid;
/* Run-Time(s) */
unsigned long long m_nRunTime;
/* Process Name */
char m_szName[128];
/* Process File-Name */
char m_szFileName[256];
#ifdef WIN32
/* Process Describe */
char m_szDescribe[512];
#endif
ProcessInfo() : m_nPid(0), m_nRunTime(0)
{
m_nStartTime_Year = m_nStartTime_Month = m_nStartTime_Day = m_nStartTime_Hour = m_nStartTime_Minute = m_nStartTime_Second = 0;
memset(m_szName, 0, sizeof(m_szName));
memset(m_szFileName, 0, sizeof(m_szFileName));
#ifdef WIN32
memset(m_szDescribe, 0, sizeof(m_szDescribe));
#endif
}
};
#endif //_PEER_2_PEER_DATA_H
#ifndef _DATA_ACQUISITION_
#define _DATA_ACQUISITION_
#include "Peer2PeerData.h"
#include <vector>
#include <string>
using namespace std;
/*
Data Acquisition (DAQ)
*/
class DataAcquisition
{
public:
DataAcquisition(void);
~DataAcquisition(void);
/*------CPU Start------*/
public:
/**
* CPU核数.
*
* @return int.
* @version 10/28/2016 W Initial Version
**/
int ProcessorCores();
/**
* CPU各核的使用率(%).
*
* @param -[in,out] vector<double> &vUtilization: [使用率]
* @return int.
* @version 10/28/2016 W Initial Version
* @example cpu : 2.47525(%)
* cpu0: 1.96078(%)
* cpu1: 2.2703(%)
* ...
**/
int CpuUsageOfCores(vector<double> &vUtilization);
/**
* 进程的CPU使用率(%).
*
* @param -[in,out] double &nUtilize: [使用率]
* @param -[in] int nPid: [PID]
* @return int.
* @version 10/28/2016 W Initial Version
* @remark -[Pid = -1] Mean Current Process
* @example 2.47525(%)
**/
int CpuUsageByProcess(double &nUtilize, int nPid = -1);
private:
/* CPU Cores */
int m_nProcessorCores;
/*------ CPU End ------*/
/*------Memory Start------*/
public:
/**
* 物理内存(kB).
*
* @param -[in,out] ULLong &nTotal: [总值]
* @return int.
* @version 10/28/2016 W Initial Version
* @example 1024(kB)
**/
int PhysicalMemory(ULLong &nTotal);
/**
* 空闲物理内存(kB).
*
* @param -[in,out] ULLong &nFree: [空闲值]
* @return int.
* @version 10/28/2016 W Initial Version
* @example 512(kB)
**/
int PhysicalMemoryFree(ULLong &nFree);
/**
* 进程的物理内存使用值(kB).
*
* @param -[in,out] ULLong &nUsage: [使用值]
* @param -[in] int nPid: [PID]
* @return int.
* @version 10/28/2016 W Initial Version
* @remark -[Pid = -1] Mean Current Process
* @example 64(kB)
**/
int PhysicalMemroyUsageByProcess(ULLong &nUsage, int nPid = -1);
/**
* 虚拟内存(kB).
*
* @param -[in,out] ULLong &nTotal: [总值]
* @return int.
* @version 10/28/2016 W Initial Version
* @example 1024(kB)
**/
int VirtualMemory(ULLong &nTotal);
/**
* 空闲虚拟内存(kB).
*
* @param -[in,out] ULLong &nFree: [空闲值]
* @return int.
* @version 10/28/2016 W Initial Version
* @example 512(kB)
**/
int VirtualMemoryFree(ULLong &nFree);
/**
* 进程的虚拟内存使用值(kB).
*
* @param -[in,out] ULLong &nUsage: [使用值]
* @param -[in] int nPid: [PID]
* @return int.
* @version 10/28/2016 W Initial Version
* @remark -[Pid = -1] Mean Current Process
* @example 64(kB)
**/
int VirtualMemroyUsageByProcess(ULLong &nUsage, int nPid = -1);
private:
/* 物理内存(kB) */
ULLong m_nPhysicalMemory;
/* 虚拟内存(kB) */
ULLong m_nVirtualMemory;
/*------ Memory End ------*/
/*------Disk Start------*/
public:
/**
* 磁盘数.
*
* @return int.
* @version 10/28/2016 W Initial Version
**/
int DiskCount();
/**
* 挂载/盘符数.
*
* @return int.
* @version 10/28/2016 W Initial Version
**/
int DriveLetterCount();
/**
* 磁盘容量信息.
*
* @param -[in,out] vector<CapacityInfo> &vCapacityInfo: [容量信息]
* @return int.
* @version 10/28/2016 W Initial Version
**/
int TheDiskCapacityInfo(vector<CapacityInfo*> &vCapacityInfo);
/**
* 挂载/盘符容量信息.
*
* @param -[in,out] vector<CapacityInfo> &vCapacityInfo: [容量信息]
* @param -[in] const char* szDriveLetter: [挂载/盘符]
* @return int.
* @version 10/28/2016 W Initial Version
* @remark -[szDriveLetter = NULL] Mean All Drive-Letter
* @example Windows(szDriveLetter = ‘C:\‘), Linux(szDriveLetter = ‘/root‘)
**/
int TheDriveLetterCapacityInfo(vector<CapacityInfo*> &vCapacityInfo, const char* szDriveLetter = NULL);
/*------ Disk End ------*/
/*------Process Start------*/
public:
/**
* 打开文件.
*
* @param -[in] const char* szFile: [文件]
* @param -[in] const char* szParameters: [参数]
* @return int.
* @version 10/28/2016 W Initial Version
* @remark -[szParameters = NULL] Mean Without Parameter
**/
int OpenTheFile(const char* szFile, const char* szParameters = NULL);
/**
* 进程信息.
*
* @param -[in,out] vector<ProcessInfo*> &vProcessInfo: [进程信息]
* @param -[in] int nPid: [PID]
* @return int.
* @version 10/28/2016 W Initial Version
* @remark -[nPid = -1] Mean All Process-Info
**/
int Processes(vector<ProcessInfo*> &vProcessInfo, int nPid = -1);
/**
* 进程信息.
*
* @param -[in] const char* szProcessName: [进程名称]
* @param -[in,out] int &nPid: [PID]
* @return int.
* @version 10/28/2016 W Initial Version
* @remark -[nPid = -1] Mean Error Occurred
**/
int TheProcessIDByName(const char* szProcessName, int &nPid);
/*------ Process End ------*/
/*------PC Start------*/
public:
/**
* Ping.
*
* @param -[in] char* szHostName: [主机地址]
* @return bool.
* @version 10/28/2016 W Initial Version
**/
bool Ping(const char *szIPAddress);
/**
* 主机名称.
*
* @param -[in] char* szHostName: [主机名称]
* @param -[in,out] unsigned long &nLength: [长度]
* @return int.
* @version 10/28/2016 W Initial Version
* @remark -[nPid = -1] Mean Error Occurred
**/
int TheHostName(char* szHostName, unsigned long &nLength);
/**
* 当前用户名称.
*
* @param -[in] char* szUserName: [用户名称]
* @param -[in,out] unsigned long &nLength: [长度]
* @return int.
* @version 10/28/2016 W Initial Version
**/
int TheUserName(char* szUserName, unsigned long &nLength);
/**
* 主机IP.
*
* @param -[in,out] vector<string> &vIPAddress: [IP]
* @param -[in] unsigned short nFamily: [协议]
* @return int.
* @version 10/28/2016 W Initial Version
* @remark OS Family Value
* Windows AF_INET 2
* Windows/Linux AF_INET6 23/10
* Windows AF_UNSPEC 0
**/
int TheHostIPAddress(vector<string> &vIPAddress, unsigned short nFamily /* = AF_INET or AF_INET6 or AF_UNSPEC*/);
/*------ PC End ------*/
/*------Net Start------*/
/*------ Net End ------*/
};
#endif //_DATA_ACQUISITION_
#include "DataAcquisition.h"
//#include <cstdio>
#include <stdio.h>
#include <sstream>
#ifdef WIN32
//#define WIN32_LEAN_AND_MEAN 1
#define C_DRIVERLETTER 0x43
#include <tchar.h>
#include <ctype.h>
#include <Winsock2.h>
#include <WS2tcpip.h>
#include <Windows.h>
#include <TlHelp32.h>
#include <Pdh.h>
#pragma comment(lib, "Pdh.lib")
#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")
#include <IPHlpApi.h>
#pragma comment(lib, "Iphlpapi.lib")
#include <WinIoCtl.h>
#include <ShellAPI.h>
#include <devguid.h>
#include <Setupapi.h>
#pragma comment(lib, "Setupapi.lib")
PDH_HQUERY g_Query = NULL;
PDH_HCOUNTER *g_pCounters = NULL;
PDH_FMT_COUNTERVALUE *g_pCounterValue = NULL;
#else
#ifdef __GNUC__
#include "x86intrin.h"
#define __rdtsc() __builtin_ia32_rdtsc()
#endif
#include <iostream>
#include <vector>
#include <string>
#include <stdio.h>
#include <cstring>
#include <sys/times.h>
#include <sys/vtimes.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/sysinfo.h>
#include <stdlib.h>
#include <dirent.h>
#include <fstream>
#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <map>
#define HERTZ (sysconf(_SC_CLK_TCK) * 1.0)
#define READ_CHARS_LENGTH 256
#endif
using namespace std;
DataAcquisition::DataAcquisition(void) :
m_nProcessorCores(0),
m_nPhysicalMemory(0),
m_nVirtualMemory(0)
{
}
DataAcquisition::~DataAcquisition(void)
{
#ifdef WIN32
if(g_Query)
PdhCloseQuery(g_Query);
if(g_pCounters != NULL || g_pCounterValue != NULL)
{
delete[] g_pCounters;
delete[] g_pCounterValue;
}
#else
#endif
}
/*------Global Function Start------*/
#ifdef WIN32
bool AdjustTokenPrivilege(HANDLE hProcess, DWORD nDesiredAccess = TOKEN_ALL_ACCESS /* TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY */)
{
HANDLE hToken = NULL;
if(!OpenProcessToken(hProcess, nDesiredAccess, &hToken))
{
if(hToken != NULL)
CloseHandle(hToken);
if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
return true;
else return false;
}
TOKEN_PRIVILEGES tokenPrivileges;
if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME/*SE_SECURITY_NAME*/, &tokenPrivileges.Privileges[0].Luid))
{
if(hToken != NULL)
CloseHandle(hToken);
return false;
}
tokenPrivileges.PrivilegeCount = 1;
tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
BOOL bReturn = AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL);
if(hToken != NULL)
CloseHandle(hToken);
return bReturn == TRUE;
}
int TheProcessIDByWindowName(const char* szWinName)
{
DWORD ProcessID = -1;
HWND hWnd = FindWindow(NULL, szWinName);
if (hWnd != NULL)
GetWindowThreadProcessId(hWnd, &ProcessID);
return ProcessID;
}
HANDLE TheProcessByID(int nPid, unsigned long nDesiredAccess = PROCESS_QUERY_INFORMATION /* PROCESS_ALL_ACCESS */)
{
return OpenProcess(nDesiredAccess, FALSE, nPid);
}
#else
void LinesFrom(FILE *pFile, vector<string> &vResult)
{
vResult.clear();
char szLine[READ_CHARS_LENGTH] = { 0 };
while(fgets(szLine, READ_CHARS_LENGTH, pFile) != NULL)
{
int nLength = strlen(szLine);
if(szLine[nLength - 1] == ‘\n‘)
szLine[nLength - 1] = ‘\0‘;
vResult.push_back(szLine);
}
}
int ExecuteCommand(const char *szCommand, vector<string> &vResult)
{
FILE *pCmd = popen(szCommand, "r");
if(pCmd == NULL)
return -1;
LinesFrom(pCmd, vResult);
return pclose(pCmd);
}
int OpenTheFileWithMode(const char *szFile, vector<string> &vResult, const char *szMode = "r")
{
FILE *pFile = fopen(szFile, szMode);
if(pFile == NULL)
return -1;
LinesFrom(pFile, vResult);
return fclose(pFile);
}
int CPUCurrentUsageCalculator(vector<ULLong> &vltTotal, vector<ULLong> &vltIdle)
{
vltTotal.clear();
vltIdle.clear();
// /proc/stat | grep cpu | awk -F ‘ ‘ ‘{ print $2 + $3 + $4 + $5 + $6 + $7 + $8 + $9, $5 }‘
vector<string> vResult;
ExecuteCommand("cat /proc/stat | grep cpu | awk -F ‘ ‘ ‘{ print $2 + $3 + $4 + $5 + $6 + $7 + $8 + $9, $5 }‘", vResult);
int nCores = vResult.size();
for(int i = 0; i < nCores; i++)
{
ULLong ltTotal, ltIdle;
sscanf(vResult[i].c_str(), "%llu %llu", <Total, <Idle);
vltTotal.push_back(ltTotal);
vltIdle.push_back(ltIdle);
}
return nCores;
}
#endif
/*------Global Function End------*/
/*------CPU Start------*/
int DataAcquisition::ProcessorCores()
{
if(m_nProcessorCores == 0)
{
#ifdef WIN32
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
m_nProcessorCores = sysInfo.dwNumberOfProcessors;
#else
m_nProcessorCores = sysconf(_SC_NPROCESSORS_ONLN);
#endif
}
return m_nProcessorCores;
}
int DataAcquisition::CpuUsageOfCores(vector<double> &vUtilization)
{
vUtilization.clear();
int nCores = ProcessorCores();
vUtilization.assign(nCores + 1, 0);
#ifdef WIN32
/*also by FILETIME GetSystemTimes()
utilization = (1 - idle / (kernel + user)) * 100;
*/
if(g_Query == NULL || g_pCounters == NULL)
{
g_pCounters = new PDH_HCOUNTER[nCores + 1];
g_pCounterValue = new PDH_FMT_COUNTERVALUE[nCores + 1];
PdhOpenQuery(NULL, NULL, &g_Query);
PdhAddCounter(g_Query, "\\Processor(_Total)\\% Processor Time", NULL, &g_pCounters[0]);
char szCounterPath[64] = { 0 };
for(int i = 1; i <= nCores; i++)
{
sprintf(szCounterPath, "\\Processor(%d)\\%% Processor Time", i);
PdhAddCounter(g_Query, szCounterPath, NULL, &g_pCounters[i]);
}
PdhCollectQueryData(g_Query);
for(int i = 0; i <= nCores; i++)
{
PdhGetFormattedCounterValue(g_pCounters[i], PDH_FMT_DOUBLE, NULL, &g_pCounterValue[i]);
}
Sleep(QUERY_SLEEP_TIMESTAMP_MS / 8);
}
PdhCollectQueryData(g_Query);
for(int i = 0; i <= nCores; i++)
{
PdhGetFormattedCounterValue(g_pCounters[i], PDH_FMT_DOUBLE, NULL, &g_pCounterValue[i]);
vUtilization[i] = g_pCounterValue[i].doubleValue;
}
//Sleep(QUERY_SLEEP_TIMESTAMP_MS / 16);//WaitForSingleObject
#else
vector<ULLong> vltTotalFirst, vltIdleFirst;
nCores = CPUCurrentUsageCalculator(vltTotalFirst, vltIdleFirst);
sleep(1);
vector<ULLong> vltTotalSecond, vltIdleSecond;
nCores = CPUCurrentUsageCalculator(vltTotalSecond, vltIdleSecond);
for(int i = 0; i < nCores; i++)
{
double divisor = (vltIdleSecond[i] - vltIdleFirst[i]) * 1.0;
double dividend = (vltTotalSecond[i] - vltTotalFirst[i]) * 1.0;
double utilizate = (dividend <= 0 || divisor <= 0) ? 0 : (dividend - divisor) <= 0 ? 0 : (dividend - divisor) / dividend;
vUtilization[i] = utilizate >= 1 ? 100 : utilizate * 100;
}
#endif
return 0;
}
int DataAcquisition::CpuUsageByProcess(double &nUtilize, int nPid)
{
nUtilize = 0;
#ifdef WIN32
/*also by "\\Process(%s)\\% Processor Time"
%s=The Process Name;
*/
ULARGE_INTEGER uiPFistIdle, uiPFistKernel, uiPFistUser;
FILETIME ftPFistIdle, ftPFistKernel, ftPFistUser;
GetSystemTimeAsFileTime(&ftPFistIdle);
memcpy(&uiPFistIdle, &ftPFistIdle, sizeof(FILETIME));
HANDLE hProcess = nPid == -1 ? GetCurrentProcess() : TheProcessByID(nPid);
AdjustTokenPrivilege(hProcess);
if(FALSE == GetProcessTimes(hProcess, &ftPFistIdle, &ftPFistIdle, &ftPFistKernel, &ftPFistUser))
return -1;
memcpy(&uiPFistUser, &ftPFistUser, sizeof(FILETIME));
memcpy(&uiPFistKernel, &ftPFistKernel, sizeof(FILETIME));
Sleep(QUERY_SLEEP_TIMESTAMP_MS / 16);//WaitForSingleObject(hProcess, QUERY_SLEEP_TIMESTAMP_MS / 4);
DWORD eCode = 0;
GetExitCodeProcess(hProcess, &eCode);
if(eCode != STILL_ACTIVE)
return -1;
ULARGE_INTEGER uiPSecondIdle, uiPSecondKernel, uiPSecondUser;
FILETIME ftPSecondIdle, ftPSecondKernel, ftPSecondUser;
GetSystemTimeAsFileTime(&ftPSecondIdle);
memcpy(&uiPSecondIdle, &ftPSecondIdle, sizeof(FILETIME));
if(FALSE == GetProcessTimes(hProcess, &ftPSecondIdle, &ftPSecondIdle, &ftPSecondKernel, &ftPSecondUser))
return -1;
memcpy(&uiPSecondUser, &ftPSecondUser, sizeof(FILETIME));
memcpy(&uiPSecondKernel, &ftPSecondKernel, sizeof(FILETIME));
//(kernel + user) / (idle * cors) * 100;
double divisor = (uiPSecondKernel.QuadPart - uiPFistKernel.QuadPart + uiPSecondUser.QuadPart - uiPFistUser.QuadPart) * 1.0;
double dividend = (uiPSecondIdle.QuadPart - uiPFistIdle.QuadPart) * 1.0;
double utilization = (dividend <= 0 || divisor <= 0) ? 0 : divisor / dividend * ProcessorCores();
nUtilize = utilization >= 1 ? 100 : utilization * 100;
#else
// also "ps -p {pid} h -o %cpu"
// cat /proc/{pid}/stat | awk -F ‘ ‘ ‘{ print $14 + $15 + $16 + $17 }‘
if(nPid == 0)
return -1;
if(nPid <= -1)
nPid = getpid();
char cmd[128] = { 0 };
sprintf(cmd, "cat /proc/%i/stat | awk -F ‘ ‘ ‘{ print $14 + $15 + $16 + $17 }‘", nPid);
vector<string> vResult;
ExecuteCommand(cmd, vResult);
if(vResult.size() == 0)
return -1;
ULLong nTotalFirst;
sscanf(vResult[0].c_str(), "%llu", &nTotalFirst);
vector<ULLong> vltTotalFirst, vltIdleFirst;
CPUCurrentUsageCalculator(vltTotalFirst, vltIdleFirst);
sleep(1);
ExecuteCommand(cmd, vResult);
if(vResult.size() == 0)
return -1;
ULLong nTotalSecond;
sscanf(vResult[0].c_str(), "%llu", &nTotalSecond);
vector<ULLong> vltTotalSecond, vltIdleSecond;
CPUCurrentUsageCalculator(vltTotalSecond, vltIdleSecond);
double divisor = (nTotalSecond - nTotalFirst) * 1.0;
double dividend = (vltTotalSecond[0] - vltTotalFirst[0]) * 1.0;
double utilization = (dividend <= 0 || divisor <= 0) ? 0 : divisor / dividend * ProcessorCores();
nUtilize = utilization >= 1 ? 100 : utilization * 100;
#endif
return 0;
}
/*------ CPU End ------*/
/*------Memory Start------*/
int DataAcquisition::PhysicalMemory(ULLong &nTotal)
{
if(m_nPhysicalMemory == 0)
{
#ifdef WIN32
MEMORYSTATUSEX vMemory;
vMemory.dwLength = sizeof(MEMORYSTATUSEX);
GlobalMemoryStatusEx(&vMemory);
m_nPhysicalMemory = vMemory.ullTotalPhys / 1024;
#else
struct sysinfo pMemory;
sysinfo(&pMemory);
m_nPhysicalMemory = pMemory.totalram * pMemory.mem_unit / 1024;
#endif
}
nTotal = m_nPhysicalMemory;
return 0;
}
int DataAcquisition::PhysicalMemoryFree(ULLong &nFree)
{
nFree = 0;
#ifdef WIN32
/*also by "\\Memory\\Available Bytes";
*/
MEMORYSTATUSEX vMemory;
vMemory.dwLength = sizeof(MEMORYSTATUSEX);
GlobalMemoryStatusEx(&vMemory);
if(m_nPhysicalMemory == 0)
m_nPhysicalMemory = vMemory.ullTotalPhys / 1024;
nFree = vMemory.ullAvailPhys / 1024;
#else
/*also /proc/meminfo
*/
struct sysinfo pMemory;
sysinfo(&pMemory);
if(m_nPhysicalMemory == 0)
m_nPhysicalMemory = pMemory.totalram * pMemory.mem_unit / 1024;
nFree = pMemory.freeram * pMemory.mem_unit / 1024;
#endif
return 0;
}
int DataAcquisition::PhysicalMemroyUsageByProcess(ULLong &nUsage, int nPid)
{
nUsage = 0;
#ifdef WIN32
PROCESS_MEMORY_COUNTERS pMemCounter;
GetProcessMemoryInfo(nPid == -1 ? GetCurrentProcess() : TheProcessByID(nPid), &pMemCounter, sizeof(PROCESS_MEMORY_COUNTERS));
nUsage = pMemCounter.WorkingSetSize / 1024;
#else
/*also "ps -p {pid} h -o %mem"
*/
if(nPid == 0)
return -1;
if(nPid <= -1)
nPid = getpid();
// grep VmRSS /proc/{nPid}/status
// RssAnon :system-monitor value
char buf[32] = { 0 };
sprintf(buf, "grep VmRSS /proc/%i/status", nPid);
vector<string> vResult;
ExecuteCommand(buf, vResult);
if(vResult.size() == 0)
return -1;
sscanf(vResult[0].c_str(), "VmRSS:%llukB", &nUsage);
#endif
return 0;
}
int DataAcquisition::VirtualMemory(ULLong &nTotal)
{
if(m_nVirtualMemory == 0)
{
#ifdef WIN32
MEMORYSTATUSEX vMemory;
vMemory.dwLength = sizeof(MEMORYSTATUSEX);
GlobalMemoryStatusEx(&vMemory);
m_nVirtualMemory = vMemory.ullTotalVirtual / 1024;
#else
struct sysinfo vMemory;
sysinfo(&vMemory);
m_nVirtualMemory = vMemory.totalswap * vMemory.mem_unit / 1024;
#endif
}
nTotal = m_nVirtualMemory;
return 0;
}
int DataAcquisition::VirtualMemoryFree(ULLong &nFree)
{
nFree = 0;
#ifdef WIN32
MEMORYSTATUSEX vMemory;
vMemory.dwLength = sizeof(MEMORYSTATUSEX);
GlobalMemoryStatusEx(&vMemory);
if(m_nVirtualMemory == 0)
m_nVirtualMemory = vMemory.ullTotalVirtual / 1024;
nFree = vMemory.ullAvailVirtual / 1024;
#else
struct sysinfo vMemory;
sysinfo(&vMemory);
if(m_nVirtualMemory == 0)
m_nVirtualMemory = vMemory.totalswap * vMemory.mem_unit / 1024;
nFree = vMemory.freeswap * vMemory.mem_unit / 1024;
#endif
return 0;
}
int DataAcquisition::VirtualMemroyUsageByProcess(ULLong &nUsage, int nPid)
{
nUsage = 0;
#ifdef WIN32
PROCESS_MEMORY_COUNTERS pMemCounter;
GetProcessMemoryInfo(nPid == -1 ? GetCurrentProcess() : TheProcessByID(nPid), &pMemCounter, sizeof(PROCESS_MEMORY_COUNTERS));
nUsage = pMemCounter.PagefileUsage / 1024;
#else
if(nPid == 0)
return -1;
if(nPid <= -1)
nPid = getpid();
char buf[32] = { 0 };
sprintf(buf, "ps p %i -o vsz h", nPid);
vector<string> vResult;
ExecuteCommand(buf, vResult);
if(vResult.size() == 0)
return -1;
sscanf(vResult[0].c_str(), "%llu", &nUsage);
#endif
return 0;
}
/*------ Memory End ------*/
/*------Disk Start------*/
int DataAcquisition::DiskCount()
{
int nCount = 1;//At Least 1
#ifdef WIN32
HDEVINFO hDeviceInfoSet = SetupDiGetClassDevs(&GUID_DEVCLASS_DISKDRIVE, NULL, NULL, DIGCF_PRESENT);
if (hDeviceInfoSet == INVALID_HANDLE_VALUE)
return nCount;
SP_DEVINFO_DATA deviceInfoData;
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
DWORD nDeviceIndex = 0;
while(SetupDiEnumDeviceInfo(hDeviceInfoSet, nDeviceIndex, &deviceInfoData))
nDeviceIndex++;
if(hDeviceInfoSet)
SetupDiDestroyDeviceInfoList(hDeviceInfoSet);
nCount = nDeviceIndex;
#else
//lsblk -nd | grep -w disk
vector<string> vResult;
ExecuteCommand("lsblk -dn | grep -w disk", vResult);
int nSize = vResult.size();
if(nSize > 0)
return nSize;
#endif
return nCount;
}
int DataAcquisition::DriveLetterCount()
{
int nCount = 0;
#ifdef WIN32
//Bit position 0 (the least-significant bit) is drive A, bit position 1 is drive B, bit position 2 is drive C, and so on.
DWORD nDrive = GetLogicalDrives();
while(nDrive)
{
if(nDrive & 1)
++nCount;
nDrive >>= 1;
}
#else
//df --output=target
vector<string> vResult;
ExecuteCommand("df --output=target", vResult);
int nSize = vResult.size();
if(nSize > 0)
return nSize - 1;
#endif
return nCount;
}
int DataAcquisition::TheDiskCapacityInfo(vector<CapacityInfo*> &vCapacityInfo)
{
vCapacityInfo.clear();
#ifdef WIN32
int nPhsicalDriveCount = DiskCount();
while(nPhsicalDriveCount-- > 0)
{
char szPhysicalDrive[32] = { 0 };
sprintf(szPhysicalDrive, "\\\\.\\PhysicalDrive%d", nPhsicalDriveCount);
HANDLE hDevice = CreateFile(szPhysicalDrive, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
return -1;
DWORD nReturn = 0;
DISK_GEOMETRY outBuffer;
if(DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &outBuffer, sizeof(DISK_GEOMETRY), &nReturn, (LPOVERLAPPED)NULL))
{
CapacityInfo *pCI = new CapacityInfo();
pCI->m_nTotal = outBuffer.Cylinders.QuadPart * (ULONG)outBuffer.TracksPerCylinder * (ULONG)outBuffer.SectorsPerTrack * (ULONG)outBuffer.BytesPerSector / 1024;
vCapacityInfo.push_back(pCI);
}
CloseHandle(hDevice);
}
#else
//lsblk -ndbo name,size,type | grep -w disk | awk -F ‘ ‘ ‘{print $1, $2 / 1024}‘
vector<string> vResult;
ExecuteCommand("lsblk -ndbo name,size,type | grep -w disk | awk -F ‘ ‘ ‘{print $1, $2 / 1024}‘", vResult);
if(vResult.size() == 0)
return -1;
for(vector<string>::iterator item = vResult.begin(); item != vResult.end(); item++)
{
CapacityInfo *pCI = new CapacityInfo();
sscanf(item->c_str(), "%s %llu", pCI->m_szName, &pCI->m_nTotal);
vCapacityInfo.push_back(pCI);
}
#endif
return 0;
}
int DataAcquisition::TheDriveLetterCapacityInfo(vector<CapacityInfo*> &vCapacityInfo, const char* szDriveLetter)
{
vCapacityInfo.clear();
#ifdef WIN32
int nDriveCount = 0, nIndex = 0;
if(szDriveLetter == NULL)
nDriveCount = DriveLetterCount();
char szDriveLetterFormat[4] = { 0 };
ULARGE_INTEGER atc, nTotal, nFree;
do
{
if(szDriveLetter == NULL)
sprintf(szDriveLetterFormat, "%c:\\", C_DRIVERLETTER + nIndex++);
UINT nType = GetDriveType(szDriveLetter == NULL ? szDriveLetterFormat : szDriveLetter);
if(nType != DRIVE_REMOVABLE && nType != DRIVE_FIXED)
continue;
if(GetDiskFreeSpaceEx(szDriveLetter == NULL ? szDriveLetterFormat : szDriveLetter, &atc, &nTotal, &nFree))
{
CapacityInfo *pCI = new CapacityInfo();
pCI->m_nTotal = nTotal.QuadPart / 1024;
pCI->m_nFree = nFree.QuadPart / 1024;
strncpy(pCI->m_szName, szDriveLetter == NULL ? szDriveLetterFormat : szDriveLetter, strlen(szDriveLetter == NULL ? szDriveLetterFormat : szDriveLetter));
vCapacityInfo.push_back(pCI);
}
if(szDriveLetter != NULL)
break;
}while(nIndex < nDriveCount);
#else
vector<string> vResult;
//all of mounted partitions
if(szDriveLetter == NULL)
{
//df -l | grep -E ‘^/|/mnt/‘
ExecuteCommand("df -l | grep -E ‘^/|/mnt/‘", vResult);
}
else//just the special one
{
//df -l | grep -w {szPartition}
if(szDriveLetter[0] != ‘/‘)
return -1;
string cmd("df -l | grep -w ");
cmd.append(szDriveLetter);
ExecuteCommand(cmd.c_str(), vResult);
printf(cmd.c_str());
}
if(vResult.size() == 0)
return -1;
for(vector<string>::iterator item = vResult.begin(); item != vResult.end(); item++)
{
CapacityInfo *pCI = new CapacityInfo();
sscanf(item->c_str(), "%*s %llu %*llu %llu %*i%% %s", &pCI->m_nTotal, &pCI->m_nFree, pCI->m_szName);
vCapacityInfo.push_back(pCI);
}
#endif
return 0;
}
/*------ Disk End ------*/
/*------Process Start------*/
int DataAcquisition::OpenTheFile(const char* szFile, const char* szParameters)
{
#ifdef WIN32
ShellExecute(NULL, "open", szFile, szParameters, NULL, SW_SHOWNORMAL);
return 0;
#else
//execve(szFile, argv, envp);
string cmd(szFile);
if(szParameters != NULL)
{
cmd.append(" ");
cmd.append(szParameters);
}
return system(cmd.c_str());
#endif
}
int DataAcquisition::Processes(vector<ProcessInfo*> &vProcessInfo, int nPid)
{
vProcessInfo.clear();
#ifdef WIN32
AdjustTokenPrivilege(GetCurrentProcess());
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
return -1;
PROCESSENTRY32 proEntry32;
proEntry32.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(hSnapshot, &proEntry32))
{
CloseHandle(hSnapshot);
return -1;
}
while(Process32Next(hSnapshot, &proEntry32))
{
if(nPid != -1)
{
if(proEntry32.th32ProcessID != nPid)
continue;
}
ProcessInfo *pi = new ProcessInfo();
pi->m_nPid = proEntry32.th32ProcessID;
strncpy(pi->m_szName, proEntry32.szExeFile, strlen(proEntry32.szExeFile));
//WideCharToMultiByte(CP_ACP, 0, proEntry32.szExeFile, -1, pi.m_szName, sizeof(pi.m_szName), NULL, NULL);
HANDLE theProcess = TheProcessByID(proEntry32.th32ProcessID);
DWORD dwSize = sizeof(pi->m_szFileName);
QueryFullProcessImageName(theProcess, 0/*PROCESS_NAME_NATIVE or 0*/, pi->m_szFileName, &dwSize);
if(dwSize > 0)
{
/*
Comments InternalName ProductName CompanyName LegalCopyright ProductVersion
FileDescription LegalTrademarks PrivateBuild FileVersion OriginalFilename SpecialBuild
*/
DWORD nHandle = 0;
DWORD nSize = GetFileVersionInfoSize(pi->m_szFileName, &nHandle);
if(nSize > 0)
{
char *szVersionInfo = new char[nSize + 1]();
if(GetFileVersionInfo(pi->m_szFileName, 0, nSize + 1, szVersionInfo))
{
DWORD *nLangCode = NULL;
UINT nLen = 0;
VerQueryValue(szVersionInfo, "\\VarFileInfo\\Translation", (LPVOID*)&nLangCode, &nLen);
char szDes[64] = { 0 };
sprintf(szDes, "\\StringFileInfo\\%04x%04x\\FileDescription", LOWORD(nLangCode[0]), HIWORD(nLangCode[0]));
UINT nLenFileDes = 0;
char *szFileDes = NULL;
VerQueryValue(szVersionInfo, szDes, (LPVOID*)&szFileDes, &nLenFileDes);
memcpy(pi->m_szDescribe, szFileDes, nLenFileDes);
//WideCharToMultiByte(CP_ACP, 0, proEntry32.szExeFile, -1, pi.m_szName, sizeof(pi.m_szName), NULL, NULL);
//char szPN[64] = { 0 };
//sprintf(szPN, "\\StringFileInfo\\%04x%04x\\ProductName", LOWORD(nLangCode[0]), HIWORD(nLangCode[0]));
//UINT nLenProName = 0;
//char *szProName = NULL;
//VerQueryValue(szVersionInfo, szPN, (LPVOID*)&szProName, &nLenProName);
//pi->m_pProductName = new char[nLenProName + 1]();
////WideCharToMultiByte(CP_ACP, 0, proEntry32.szExeFile, -1, pi.m_szName, sizeof(pi.m_szName), NULL, NULL);
//memcpy(pi->m_pProductName, szProName, nLenProName);
}
delete[] szVersionInfo;
}
}
FILETIME ftCreationTime, ftExitTime, ftKernelTime, ftUserTime;
if(GetProcessTimes(theProcess, &ftCreationTime, &ftExitTime, &ftKernelTime, &ftUserTime))
{
//or ULARGE_INTEGER uiStart;
// memcpy(&uiStart, &creationTime, sizeof(ULARGE_INTEGER));
FILETIME ftNowTime;
GetSystemTimeAsFileTime(&ftNowTime);
pi->m_nRunTime = (reinterpret_cast<ULARGE_INTEGER*>(&ftNowTime)->QuadPart - reinterpret_cast<ULARGE_INTEGER*>(&ftCreationTime)->QuadPart) / ELAPSEDSECONDS;
FILETIME ftLocalCreationTime;
FileTimeToLocalFileTime(&ftCreationTime, &ftLocalCreationTime);
SYSTEMTIME stLocalUTC8CreationTime;
FileTimeToSystemTime(&ftLocalCreationTime, &stLocalUTC8CreationTime);
pi->m_nStartTime_Year = stLocalUTC8CreationTime.wYear;
pi->m_nStartTime_Month = stLocalUTC8CreationTime.wMonth;
pi->m_nStartTime_Day = stLocalUTC8CreationTime.wDay;
pi->m_nStartTime_Hour = stLocalUTC8CreationTime.wHour;
pi->m_nStartTime_Minute = stLocalUTC8CreationTime.wMinute;
pi->m_nStartTime_Second = stLocalUTC8CreationTime.wSecond;
}
vProcessInfo.push_back(pi);
if(nPid != -1)
break;
}
CloseHandle(hSnapshot);
#else
static map<string, int> Month = { };
if(Month.size() == 0)
{
Month["Jan"] = 1;Month["Feb"] = 2; Month["Mar"] = 3; Month["Apr"] = 4; Month["May"] = 5; Month["Jun"] = 6;
Month["Jul"] = 7; Month["Aug"] = 8; Month["Sep"] = 9; Month["Oct"] = 10; Month["Nov"] = 11; Month["Dec"] = 12;
}
DIR *dir = opendir("/proc");
if(dir == NULL)
return -1;
char cmd[128] = { 0 };
char month[4] = { 0 };
vector<string> vResult;
struct dirent *dirEnt;
while(dirEnt = readdir(dir))
{
if(dirEnt->d_type != DT_DIR)
continue;
pid_t pid = (pid_t)atoi(dirEnt->d_name);
if(pid <= 0)
continue;
//ps -p 950 -o pid,etimes,lstart h
sprintf(cmd, "ps -p %i -o etimes,lstart h", pid);
ExecuteCommand(cmd, vResult);
ProcessInfo *pi = new ProcessInfo();
if(vResult.size() > 0)
{
sscanf(vResult[0].c_str(), "%llu %*s %s %d %d:%d:%d %d", &pi->m_nRunTime, month, &pi->m_nStartTime_Day, &pi->m_nStartTime_Hour, &pi->m_nStartTime_Minute, &pi->m_nStartTime_Second, &pi->m_nStartTime_Year);
pi->m_nStartTime_Month = Month[string(month)];
}
sprintf(cmd, "/proc/%i/exe", pid);
readlink(cmd, pi->m_szFileName, sizeof(pi->m_szFileName));
int nLength = strlen(pi->m_szFileName);
if(nLength > 0)
strncpy(pi->m_szName, basename(pi->m_szFileName), nLength);
else
{
sprintf(cmd, "cat /proc/%i/comm", pid);
ExecuteCommand(cmd, vResult);
if(vResult.size() > 0)
strncpy(pi->m_szName, vResult[0].c_str(), strlen(vResult[0].c_str()));
else
printf("%d %s\n", pid, "No Result.");
}
pi->m_nPid = static_cast<unsigned short>(pid);
vProcessInfo.push_back(pi);
}
closedir(dir);
#endif
return 0;
}
int DataAcquisition::TheProcessIDByName(const char* szProcessName, int &nPid)
{
nPid = -1;
#ifdef WIN32
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
return -1;
PROCESSENTRY32 process;
process.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(hSnapshot, &process))
{
CloseHandle(hSnapshot);
return -1;
}
while(Process32Next(hSnapshot, &process))
{
if (strcmp(process.szExeFile, szProcessName) == 0)
{
nPid = process.th32ProcessID;
break;
}
}
CloseHandle(hSnapshot);
#else
DIR *dir = opendir("/proc");
if(dir == NULL)
return -1;
struct dirent *dirEnt;
vector<string> vResult;
while(dirEnt = readdir(dir))
{
if(dirEnt->d_type != DT_DIR)
continue;
pid_t pid = (pid_t)atoi(dirEnt->d_name);
if(pid <= 0)
continue;
/* also ls -l /proc/{pid}/exe (better)
// http://man7.org/linux/man-pages/man2/readlink.2.html
*/
//Not Recommended (/proc/{pid}/cmdline)
string cmdPath = string("/proc/") + dirEnt->d_name + "/cmdline";
OpenTheFileWithMode(cmdPath.c_str(), vResult);
if(vResult.size() == 0)
continue;
/*
if(strlen(vResult[0].c_str()) >= TASK_COMM_LEN)
vResult[0][TASK_COMM_LEN] = ‘\0‘;
if(strcmp(szProcessName, vResult[0].c_str()) != 0)
continue;
*/
/*The code below has a bug!!!
also cout << strrchr(vResult[0].c_str(), ‘/‘) + 1 << endl;
*/
string::size_type pos = vResult[0].rfind(‘/‘);
if(pos != string::npos)
{
if(string(szProcessName) != vResult[0].substr(pos + 1))
continue;
}
else
{
if(strcmp(szProcessName, vResult[0].c_str()) != 0)
continue;
}
nPid = pid;
break;
}
closedir(dir);
#endif
return 0;
}
/*------ Process End ------*/
/*------PC Start------*/
bool DataAcquisition::Ping(const char *szIPAddress)
{
#ifdef WIN32
string cmd("cmd /C ping -n 3 -w 1024 ");
cmd.append(szIPAddress);
//WinExec(cmd.c_str(), SW_HIDE);
return system(cmd.c_str()) == 0;
#else
string cmd("ping -c 3 -W 1 ");
cmd.append(szIPAddress);
cmd += " | grep received";
cmd += " | awk -F , ‘{ print $2 }‘ | awk ‘{ print $1 }‘";
vector<string> vResult;
ExecuteCommand(cmd.c_str(), vResult);
if(vResult.size() == 0)
return false;
if(vResult[0] == "0")
return false;
return true;
#endif
}
int DataAcquisition::TheHostName(char* szHostName, unsigned long &nLength)
{
#ifdef WIN32
if(!GetComputerName(szHostName, &nLength)) //char*,DWORD*
return -1;
#else
if(gethostname(szHostName, nLength) == 0)
nLength = strlen(szHostName);
else return -1;
#endif
return 0;
}
int DataAcquisition::TheUserName(char* szUserName, unsigned long &nLength)
{
#ifdef WIN32
if(!GetUserName(szUserName, &nLength))//(w)char*,DWORD*
return -1;
#else
/* also getlogin()
*/
if(getlogin_r(szUserName, nLength) == 0)
nLength = strlen(szUserName);
else return -1;
#endif
return 0;
}
int DataAcquisition::TheHostIPAddress(vector<string> &vIPAddress, unsigned short nFamily)
{
vIPAddress.clear();
#ifdef WIN32
DWORD nSize = 0;
IP_ADAPTER_ADDRESSES *pAdapterAddress = NULL;
GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAdapterAddress, &nSize);
pAdapterAddress = (IP_ADAPTER_ADDRESSES*)malloc(nSize);
if(GetAdaptersAddresses(nFamily, GAA_FLAG_INCLUDE_PREFIX, NULL, pAdapterAddress, &nSize) != ERROR_SUCCESS)
{
free(pAdapterAddress);
return -1;
}
IP_ADAPTER_ADDRESSES *pAdapter = pAdapterAddress;
for(; pAdapter; pAdapter = pAdapter->Next)
{
// Skip loopback adapters
if (IF_TYPE_SOFTWARE_LOOPBACK == pAdapter->IfType)
continue;
// Parse all IPv4 and IPv6 addresses
for(IP_ADAPTER_UNICAST_ADDRESS* pAddress = pAdapter->FirstUnicastAddress; pAddress; pAddress = pAddress->Next)
{
auto family = pAddress->Address.lpSockaddr->sa_family;
if (AF_INET == family)
{
// IPv4
SOCKADDR_IN* Ipv4 = reinterpret_cast<SOCKADDR_IN*>(pAddress->Address.lpSockaddr);
vIPAddress.push_back(inet_ntoa(Ipv4->sin_addr));
//char v4Buf[16] = { 0 };
//InetNtop(AF_INET, &(Ipv4->sin_addr), v4Buf, sizeof(v4Buf));
//vIPAddress.push_back(string(v4Buf));
}
else if(AF_INET6 == family)
{
// IPv6
SOCKADDR_IN6* Ipv6 = reinterpret_cast<SOCKADDR_IN6*>(pAddress->Address.lpSockaddr);
char v6Buf[64] = { 0 };
DWORD nAddrSize = sizeof(sockaddr_storage);
WSAAddressToString((LPSOCKADDR)Ipv6, nAddrSize, NULL, v6Buf, &nAddrSize);
//WCHAR v6Buf[64] = { 0 };
//InetNtop(AF_INET6, &(Ipv6->sin6_addr), v6Buf, sizeof(v6Buf));
vIPAddress.push_back(string(v6Buf));
}
}
}
free(pAdapterAddress);
#else
/* also https://linux.die.net/man/3/getnameinfo
*/
addrinfo hints, *result, *next;
memset(&hints, 0, sizeof(hints));
hints.ai_family = nFamily;//PF_UNSPEC (IPv4 r IPv6)
hints.ai_flags |= AI_CANONNAME;
hints.ai_socktype = SOCK_STREAM;//SOCK_DGRAM
char szHostName[256] = { 0 };
unsigned long length = sizeof(szHostName);
TheHostName(szHostName, length);
if(getaddrinfo(szHostName, NULL, &hints, &result) != 0)
return -1;
char szAddress[128] = { 0 };
for(next = result; next != NULL; next = next->ai_next)
{
void *addr;
switch(next->ai_family)
{
case AF_INET:
addr = &(((sockaddr_in*)next->ai_addr)->sin_addr);
break;
case AF_INET6:
addr = &(((sockaddr_in6*)next->ai_addr)->sin6_addr);
break;
}
//convert ip address to human-readable form
inet_ntop(next->ai_family, addr, szAddress, sizeof(szAddress));
vIPAddress.push_back(string(szAddress));
}
freeaddrinfo(result);
return vIPAddress.size();
#endif
return 0;
}
/*------ PC End ------*/
#ifdef WIN32
#else
#endif