远程监控主机CPU、内存使用率

来源:互联网 发布:淘宝是cs还是bs 编辑:程序博客网 时间:2024/06/08 17:15

小弟不才,毕业设计做了这个题目,导师要我用Winpcap做,结果后来自己用Winsock就实现了。 将代码置于此,以待后人用。功能很简单,但是实现了如题的功能。

客户端

#include<stdio.h>                            //包含头文件
#include<winsock.h>                         
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

//与服务器端连接的功能函数
void StreamClient(char *szServer,short nPort,char buffer[]);

//定义一个宏来帮助显示错误信息

#define PRINTERROR(s)/
     fprintf(stderr,"/n%s:%d/n",s,WSAGetLastError())

////////////////////////////////////////以下是获得内存信息///////////////////////////////

MEMORYSTATUS memstatus;//定义全局变量:内存信息
int GetMemoryStatus()
{
 memstatus.dwLength=sizeof(memstatus);//初始化
    GlobalMemoryStatus(&memstatus);//获取内存信息
    return memstatus.dwMemoryLoad;
}
///////////////////////////////////////////////////////////////////////////////////////////////

 

//定义一个宏来帮助显示错误信息

#define PRINTERROR(s)/
     fprintf(stderr,"/n%s:%d/n",s,WSAGetLastError())

 

/////////////////////////////////////////////以下为获得CPU使用率///////////////////////////////

#define SystemBasicInformation 0
#define SystemPerformanceInformation 2
#define SystemTimeInformation 3

#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))

typedef struct
{
DWORD dwUnknown1;
ULONG uKeMaximumIncrement;
ULONG uPageSize;
ULONG uMmNumberOfPhysicalPages;
ULONG uMmLowestPhysicalPage;
ULONG uMmHighestPhysicalPage;
ULONG uAllocationGranularity;
PVOID pLowestUserAddress;
PVOID pMmHighestUserAddress;
ULONG uKeActiveProcessors;
BYTE bKeNumberProcessors;
BYTE bUnknown2;
WORD wUnknown3;
} SYSTEM_BASIC_INFORMATION;

typedef struct
{
LARGE_INTEGER liIdleTime;
DWORD dwSpare[76];
} SYSTEM_PERFORMANCE_INFORMATION;

typedef struct
{
LARGE_INTEGER liKeBootTime;
LARGE_INTEGER liKeSystemTime;
LARGE_INTEGER liExpTimeZoneBias;
ULONG uCurrentTimeZoneId;
DWORD dwReserved;
} SYSTEM_TIME_INFORMATION;


// ntdll!NtQuerySystemInformation (NT specific!)
//
// The function copies the system information of the
// specified type into a buffer
//
// NTSYSAPI
// NTSTATUS
// NTAPI
// NtQuerySystemInformation(
// IN UINT SystemInformationClass, // information type
// OUT PVOID SystemInformation, // pointer to buffer
// IN ULONG SystemInformationLength, // buffer size in bytes
// OUT PULONG ReturnLength OPTIONAL // pointer to a 32-bit
// // variable that receives
// // the number of bytes
// // written to the buffer
// );
typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);

PROCNTQSI NtQuerySystemInformation;

SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
SYSTEM_TIME_INFORMATION SysTimeInfo;
SYSTEM_BASIC_INFORMATION SysBaseInfo;
double dbIdleTime;
double dbSystemTime;
LONG status;
LARGE_INTEGER liOldIdleTime = {0,0};
LARGE_INTEGER liOldSystemTime = {0,0};

int GetCPUUsage()
{
int CPUUsage = 0;
NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(
GetModuleHandle("ntdll"),
"NtQuerySystemInformation"
);

if (!NtQuerySystemInformation)
return -1;

// get number of processors in the system
status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL);
if (status != NO_ERROR)
return -1;

// get new system time
status = NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0);
if (status!=NO_ERROR)
return -1;

// get new CPU's idle time
status = NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL);
if (status != NO_ERROR)
return -1;

// if it's a first call - skip it
if (liOldIdleTime.QuadPart != 0)
{
// CurrentValue = NewValue - OldValue
dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);

// CurrentCpuIdle = IdleTime / SystemTime
dbIdleTime = dbIdleTime / dbSystemTime;

// CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors + 0.5;

CPUUsage=(UINT)dbIdleTime;
}

// store new CPU's idle and system time
liOldIdleTime = SysPerfInfo.liIdleTime;
liOldSystemTime = SysTimeInfo.liKeSystemTime;

return CPUUsage;
}

////////////////////////////////////////////获得主机IP地址函数段//////////////////////////

char  *psz;
char *GetHostIP()
{
 struct hostent * pHost; 
 char HostName[128];
 if(gethostname(HostName,128)==0)
 {
     pHost = gethostbyname(HostName);  
     psz=inet_ntoa (*(struct in_addr *)pHost->h_addr_list[0]);
     return psz;
 }
 else exit(0);
}

////////////////////////////////////获取系统时间////////////////////////////

struct tm *date_time;
time_t timer;

char *gettime()
{
 time(&timer);
 date_time=localtime(&timer);
 char *time;
 time=asctime(date_time);
 return time;
}

 


///////////////////////////////////////主函数////////////////////////////////////////

 

void main (int argc,char **argv)
{
 WORD wVersionRequested=MAKEWORD(1,1);//定义需要的WSA版本号为1.1
 WSADATA wsaData;//WSADATA结构体用来放置Windows Sockets最初的信息
  int nRet;//定义整形变量
  short nPort;//定义short int变量

  //
  //对运行.EXE后输入的命令格式正确与否进行检查
  //
  if(argc !=3)
  {
   fprintf(stderr,"/nSyntax:client ServerName PortNumber/n");
   return;
  }
  //////////////////////////////////////////////////

  nPort=atoi(argv[2]);//将字符型转化为整数型

  //
  //初始化WinSock并且检查版本
        //
  nRet =WSAStartup(wVersionRequested,&wsaData);//初始化WinSock
  if(wsaData.wVersion!=wVersionRequested)//检查版本是否符合要求
  {
   fprintf(stderr,"/n Wrong version/n");
   return;
  }

  //
  //运行客户端程序
  //
  printf("/nStream Client connecting to server:%s on port:%d/n",argv[1],nPort);//显示连接信息

        char *IP;//获取本地IP地址
  IP=GetHostIP();

  while(1)
  {
             //
             //处理要发送的数据
             //

             char buffer[256];//定义大小为256个字符的数组,用于传送数据流
             char temp0[4];//定义大小为4个字符的数组,用于存放临时数据流
             char temp1[4];//定义大小为4个字符的数组,用于存放临时数据流
            
             int i_length[2];
             char s_length[2][2];

             memset(buffer,0,sizeof(buffer));//清空数据缓冲区
             memset(temp0,0,sizeof(temp0));
             memset(temp1,0,sizeof(temp1));

             int dwMemoryLoad=GetMemoryStatus();//获取内存信息
             _itoa(dwMemoryLoad,temp0,10);//将数据存入temp1
             i_length[0]=strlen(temp0);
             _itoa(i_length[0],s_length[0],10);
             strcat(buffer,s_length[0]);//将内存数据大小信息存入buffer


             int CPUUsage=GetCPUUsage();//获取CPU信息
             _itoa(CPUUsage,temp1,10);//将数据存入temp2
             i_length[1]=strlen(temp1);
             _itoa(i_length[1],s_length[1],10);
             strcat(buffer,s_length[1]);//将CPU数据大小信息存入buffer

    char *time;//获取系统时间
    time=gettime();

             strcat(buffer,temp0);//将内存信息放入buffer中
             strcat(buffer,temp1);//将CPU信息都放入buffer中
    strcat(buffer,time);//将时间信息都放入buffer中
             strcat(buffer,IP);//将IP信息都放入buffer中

    //发送数据
             StreamClient(argv[1],nPort,buffer);
    //等待2秒后再执行
             Sleep(2000);
  }

  //
  //释放WinSock
  //
  WSACleanup();
}

//////////////////////////////////////////////////////////////////////////////////////


void StreamClient(char *szServer,short nPort,char buffer[])
{
 //
 //查找服务器
 //
 LPHOSTENT lpHostEntry;//定义指向hostent型的指针

 lpHostEntry=gethostbyname (szServer);//通过主机名获取主机信息
 if (lpHostEntry==NULL)//检查gethostbyname过程是否正常
 {
  PRINTERROR("gethostbyname()");//显示出错信息
  return;//退出函数
 }

 //
 //建立一个TCP/IP流式socket
 //
 SOCKET theSocket;

theSocket=socket(AF_INET,        //地址族
     SOCK_STREAM,    //Socket类型
     IPPROTO_TCP);//协议类型
if (theSocket==INVALID_SOCKET)//检查socket建立过程是否正常
{
 PRINTERROR("socket()");//显示出错信息
 return;//退出函数
}
//
//填写地址结构体中的内容
//
SOCKADDR_IN saServer;//定义INTERNET地址变量
saServer.sin_family=AF_INET;//地址族为INTERNET
saServer.sin_addr=*((LPIN_ADDR)*lpHostEntry->h_addr_list);
       //服务器地址
saServer.sin_port=htons(nPort);//从输入命令行里获取的端口号
//
//连接服务器
//
int nRet;//定义一整型变量

nRet=connect(theSocket,                 //Socket
    (LPSOCKADDR)&saServer,     //Server地址
    sizeof(struct sockaddr));  //服务器地址结构体的大小
if(nRet==SOCKET_ERROR)//检查connect过程建立是否正常
{
 PRINTERROR("socket()");
 closesocket(theSocket);
 return;
}

//
//向服务器发送信息
//

nRet=send (theSocket,//连接用socket
     buffer,//数据缓冲区
     strlen(buffer),//数据大小
     0);//标志位
if (nRet==SOCKET_ERROR)//检查send过程建立是否正常
{
 PRINTERROR("send()");
 closesocket(theSocket);
 return;
}

closesocket(theSocket);//关闭Socket

}


服务器端:

#include <stdio.h>               //包含头文件
#include <winsock.h>             //包含头文件

//服务器端接受数据功能函数

void StreamServer(short nPort);

//定义宏来帮助错误信息的显示

#define PRINTERROR(s)  fprintf(stderr,"/n%:%d/n",s,WSAGetLastError())

//定义字符串用于存储客户端状态信息

char *memory;
char *CPUStatus;
char *IP;
char *date_time;

/////////////////////////////////////////////////////////////////////

void main(int argc,char **argv)  //主函数
{
 WORD wVersionRequested=MAKEWORD(1,1);//定义需要的WSA版本号为1.1
 WSADATA wsaData;//WSADATA结构体用来放置Windows Sockets最初的信息
 int nRet;  //定义整形变量
 short nPort;//定义short int变量

 //
 //对运行.EXE后输入的命令格式正确与否进行检查
 //
 if(argc!=2)
 {
  fprintf(stderr,"/nSyntax:server PortNumber/n");
  return;
 }

 nPort=atoi(argv[1]);//将字符型转化为整数型

 //
 //初始化WinSock并且检查版本
 //
 nRet=WSAStartup(wVersionRequested,&wsaData);//启动并初始化WinSock
 if(wsaData.wVersion!=wVersionRequested)//检查版本
 {
  fprintf(stderr,"/n Wrong version/n");
  return;
 }

 //
 //运行服务器程序
 //

 StreamServer(nPort);

 //
 //释放WinSock
 //
 WSACleanup();
}

/////////////////////////////////字符串处理函数/////////////////////////////////////

char *catch_stringCPU(int i,int j,char buffer[]);

char *catch_stringDAT(int i,int j,char buffer[]);

char *catch_stringMEM(int i,int j,char buffer[]);

char *catch_stringIP(int i,int j,char buffer[]);

//////////////////////////////////服务器程序///////////////////////////////

void StreamServer(short nPort) 
{
 //
 //建立一个TCP/IP stream socket并处于监听状态
 //

 SOCKET listenSocket;//建立一个监听的socket
 listenSocket=socket(AF_INET,     //定义地址族INTERNET
                  SOCK_STREAM,  //Socker类型
      IPPROTO_TCP); //定义协议
 if(listenSocket==INVALID_SOCKET)//检查listenSocket建立是否正常
 {
  PRINTERROR("socket()");
  return;
 }

 //
 //填写地址结构体中的内容
 //
 SOCKADDR_IN saServer;//定义INTERNET地址变量
 saServer.sin_family=AF_INET;//地址族为INTERNET
 saServer.sin_addr.s_addr=INADDR_ANY;//让WinSock自动提供本地地址
 saServer.sin_port=htons(nPort);    //定义端口号
//
//将上面建立的SOCKET与本地绑定
//
    int nRet;
 nRet=bind(listenSocket,  //socket
    (LPSOCKADDR)&saServer,  //本地地址
    sizeof(struct sockaddr)); // 地址结构体的大小
 if(nRet==SOCKET_ERROR)//检查bind是否正常
 {
  PRINTERROR("bind()");//显示错误信息
  closesocket(listenSocket);//关闭开始建立的listenSocket
  return;                   //退出函数
 }

 int nLen;//定义一整型变量
 nLen=sizeof(SOCKADDR);//求出结构体SOCKADDR的大小
 char buffer[256];//定义大小为256个字符的数组
   
 nRet=gethostname(buffer,sizeof(buffer));//获取主机名
  if(nRet==SOCKET_ERROR)//检查gethostname是否正常
    {
     PRINTERROR("gethostname()");//显示出错信息
     closesocket(listenSocket);//关闭listenSocket
     return;//退出程序
    }
 //
    //显示server的名称和使用的端口号
 //

 printf("/nServer named %s waiting on port %d/n",buffer,nPort);
 //
 //使端口处于监听状态
 //
 
 printf("/nlisten()/n");
 printf("      IP                CPU     MEMORY            DATE_TIME/n");

 nRet=listen(listenSocket,       //绑定的socket
     SOMAXCONN);    //请求连接的队列大小
 if(nRet==SOCKET_ERROR)//检查listen建立是否正常
 {
  PRINTERROR("listen()");//显示出错信息
  closesocket(listenSocket);//关闭listen
  return;//退出函数
 }
 //
 //等待进入的连接请求
 //
do
 {
 SOCKET remoteSocket;//建立一个用于处理连接的socket
 remoteSocket=accept(listenSocket,    //监听socket
                          NULL,             //任意的client地址
           NULL);
    if(remoteSocket==INVALID_SOCKET)//检查accept过程是否正常
 {PRINTERROR("accept()");//显示出错信息
  closesocket(listenSocket);//关闭listenSocket
  return;//退出函数
 }

//我们连接到了一个客户端
//新的套接字 已经返回
//获得客户端地址

//
//从客户端接收数据
//
     memset(buffer,0,sizeof(buffer));                       //接受数据的缓冲区清空
     nRet=recv(remoteSocket,                              //客户端连接
        buffer,                                     //接收缓存
         sizeof(buffer),                             //定义缓存长度
         0);                                        //标志值
     if(nRet==INVALID_SOCKET)//检查recv过程是否正常
 {
       PRINTERROR("recv()");//显示出错信息
      return;//退出循环
 }
     if (!buffer)                                        //判断是否结束该对话
 {
      printf("ending connecting.");//显示信息
      return;//退出循环
 }
////////////////////////////////
 char buffer0=buffer[0];
 char buffer1=buffer[1];
 int i,j;
 i=(int)buffer[0]-48;
 j=(int)buffer[1]-48;

 memory=catch_stringMEM(2,(1+i),buffer);
 CPUStatus=catch_stringCPU((2+i),(1+i+j),buffer);
 date_time=catch_stringDAT((2+i+j),(26+i+j),buffer);
 IP=catch_stringIP((27+i+j),(27+i+j+15),buffer);
 
 
 
//
//显示收到的数据
//


    printf("%-16s         /b/b/b%3s%%         /b/b/b%3s%%         %s/n",IP,CPUStatus,memory,date_time);//显示得到收到的数据

//
//在退出前关闭套接字
//
    closesocket(remoteSocket);
 }while(1);


closesocket(listenSocket);                        //在退出前关闭套接字
 
 

}


/////////////////////////////////////////////////////////////////////////////////

char TEMP0[64];
char TEMP1[64];
char TEMP2[64];
char TEMP3[64];


char *catch_stringCPU(int i,int j,char buffer[])
{
 
 memset(TEMP1,0,sizeof(TEMP1));
 int k=0;
 for(k,i;i<=j;i++,k++)
 {
  TEMP1[k]=buffer[i];
 }
 return TEMP1;
}


char *catch_stringDAT(int i,int j,char buffer[])
{
 
 memset(TEMP2,0,sizeof(TEMP2));
 int k=0;
 for(k,i;i<=j;i++,k++)
 {
  TEMP2[k]=buffer[i];
 }
 return TEMP2;
}


char *catch_stringMEM(int i,int j,char buffer[])
{
 
 memset(TEMP3,0,sizeof(TEMP3));
 int k=0;
 for(k,i;i<=j;i++,k++)
 {
  TEMP3[k]=buffer[i];
 }
 return TEMP3;
}


char *catch_stringIP(int i,int j,char buffer[])
{
 
 memset(TEMP0,0,sizeof(TEMP0));
 int k=0;
 for(k,i;i<=j;i++,k++)
 {
  TEMP0[k]=buffer[i];
 }
 return TEMP0;
}

 

注意:需要在工程中加入wsock32.lib

具体怎么加在百度一搜就知道拉。要是实在不会就留言给我啊。

原创粉丝点击