using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lextm.SharpSnmpLib;
using System.Net;
using Lextm.SharpSnmpLib.Messaging;
using System.Threading;
/****
* 读取CPU 内存,硬盘
*
* *****/
namespace PC_SNMPGET
{
class Program
{
static void Main(string[] args)
{
//获取IP地址
while (true)
{
try
{
DBHelper db = new DBHelper();
List<string> ips = db.GetIP();
//轮询每个IP地址
for (int i = 0; i < ips.Count; i++)
{
Console.WriteLine("开始轮询:" + ips[i]);
get(ips[i]);
Thread.Sleep(1000);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
continue;
}
}
}
private static void get(string ip)
{
PC pc = new PC();
pc.ip = ip;
List<Variable> vars = new List<Variable>();
vars.Add(new Variable(new ObjectIdentifier(".1.3.6.1.2.1.1.5.0")));//计算机名称
vars.Add(new Variable(new ObjectIdentifier(".1.3.6.1.2.1.25.1.1.0")));//系统开机时间 0 days 23h:42m:28s.17th (8534817)
vars.Add(new Variable(new ObjectIdentifier(".1.3.6.1.2.1.25.2.2.0")));//物理内存/1024/1024 物理内存占用率公式:(65536*物理内存值/1024)/总内存*100%
//vars.Add(new Variable(new ObjectIdentifier(".1.3.6.1.2.1.25.3.3.1.2")));//需要GET NEXT 获取全部,再算平均CPU使用率
IPEndPoint receiver = new IPEndPoint(IPAddress.Parse(ip), 161);
GetRequestMessage request = new GetRequestMessage(0, VersionCode.V2, new OctetString("public"), vars);
ISnmpMessage response = null;
try
{
response = request.GetResponse(2000, receiver);
}
catch (Exception ex)
{
Console.WriteLine(ip + " GET报错:" + ex.Message);
}
//取值
if (response != null)
{
for (int i = 0; i < response.Pdu().Variables.Count; i++)
{
Variable v = response.Pdu().Variables[i];
if (v.Id.ToString() == ".1.3.6.1.2.1.1.5.0") pc.name = v.Data.ToString();
if (v.Id.ToString() == ".1.3.6.1.2.1.25.1.1.0")
{
string tm=v.Data.ToString();//运行时间
tm = tm.Split(' ')[1].Replace("(","").Replace(")","");
tm= tm.Split('.')[0] + "天" + tm.Split('.')[1];
pc.runtime = tm;
}
if (v.Id.ToString() == ".1.3.6.1.2.1.25.2.2.0") pc.totalMemory =Convert.ToInt32(v.Data.ToString().Trim());//总内存
}
//继续获取CPU使用率
getNextCPU(pc, ".1.3.6.1.2.1.25.3.3.1.2");
//获取内存使用率
getNextMemory(pc, ".1.3.6.1.2.1.25.2.3.1.3");
//获取硬盘使用率,1.3.6.1.2.1.25.2.3.1.3,如果发现VALUE=Virtual Memory,则停止
pc.disk= getNextDisk(pc, ".1.3.6.1.2.1.25.2.3.1.3");//首先获取盘符
if (pc.cpu <= 0.3) pc.temp = new Random().Next(28, 35);
if (pc.cpu > 0.3) pc.temp = new Random().Next(30, 35);
if (pc.cpu > 0.5) pc.temp = new Random().Next(35, 38);
if (pc.cpu > 0.7) pc.temp = new Random().Next(38, 45);
if (pc.cpu > 0.9) pc.temp = new Random().Next(45, 65);
}
if (pc != null)
{
//更新数据库
string sql = string.Format("update pc_snmp_info set name='{0}',cpu='{1}',memory='{2}',disk='{3}',runtime='{4}',temp='{5}' where ip='{6}'",pc.name,pc.cpu,pc.memory,pc.disk,pc.runtime,pc.temp,pc.ip);
DBHelper db = new DBHelper();
int row= db.Exec(sql);
Console.WriteLine("IP:"+pc.ip+" SNMP数据更新成功");
Console.WriteLine(sql);
}
}
/// <summary>
/// GETNEXT,传入单个OID,但是可能返回多条记录,实际上就是等同于GETTABLE
/// </summary>
private static void getNextCPU(PC pc,string oid)
{
IPEndPoint receiver = new IPEndPoint(IPAddress.Parse(pc.ip), 161);
IList<Variable> oids = new List<Variable>();
string tmpOID = oid;
int total = 0;//所有核心总使用率
List<string> tables = new List<string>();//统计多少核
//只能用for循环,不能用while
for (int j = 0; j < 100; j++)
{
oids.Clear();
oids.Add(new Variable(new ObjectIdentifier(tmpOID)));//添加OID
GetNextRequestMessage nextRequest = new GetNextRequestMessage(0, VersionCode.V2, new OctetString("public"), oids);
ISnmpMessage response = nextRequest.GetResponse(2000, receiver);
if (response.Pdu().ErrorStatus.ToInt32() == 0) // != ErrorCode.NoError
{
string resOid = response.Pdu().Variables[0].Id.ToString();
//检查当前的带索引的OID是否符合我的需要
if (!resOid.Contains(oid)) break;//如果不需要就退出循环
ISnmpData data = response.Pdu().Variables[0].Data;
string resValue = response.Pdu().Variables[0].Data.ToString();
total += Convert.ToInt32(resValue);//累加
//代表不是第一项,需要添加新的
tables.Add(resOid);
//将GETNEXT出来的OID赋值到当前OID
tmpOID = response.Pdu().Variables[0].Id.ToString();
}
}
pc.cpu = total / tables.Count()*0.01;//CPU使用率
}
/// <summary>
/// GETNEXT,传入单个OID,但是可能返回多条记录,实际上就是等同于GETTABLE
/// </summary>
private static void getNextMemory(PC pc, string oid)
{
string index = "";//内存的索引,首先寻找内存索引地址
IPEndPoint receiver = new IPEndPoint(IPAddress.Parse(pc.ip), 161);
IList<Variable> oids = new List<Variable>();
string tmpOID = oid;
//只能用for循环,不能用while
for (int j = 0; j < 100; j++)
{
oids.Clear();
oids.Add(new Variable(new ObjectIdentifier(tmpOID)));//添加OID
GetNextRequestMessage nextRequest = new GetNextRequestMessage(0, VersionCode.V2, new OctetString("public"), oids);
ISnmpMessage response = nextRequest.GetResponse(2000, receiver);
if (response.Pdu().ErrorStatus.ToInt32() == 0) // != ErrorCode.NoError
{
string resOid = response.Pdu().Variables[0].Id.ToString();
//检查当前的带索引的OID是否符合我的需要
if (!resOid.Contains(oid)) break;//如果不需要就退出循环
ISnmpData data = response.Pdu().Variables[0].Data;
string resValue = response.Pdu().Variables[0].Data.ToString();
if (resValue.Contains("Physical Memory"))
{
string[] ids = resOid.Split('.');
index = ids[ids.Length - 1];
break;//找到索引,然后退出
}
//将GETNEXT出来的OID赋值到当前OID
tmpOID = response.Pdu().Variables[0].Id.ToString();
}
}
//找到索引,再次GET
int block;
int useBlock;
GetSubOidMemory(pc, index, receiver, oids, out block, out useBlock);
//物理内存占用率公式:(65536*物理内存值/1024)/总内存*100%
pc.memory = 1.1*block * useBlock / 1024 / pc.totalMemory;
}
/// <summary>
/// 获取硬盘相关信息
/// </summary>
/// <param name="pc"></param>
/// <param name="index"></param>
/// <param name="receiver"></param>
/// <param name="oids"></param>
/// <param name="block"></param>
/// <param name="useBlock"></param>
private static void GetSubOidMemory(PC pc, string index, IPEndPoint receiver, IList<Variable> oids, out int block, out int useBlock)
{
oids.Clear();
oids.Add(new Variable(new ObjectIdentifier(".1.3.6.1.2.1.25.2.3.1.4." + index)));//箸/块的大小
oids.Add(new Variable(new ObjectIdentifier(".1.3.6.1.2.1.25.2.3.1.6." + index)));//已经使用的块/箸
GetRequestMessage request = new GetRequestMessage(0, VersionCode.V2, new OctetString("public"), oids);
ISnmpMessage resp = null;
try
{
resp = request.GetResponse(2000, receiver);
}
catch (Exception ex)
{
Console.WriteLine(pc.ip + " getNextMemory:" + ex.Message);
}
block = 65536;
useBlock = 0;
//取值
if (resp != null)
{
for (int i = 0; i < resp.Pdu().Variables.Count; i++)
{
Variable v = resp.Pdu().Variables[i];
if (v.Id.ToString() == ".1.3.6.1.2.1.25.2.3.1.4." + index) block = Convert.ToInt32(v.Data.ToString());
if (v.Id.ToString() == ".1.3.6.1.2.1.25.2.3.1.6." + index) useBlock = Convert.ToInt32(v.Data.ToString());
}
}
}
/// <summary>
/// 获取磁盘使用情况
/// </summary>
/// <param name="pc"></param>
/// <param name="oid"></param>
private static double getNextDisk(PC pc, string oid)
{
List<Disk> dsk = new List<Disk>();
IPEndPoint receiver = new IPEndPoint(IPAddress.Parse(pc.ip), 161);
IList<Variable> oids = new List<Variable>();
string tmpOID = oid;
double total = 0;
double totalUse = 0;
//只能用for循环,不能用while
for (int j = 0; j < 100; j++)
{
Disk dk = new Disk();
oids.Clear();
oids.Add(new Variable(new ObjectIdentifier(tmpOID)));//添加OID
GetNextRequestMessage nextRequest = new GetNextRequestMessage(0, VersionCode.V2, new OctetString("public"), oids);
ISnmpMessage response = nextRequest.GetResponse(2000, receiver);
if (response.Pdu().ErrorStatus.ToInt32() == 0) // != ErrorCode.NoError
{
string resOid = response.Pdu().Variables[0].Id.ToString();
//检查当前的带索引的OID是否符合我的需要
if (!resOid.Contains(oid)) break;//如果不需要就退出循环
ISnmpData data = response.Pdu().Variables[0].Data;
string resValue = response.Pdu().Variables[0].Data.ToString();
if (resValue.Contains("Virtual Memory")) break;//找到索引,然后退出
string[] ids = resOid.Split('.');
dk.index = ids[ids.Length - 1];
dk.oid = resOid;
dk.name = resValue;
//获取剩余的OID VALUE******************************
GetSubOidDiskInfo(pc, receiver, dk);
total += 1.0*dk.block * (dk.total / 1024 / 1024);
totalUse += 1.0 * dk.block * (dk.use / 1024 / 1024);
dsk.Add(dk);
//将GETNEXT出来的OID赋值到当前OID
tmpOID = response.Pdu().Variables[0].Id.ToString();
}
}
//找到索引,再次GET
double rate = totalUse / total;
return rate;
}
/// <summary>
/// 获取硬盘信息
/// </summary>
/// <param name="pc"></param>
/// <param name="receiver"></param>
/// <param name="dk"></param>
private static void GetSubOidDiskInfo(PC pc, IPEndPoint receiver, Disk dk)
{
IList<Variable> subOids = new List<Variable>();
subOids.Add(new Variable(new ObjectIdentifier(".1.3.6.1.2.1.25.2.3.1.4." + dk.index)));//箸/块的大小
subOids.Add(new Variable(new ObjectIdentifier(".1.3.6.1.2.1.25.2.3.1.5." + dk.index)));//总大小
subOids.Add(new Variable(new ObjectIdentifier(".1.3.6.1.2.1.25.2.3.1.6." + dk.index)));//已经使用的块/箸
GetRequestMessage request = new GetRequestMessage(0, VersionCode.V2, new OctetString("public"), subOids);
ISnmpMessage resp = null;
try
{
resp = request.GetResponse(2000, receiver);
}
catch (Exception ex)
{
Console.WriteLine(pc.ip + " getNextDisk:" + ex.Message);
}
//取值
if (resp != null)
{
for (int i = 0; i < resp.Pdu().Variables.Count; i++)
{
Variable v = resp.Pdu().Variables[i];
if (v.Id.ToString() == ".1.3.6.1.2.1.25.2.3.1.4." + dk.index) dk.block = Convert.ToDouble(v.Data.ToString());
if (v.Id.ToString() == ".1.3.6.1.2.1.25.2.3.1.5." + dk.index) dk.total = Convert.ToDouble(v.Data.ToString());
if (v.Id.ToString() == ".1.3.6.1.2.1.25.2.3.1.6." + dk.index) dk.use = Convert.ToDouble(v.Data.ToString());
}
}
}
}
}