随笔-82  评论-278  文章-1  trackbacks-19

在C#中调用API获取网络信息和流量

最近一项目中要求显示网络流量,而且必须使用C#。

事实上,调用 IpHlpApi.dll 的 GetIfTable API 可以轻易获得网络信息和网络流量。只是要在C#中实现还是比较复杂。

先看看怎么定义该 API

[DllImport("IpHlpApi.dll")]
        
extern static public uint GetIfTable(byte[] pIfTable, ref uint pdwSize, bool bOrder);

本来想把 pIfTable 定义为 IntPtr,但是这样的结果是,获取的信息是错误的(直到现在都不知是什么原因)。

但显然定义为 byte[] 是不能直接使用的。幸好在 Google Code Search 找到了三个类:

CustomtMarshaler.cs

MIB_IFROW.cs

MIB_IFTABLE.cs

再定义一个 NetInfo 类,存储网络信息

NetInfo.cs

OK,现在可以获取网络信息了

        /// <summary>
        
/// Get IFTable
        
/// </summary>
        
/// <returns>MIB_IFTABLE Class</returns>

        private static MIB_IFTABLE GetAllIfTable()
        
{
            
//缓冲区大小
            uint dwSize = 0;

            
//获取缓冲区大小
            uint ret = GetIfTable(nullref dwSize, false);
            
if (ret == 50)
            
{
                
//此函数仅支持于 win98/nt 系统
                return null;
            }


            
//定义,获取 MIB_IFTABLE 对象
            MIB_IFTABLE tbl = new MIB_IFTABLE((int)dwSize);
            ret 
= GetIfTable(tbl.ByteArray, ref dwSize, false);

            
//如果不成功
            if (ret != 0)
            
{
                
return null;
            }


            
return tbl;
        }


        
/// <summary>
        
/// Get NetInfo Class
        
/// </summary>
        
/// <param name="row">MIB_IFROW Class</param>
        
/// <returns>NetInfo Class</returns>

        private static NetInfo GetNetInfo(MIB_IFROW row)
        
{
            NetInfo ninfo 
= new NetInfo();
            ninfo.Index 
= row.dwIndex;
            ninfo.Name 
= Encoding.ASCII.GetString(row.bDescr, 0, (int)row.dwDescrLen);
            ninfo.PhysAddr 
= GetPhysAddr(row.bPhysAddr, (int)row.dwPhysAddrLen);
            ninfo.Type 
= (NetType)row.dwType;
            ninfo.Status 
= (NetState)row.dwOperStatus;
            ninfo.Speed 
= row.dwSpeed;
            ninfo.InErrors 
= row.dwInErrors;
            ninfo.InOctets 
= row.dwInOctets;
            ninfo.InUnknownProtos 
= row.dwInUnknownProtos;
            ninfo.OutErrors 
= row.dwOutErrors;
            ninfo.OutOctets 
= row.dwOutOctets;
            
return ninfo;
        }

/// <summary>
        
/// 获取所有的网络信息
        
/// </summary>
        
/// <returns>NetInfo 网络信息范型</returns>

        public static List<NetInfo> GetAllNetInfo()
        
{
            
//定义范型
            List<NetInfo> ninfos = new List<NetInfo>();

            
//定义,获取 MIB_IFTABLE 对象
            MIB_IFTABLE tbl = GetAllIfTable();

            
//如果成功
            if (tbl != null)
            
{
                tbl.Deserialize();
                
for (int i = 0; i < tbl.Table.Length; i++)
                
{
                    ninfos.Add(GetNetInfo(tbl.Table[i]));
                }

            }


            
return ninfos;
        }

PS:事实上,我把获取网络、CPU、内存、磁盘、进程信息等功能封装起来,并做了一个比较完善的 Windows 任务管理器,整理完后发布源码。
 
0
0
(请您对文章做出评价)
« 上一篇:上一秒分手,下一秒就想念
» 下一篇:科学宿命论-我们到底有没有自由意志
posted on 2007-03-29 16:43 柠檬的 阅读(3218) 评论(7)  编辑 收藏 网摘 所属分类: 技术

评论:
#1楼 2007-03-29 17:56 | 周王文(Roan)[未注册用户]
虽然可以说,你的共享精神不错.可是,对于一个读者,直接读你这个共享源代码,未必能完全明白,特别是不会C#的读者.如果你读完了,明白其中原理及其算法了,何不发表出来呢?对我来说,我不想读,因为我现在不是使用C#,我只想知道其原理及相关的算法,时间可贵着呢!!!
  回复  引用    
#2楼 2007-04-29 20:27 | 小舞[未注册用户]
路过的,我也来自湖南
  回复  引用    
#3楼 2007-07-24 15:32 | Helper[未注册用户]
能得到思路就不错了,楼上的不要期望太高!
  回复  引用    
#4楼 2007-09-18 18:05 | sandheart[未注册用户]
怎么显示:

错误 当前上下文中不存在名称“GetPhysAddr”

  回复  引用    
#5楼 2008-10-18 06:08 | yhb[未注册用户]
pcCpuLoad = new PerformanceCounter("Processor","%Processor Time","_Total"); >>输入字符串的格式不正确。
  回复  引用    
#6楼 2008-12-10 23:32 | kukuQ[未注册用户]
个人分析出现字符串的格式不正确是操作系统的bug所致,需要重新配置系统所有性能计数器,执行如下命令也许可以解决:
lodctr /R

  回复  引用