NET FLOW

 

直接对网卡编程以实现网络数据的拦截与监控是件很复杂的事情。本文介绍使用“IP助手库函数iphlpapi.dll)轻松获取网络流量图的方法,并给出了具体实例程序。

 

实例程序的执行情况见下图所示:

 

 

从图中可以看到,用“IP助手库函数可获取当前所有的网络连接情况,其中包括使用网卡的局域网连接,以及使用ISDN或调制解调器的拨号网络连接。可获取的信息包括:连接速度、界面类型、操作状态、当前总共收到和发送的字节数,等等。

 

其中总共收到和发送的字节数等信息完全是累计的。也就是说,这些信息不受网络连接断开的影响(如拨号网络),能完整记录各网络全天的吞吐总量。

 

定时扫描网络的最新吞吐量,并与上一时段的吞吐量做比较,即可制作网络流量图。上图所示的是拨号网络约六分钟的下载流量图,其中数据每秒刷新一次(X方向),网格单位是KB/每秒(Y方向)。

 

一、“IP助手库函数的使用

 

用微软的“IP助手库函数iphlpapi.dll)可获取大量有关网络连接的有用信息。其中有关吞吐量的函数包括GetIfTable等,其定义为:

 

Private Declare Function GetIfTable Lib "iphlpapi" (ByRef pIfTable As Any, _ByRef pdwSize As Long, ByVal bOrder As Long) As Long

 

该函数的第一个参数指向一个缓冲区,函数执行后该缓冲区内被填入各网络连接的最新数据。缓冲区的结构是:

 

网络连接总数+网络连接1结构数据+网络连接2结构数据+...

 

其中网络连接总数4个字节;每个网络连接数据的结构为:

 

Private Type MIB_IFROW

 

wszName(0 To 511) As Byte

 

dwIndex As Long '编号

 

dwType As Long '界面类型

 

dwMtu As Long '最大传输单元

 

dwSpeed As Long '界面速度

 

dwPhysAddrLen As Long '物理地址部分有效长度

 

bPhysAddr(0 To 7) As Byte '物理地址

 

dwAdminStatus As Long '管理状态

 

dwOperStatus As Long '操作状态

 

dwLastChange As Long '操作状态最近更新时间

 

dwInOctets As Long '总共收到(字节)

 

dwInUcastPkts As Long '总共收到(unicast)

 

dwInNUcastPkts As Long '总共收到(non-unicast)

 

dwInDiscards As Long '丢弃包总数(收到)

 

dwInErrors As Long '出错包总数(收到)

 

dwInUnknownProtos As Long '其它包总数(收到)

 

dwOutOctets As Long '总共发送(字节)

 

dwOutUcastPkts As Long '总共发送(unicast)

 

dwOutNUcastPkts As Long '总共发送(non-unicast)

 

dwOutDiscards As Long '丢弃包总数(发送)

 

dwOutErrors As Long '出错包总数(发送)

 

dwOutQLen As Long '发送队列长度

 

dwDescrLen As Long '界面描述部分有效长度

 

bDescr(0 To 255) As Byte '界面描述

 

End Type

 

需要指出的是,上述GetIfTable函数只能在Windows 98/2000/NT4以及部分Win95上工作。

 

二、实例程序(VB6

 

' “IP助手获取网络流量图

 

Option Explicit

 

Dim IfTable As MIB_IFROW ' 定义一个上述结构的变量

 

Dim buf() As Byte ' 缓冲区

 

Dim buf_size As Long ' 缓冲区实际大小

 

Dim rows As Long ' 当前网络连接总数

 

Dim i, j As Long

 

Dim Pic_X, Pic_Y, Old_In As Long ' 用于在绘制流量图中保存上一时段的有关值

 

'

 

Private Const ERROR_NOT_SUPPORTED = 50&

 

Private Const ERROR_SUCCESS = 0&

 

Private Declare Function GetIfTable Lib "iphlpapi" (ByRef pIfTable As Any, _

 

ByRef pdwSize As Long, ByVal bOrder As Long) As Long

 

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef _

 

pDest As Any, ByRef pSource As Any, ByVal Length As Long)

 

Private Sub Form_Load()

 

i = GetIfTable(ByVal 0&, buf_size, 0)

 

If i = ERROR_NOT_SUPPORTED Then

 

MsgBox "函数GetIfTable只能在Win98/NT4/2000上工作。"

 

End

 

End If

 

ReDim buf(0 To buf_size - 1) As Byte ' 根据返回值,动态申请缓冲区

 

i = GetIfTable(buf(0), buf_size, True) '“True”的含义是排序

 

If i <> ERROR_SUCCESS Then End

 

Timer1.Interval = 1000 ' 刷新间隔定为一秒

 

Timer1.Enabled = True ' 启动记时器

 

Picture1.DrawMode = 13

 

Picture1.AutoRedraw = True ' 启动自动重画功能以防止画面丢失

 

Picture1.ScaleMode = 3 ' 设定画笔单位为象素(Pixel

 

Pic_X = Picture1.ScaleWidth

 

End Sub

 

Private Function GetType(Type1 As Long) As String ' “界面类型定义函数

 

Select Case Type1

 

Case 1: GetType = "Other"

 

Case 6: GetType = "Ethernet"

 

Case 9: GetType = "Tokenring"

 

Case 15: GetType = "FDDI"

 

Case 23: GetType = "PPP"

 

Case 24: GetType = "Loopback"

 

Case 28: GetType = "Slip"

 

End Select

 

End Function

 

Private Function GetState(State1 As Long) As String ' “操作状态定义函数

 

Select Case State1

 

Case 0: GetState = "Not operational"

 

Case 1: GetState = "Operational"

 

Case 2: GetState = "Disconnected"

 

Case 3: GetState = "Connecting"

 

Case 4: GetState = "Connected"

 

Case 5: GetState = "Unreachable"

 

End Select

 

End Function

 

Private Sub Timer1_Timer()

 

ReDim buf(0 To buf_size - 1) As Byte

 

i = GetIfTable(buf(0), buf_size, True)

 

CopyMemory rows, buf(0), 4 ' 缓冲区的前四个字节是网络连接总数

 

For j = 1 To rows

 

CopyMemory IfTable, buf(4 + (j - 1) * Len(IfTable)), Len(IfTable)

 

有效编号(j - 1).Caption = Str(j)

 

'

 

界面类型(j - 1).Caption = GetType(IfTable.dwType)

 

'

 

连接速度(j - 1).Caption = IfTable.dwSpeed

 

'

 

总共收到(j - 1).Caption = Str(IfTable.dwInOctets)

 

If IfTable.dwSpeed = 9600 Then ' 绘制拨号网络的下载流量图

 

Pic_X = Pic_X + 1

 

If Pic_X > Picture1.ScaleWidth Then

 

Pic_X = 1

 

Picture1.Cls

 

For i = 1 To 8 ' 绘制网格

 

Picture1.Line (0, Picture1.ScaleHeight - i * 10 - 1)- _

 

(Picture1.ScaleWidth, Picture1.ScaleHeight - i * 10 - 1), &H808080

 

Next i

 

End If

 

If Old_In = 0 Then

 

Old_In = IfTable.dwInOctets

 

Pic_Y = Picture1.ScaleHeight - 1

 

End If

 

i = Picture1.ScaleHeight - (IfTable.dwInOctets - Old_In) / 102.4 - 1

 

Picture1.Line (Pic_X - 1, Pic_Y)-(Pic_X, i), &HFF& ' 绘制流量

 

Pic_Y = i

 

Old_In = IfTable.dwInOctets

 

End If

 

'

 

总共发送(j - 1).Caption = Str(IfTable.dwOutOctets)

 

'

 

操作状态(j - 1).Caption = GetState(IfTable.dwOperStatus)

 

'

 

总共错收(j - 1).Caption = Str(IfTable.dwInErrors)

 

'

 

总共错发(j - 1).Caption = Str(IfTable.dwOutErrors)

 

'

 

其它共收(j - 1).Caption = Str(IfTable.dwInUnknownProtos)

 

Next j

 

End Sub

posted on 2009-08-12 14:12 青蛙學堂 阅读(424) 评论(0)  编辑 收藏 引用 所属分类: 硬件百科軟件布袋

只有注册用户登录后才能发表评论。
<2012年4月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

导航

统计

常用链接

留言簿(8)

随笔分类

随笔档案

收藏夹

青蛙学堂

最新评论

阅读排行榜

评论排行榜