如何使用C# / VB.Net编程测量网站带宽(上传+下载)以MB为单位?

10
希望大家都身体健康。
我正在使用C#/VB.Net编写一个Windows服务,旨在测量本地主机上所有网站的带宽消耗,并将其统计数据存储到本地/远程数据库中,包括上传、下载等等。
目标平台仅涵盖Windows Server 2003、2003 R2、2008和2008 R2。
我对此进行了一些搜索,发现了以下内容:
  1. 使用在Windows 2003中找到的SNMP mgmtapi.dll
  2. 使用自定义网络驱动程序来收集统计信息。
请指导最合适的、最安全、有效的方法/技术或一组这样的技术,用于测量每个不同网站的带宽消耗。
请在此方面分享任何代码
谢谢
Steve
1个回答

11

我发现了一个名为snmpsharpnet的程序集,它非常有助于在.NET上使用SNMP。

根据我在这篇文章中所述,给定接口的输入带宽使用率可以通过以下方式计算:

"In"带宽使用率% = (((ifInOctets(t2)-ifInOctets(t1))* 8)* 100)/(ifSpeed *(t2-t1))

以下是示例代码。

using System;
using System.Collections.Generic;
using System.Text;

using SnmpSharpNet;

namespace Exemple2
{
  class Program
  {
    static void Main(string[] args)
    {
      /* Get an SNMP Object
       */
      SimpleSnmp snmpVerb = new SimpleSnmp("192.168.1.121", 161, "public");
      if (!snmpVerb.Valid)
      {
        Console.WriteLine("Seems that IP or comunauty is not cool");
        return;
      }


      /* Sample of simple Get usage on ifSpeed on interface 10
       * TODO : for sure you have to detect the right interface
       */
      Oid oidifSpeed = new Oid(".1.3.6.1.2.1.2.2.1.5.10");

      /* Getting ifSpeed
       */
      Dictionary<Oid, AsnType> snmpDataS = snmpVerb.Get(SnmpVersion.Ver2, new string[] { oidifSpeed.ToString() });
      if (snmpDataS != null)
        Console.WriteLine("Interface speed \"{0}\" : {1}", oidifSpeed.ToString(), snmpDataS[oidifSpeed].ToString());
      else
        Console.WriteLine("Not Glop!");

      /* Sample of simple Get usage on ifInOctets on interface 10
       * TODO : for sure you have to detect the right interface
       */
      Oid oidifInOctets = new Oid(".1.3.6.1.2.1.2.2.1.10.10");
      Dictionary<Oid, AsnType> snmpData1;

      /* Getting it for the first time
       */
      snmpData1 = snmpVerb.Get(SnmpVersion.Ver2, new string[] { oidifInOctets.ToString() });
      if (snmpData1 != null)
        Console.WriteLine("Number of In octets \"{0}\" : {1}", oidifInOctets.ToString(), snmpData1[oidifInOctets].ToString());
      else
        Console.WriteLine("Not Glop!");

      int missed = 0;
      while (true)
      {
        if (missed == 0)
        {
          /* When you detect a non refesh data, keep the last one
           */
          snmpData1 = snmpVerb.Get(SnmpVersion.Ver2, new string[] { oidifInOctets.ToString() });
          if (snmpData1 != null)
            Console.WriteLine("Number of In octets \"{0}\" : {1}", oidifInOctets.ToString(), snmpData1[oidifInOctets].ToString());
          else
            Console.WriteLine("Not Glop!");
        }

        /* Some Wait (less aproximative)
         */
        int duration = 5;
        System.Threading.Thread.Sleep(duration*1000); // duration seconds

        /* Getting it for the Second time
         */
        Dictionary<Oid, AsnType> snmpData2 = snmpVerb.Get(SnmpVersion.Ver2, new string[] { oidifInOctets.ToString() });
        if (snmpData2 != null)
          Console.WriteLine("Number of In octets \"{0}\" : {1}", oidifInOctets.ToString(), snmpData2[oidifInOctets].ToString());
        else
          Console.WriteLine("Not Glop!");

        Counter32 I1 = new Counter32();
        I1.Set(snmpData1[oidifInOctets]);
        Counter32 I2 = new Counter32();
        I2.Set(snmpData2[oidifInOctets]);
        Counter32 speed = new Counter32();
        speed.Set(snmpDataS[oidifSpeed]);

        if (I2.Value == I1.Value)
        {
          missed += 1;
          continue;
        }
        decimal bandWithUsage = (((decimal)(I2.Value - I1.Value) * 8) * 100) / (speed * duration * (1+missed));
        Console.WriteLine("BandWith usage : {0}%", bandWithUsage);
        missed = 0;
      }
    }
  }
}

这只是一个概念验证,现在你可能需要加入BackgroundWorker和timer。


如果您不确定服务器上是否可连接SNMP,并且想要测试SNMP端口连接,则需要使用Microsoft的PortQry。该工具可以确定端口是否正在侦听。根据使用的命令,此工具还提供其他功能。


2
几个月前我用Perl做了同样的事情,它非常有效,但是睡眠时间需要更长,否则你总会得到零值。如果你想要更精确的值,可以选择WMI或者更好的NFDump。由于你正在处理Windows Server客户端,我肯定会选择WMI。 - raz3r
@RogerEdward,这个问题9年前还能用,那时候是我在SO上的第一个回答;o)。现在网站没有响应了,我编辑了我的答案并放置了gitHub链接,你可以使用the Nuget package - JPBlanc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接