(转上版)http://miaozk2006.blog.163.com/blog/static/382470582011111391326440/

5、运行时截图:
第十四节 返回本机网络接口数量

1、函数:

Private Declare Function GetNumberOfInterfaces Lib "iphlpapi.dll" (pdwNumIf As Long) As Long

参数说明:

pdwNumIf:[输出] 指向一个接收本机接口数量的变量。

备注:返回的接口数包括loopback接口。这个数目比GetAdaptersInfo和GetInterfaceInfo函数返回的适配器数目要多一,因为那两个函数不返回loopback接口的信息。

返回值:成功,返回0;失败,返回错误代码。

2、使用到的类型:

3、使用到的常量:

4、主要代码分析:

①定义一个Long型变量,然后直接调用函数GetNumberOfInterfaces即可:

Dim dwNumIf As Long

r = GetNumberOfInterfaces(dwNumIf)

Print "本机接口数量", dwNumIf

5、运行时截图:

第十五节 设置本机默认的生存时间(time-to-live:TTL)值

1、函数:

Private Declare Function SetIpTTL Lib "iphlpapi.dll" (ByVal nTTL As Long) As Long

参数说明:

nTTL: [输入] 本机的新的生存时间(TTL)

返回值:成功,返回0;失败,返回错误代码。

2、使用到的类型:

3、使用到的常量:

4、主要代码分析:

①定义一个Ttl值,如64、128等,然后直接调用函数SetIpTTL:

Ttl = 128

r = SetIpTTL(Ttl)

5、运行时截图:

第十六节 获取本机IP 路由表

1、函数:

Private Declare Function GetIpForwardTable Lib "iphlpapi.dll" (pIpForwardTable As MIB_IPFORWARDTABLE , pdwSize As Long, bOrder As Long) As Long

参数说明:

pIpForwardTable:[输出]指向接收IP路由表作为MIB_IPFORWARDTABLE类型的缓存

pdwSize:[输入,输出] 输入,指定 pIpForwardTable参数指向缓存的大小;输出,如果指定的缓存大小不够大,将设置此参数为必须的大小。

bOrder:[输入] 指定返回的映射表是否按照种类排列。TRUE,按以下顺序排列:目的地地址;生成路由的协议;多路径路由策略;下一跃点的地址。

返回值:成功,返回0;失败,返回错误代码。

2、使用到的类型:

①MIB_IPFORWARDTABLE 包含了IP路由表接口。

Type MIB_IPFORWARDTABLE

dwNumEntries As Long                            '表中路由接口数目

Table(120) As MIB_IPFORWARDROW      '指向MIB_IPFORWARDROW类型阵列

End Type

②MIB_IPFORWARDROW 包含描述IP网络路由的信息

public type MIB_IPFORWARDROW

dwForwardDest as long      '目的地IP地址

dwForwardMask as long     '目的地主机的子网掩码

dwForwardPolicy as long    '将会引起多通道路由选择的设置条件。参看RFC 1354。

dwForwardNextHop as long        '路由器中IP地址的下一个跃点

dwForwardIfIndex as long         '路由的接口序号

dwForwardType as long      'RFC 1354中路由的定义,以下值之一:

常量名称
 值
 说明

MIB_IPROUTE_TYPE_OTHER
 1
 其他

MIB_IPROUTE_TYPE_INVALID
 2
 非法路由

MIB_IPROUTE_TYPE_DIRECT
 3
 下一个跃点是目的地(本地路由)

MIB_IPROUTE_TYPE_INDIRECT
 4
 下一个跃点不是目的地 (远程路由)

dwForwardProto as long  '生成路由的协议,具体IPX协议值参看Routprot.h,而IP条目参看Iprtrmib.h

dwForwardAge as long  '路由持续时间,毫秒。仅用于路由远程访问服务(RRAS:Routing and Remote Access Service)运行时候,并且仅当路由类型为PROTO_IP_NETMGMT。

dwForwardNextHopAS as long  '下一跃点的自治系统编号

dwForwardMetric1 as long  '路由协议专有的公制值。详情参见RFC 1354。

dwForwardMetric2 as long  '路由协议专有的公制值。详情参见RFC 1354。

dwForwardMetric3 as long  '路由协议专有的公制值。详情参见RFC 1354。

dwForwardMetric4 as long  '路由协议专有的公制值。详情参见RFC 1354。

dwForwardMetric5 as long  '路由协议专有的公制值。详情参见RFC 1354。

End Type

3、使用到的常量:

4、主要代码分析:

①定义一个MIB_IPFORWARDTABLE类型的变量,对函数GetIpForwardTable进行两次调用,第一次调用获得参数pdwSize的实际大小;第二次调用获取pIpForwardTable数据:

Dim mIF As MIB_IPFORWARDTABLE

r = GetIpForwardTable(mIF, dwsize, order)

r = GetIpForwardTable(mIF, dwsize, order)

②调用For…Next循环,获取每个路由的信息:

For i = 0 To mIF.dwNumEntries - 1

Realip = inversaip(mIF.table(i).dwForwardDest)

RealMask = inversaip(mIF.table(i).dwForwardMask)

Print "ip", Realip

Print "mask", RealMask

Next

③将长整型格式的ip地址转换为标准IP地址格式("xxx.xxx.xxx.xxx"格式):

Private Function inversaip(IPAddrLng As Long) As String

‘同本章第九节 4  ③

End Function

5、运行时截图:

第十七节 设置TCP连接状态

1、函数:

①Private Declare Function SetTcpEntry Lib "iphlpapi.dll" (pTcpTable As MIB_TCPROW) As Long

参数说明:

PTcpRow:[输入]指向MIB_TCPROW类型,这个类型指定了TCP连接的标识,也指定了TCP连接的新状态。调用者必须指定此类型中所有成员的值。

备注:通常设置为MIB_TCP_STATE_DELETE_TCB(值为12)用来断开某个TCP连接,这也是唯一可在运行时设置的状态。

返回值:成功,返回0;失败,返回错误代码。

②Private Declare Function GetTcpTable Lib "iphlpapi.dll" (ByRef pTcpTable As MIB_TCPTABLE, ByRef pdwSize As Long, ByVal bOrder As Long) As Long

参看 本章第四节 1

2、使用到的类型:

①MIB_TCPTABLE 类型包含Tcp连接表。参看本章第四节 2 ①

②MIB_TCPROW 类型包含了TCP连接信息。参看本章第四节 2 ②

3、使用到的常量:

Const MIB_TCP_STATE_DELETE_TCB = 12           ‘设置断开此Tcp连接

4、主要代码分析:

①定义一个MIB_TCPTABLE类型的变量后直接调用GetTcpTable(参看本章第四节 4 ①)

②使用For…Next循环遍历各个Tcp连接的信息,此时的mtcp.TCP_Table(i) 将作为设置TCP连接状态的参数依据(参看本章第四节 4  ②)

For i = 0 To mtcp.dwNum_Of_Entries - 1

Print  mtcp.TCP_Table(i).dwLocalAddr & "->" & mtcp.TCP_Table(i).dwRemoteAddr

Next

③手动输入要删除的TCP连接的序号,设置MIB_TCPROW类型的每一个成员的值

TcpIndex = InputBox("接口号", "Del..")

If TcpIndex = "" Then Exit Sub Else TcpIndex = CLng(TcpIndex)

Ttable.dwLocalAddr = mtcp.TCP_Table(TcpIndex).dwLocalAddr

Ttable.dwLocalPort = mtcp.TCP_Table(TcpIndex).dwLocalPort

Ttable.dwRemoteAddr = mtcp.TCP_Table(TcpIndex).dwRemoteAddr

Ttable.dwRemotePort = mtcp.TCP_Table(TcpIndex).dwRemotePort

Ttable.dwState = MIB_TCP_STATE_DELETE_TCB

④调用函数SetTcpEntry断开对应序号的TCP连接,需要注意的是,断开系统的连接,即使调用函数显示成功,但实际并不能断开系统连接。

r = SetTcpEntry(Ttable)

5、运行时截图:

第十八节 在本地电脑的地址解析协议(ARP :Address Resolution Protocol)表中创建和删除一个ARP

1、函数:

①Private Declare Function CreateIpNetEntry Lib "iphlpapi.dll" (pArpEntry As MIB_IPNETROW) As Long

参数说明:

pArpEntry [输入] 指向一个指定了新接口信息的MIB_IPNETROW类型,调用者必须为这个类型指定所有成员的值。

返回值:成功,返回0;失败,返回错误代码。

②Private Declare Function DeleteIpNetEntry Lib "iphlpapi.dll" (pArpEntry As MIB_IPNETROW) As Long

参数说明:

pArpEntry:[输入] 指向一个MIB_IPNETROW类型。这个类型结构指定了要删除的接口。调用者至少要为这个类型指定dwIndex和 dwAddr成员的值。

返回值:成功,返回0;失败,返回错误代码。

③inet_addr是Winsocket的函数而非”iphlpapi.dll”提供的函数,目的是将标准IP地址(”xxx.xxx.xxx.xxx”)的字符串转为电脑能识别的长整型的数据。

Private Declare Function inet_addr Lib "wsock32.dll" (ByVal cp As String) As Long

参数说明:

cp:[输入] 标准IP地址(”xxx.xxx.xxx.xxx”)的字符串

返回值:成功,返回长整型的数据。

2、使用到的类型:

①MIB_IPNETROW 包含地址解析协议(ARP :Address Resolution Protocol)接口信息:

参看 本章 第十节 2 ②

3、使用到的常量:

Const MAXLEN_PHYSADDR = 7

4、主要代码分析:

Dim MI As MIB_IPNETROW

MI.dwIndex = 2

MI.dwAddr = inet_addr("xxx.xxx.xxx.5")           ‘括号内为要设置Arp的IP地址

MI.bPhysAddr(0) = 0

MI.bPhysAddr(1) = 80

MI.bPhysAddr(2) = 80

MI.bPhysAddr(3) = 80

MI.bPhysAddr(4) = 80

MI.bPhysAddr(5) = 80

MI.bPhysAddr(6) = 0

MI.bPhysAddr(7) = 0

MI.dwPhysAddrLen = 6

MI.dwType = 3

rvalue = CreateIpNetEntry(MI)

5、运行时截图:

第十九节 Ping一个IP地址

1、函数:

①获得一个Icmp句柄,使ICMP响应能被发出(以下两种声明xp下都可以,但是在2000下要用icmp.dll):

Private Declare Function IcmpCreateFile Lib "iphlpapi.dll" () As Long

Private Declare Function IcmpCreateFile Lib "icmp.dll" () As Long

返回值:成功,返回一个Icmp句柄;失败,返回0。

②发送一条ICMP响应要求, 接着返回回复(以下两种声明xp下都可以,但是在2000下调用动态链接库icmp.dll):

Private Declare Function IcmpSendEcho Lib "icmp.dll" (ByVal IcmpHandle As Long, ByVal DestinationAddress As Long, ByVal RequestData As String, ByVal RequestSize As Long, ByVal RequestOptions As Long, ReplyBuffer As ICMP_ECHO_REPLY, ByVal ReplySize As Long, ByVal Timeout As Long) As Long

Private Declare Function IcmpSendEcho Lib "iphlpapi.dll" (ByVal IcmpHandle As Long, ByVal DestinationAddress As Long, ByVal RequestData As String, ByVal RequestSize As Long, ByVal RequestOptions As Long, ReplyBuffer As ICMP_ECHO_REPLY, ByVal ReplySize As Long, ByVal Timeout As Long) As Long

参数说明:

IcmpHandle:[输入] 由IcmpCreateFile打开的句柄

DestinationAddress:[输入] 响应要求的目的地

RequestData:[输入] 包含要发送的请求数据中的缓存

RequestSize:[输入] RequestData请求数据缓存的大小,字节

RequestOptions:[输入] 指向IP头请求选项的IP_OPTION_INFORMATION类型的指针,可以为空。

ReplyBuffer:[输出] 用来保存请求响应的缓存。成功,包含一个类型的阵列,缓存应该足够大至少保存一个ICMP_ECHO_REPLY类型加上MAXRequestSize(=8) 字节的数据(一个ICMP错误信息包含8字节数据)。

ReplySize:[输出] ReplyBuffer 的大小,字节

Timeout:[输出] 等待响应时间,毫秒

返回值:成功,返回1,ICMP_ECHO_REPLY类型的数目保存在ReplyBuffer中。每一个响应的状态包含在此类型。如果返回0,调用GetLastError获取更多错误信息。

③关闭一个由IcmpCreateFile获得的Icmp句柄(以下两种声明xp下都可以,但是在2000下要用icmp.dll):

Private Declare Function IcmpCloseHandle Lib "icmp.dll" (ByVal IcmpHandle As Long) As Long

Private Declare Function IcmpCloseHandle Lib "iphlpapi.dll" (ByVal IcmpHandle As Long) As Long

返回值:成功,返回1。

④Private Declare Function inet_addr Lib "wsock32.dll" (ByVal cp As String) As Long

参见本章第十八节 1、 ③

2、使用到的类型:

①ICMP_ECHO_REPLY 描述了回复要求的返回响应的数据

Type ICMP_ECHO_REPLY

address  As Long                  ‘包含正回复的IP地址

Status  As Long                    ‘包含回复的状态(参看后面的常量部分)

RoundTripTime  As Long      ‘往返时间RTT(毫秒)

DataSize  As Integer             ‘回复数据大小(字节)

Reserved  As Integer             ‘保留

ptrData  As Long                  ‘指向回复数据的指针

Options  As IP_OPTION_INFORMATION ‘回复选项

Data  As String * 250     ‘

End Type

备注:vb和vc关于此类型的声明不一样vb多了Dara成员。

②IP_OPTION_INFORMATION  描述被包含在IP包头部的选项

Type IP_OPTION_INFORMATION

Ttl     As Byte                        ‘生存时间

Tos    As Byte                        ‘服务类型

Flags As Byte                        ‘IP头标志

OptionsSize      As Byte          ‘选项数据的大小,字节

OptionsData     As Long         ‘指向选项数据的指针

End Type

3、使用到的常量:

Const ICMP_SUCCESS = 0                                                                 ‘成功

Const ICMP_STATUS_BUFFER_TO_SMALL = 11001                 '缓存太小

Const ICMP_STATUS_DESTINATION_NET_UNREACH = 11002          '目的地网络不能到达

Const ICMP_STATUS_DESTINATION_HOST_UNREACH = 11003       '目的地主机不能到达

Const ICMP_STATUS_DESTINATION_PROTOCOL_UNREACH = 11004      '目的地协议不能到达

Const ICMP_STATUS_DESTINATION_PORT_UNREACH = 11005       '目的地端口不能到达

Const ICMP_STATUS_NO_RESOURCE = 11006                     '没有资源

Const ICMP_STATUS_BAD_OPTION = 11007                       '错误选项

Const ICMP_STATUS_HARDWARE_ERROR = 11008                 '硬件错误

Const ICMP_STATUS_LARGE_PACKET = 11009                    '信息包太大

Const ICMP_STATUS_REQUEST_TIMED_OUT = 11010              '请求超时

Const ICMP_STATUS_BAD_REQUEST = 11011                     '错误请求

Const ICMP_STATUS_BAD_ROUTE = 11012                         '错误路由

Const ICMP_STATUS_TTL_EXPIRED_TRANSIT = 11013           'TTL终止传输

Const ICMP_STATUS_TTL_EXPIRED_REASSEMBLY = 11014          'TTL终止重新组装

Const ICMP_STATUS_PARAMETER = 11015                         '参数有问题

Const ICMP_STATUS_SOURCE_QUENCH = 11016                    '资源结束

Const ICMP_STATUS_OPTION_TOO_BIG = 11017                  '选项太大

Const ICMP_STATUS_BAD_DESTINATION = 11018                 '错误目的地

Const ICMP_STATUS_NEGOTIATING_IPSEC = 11032                '谈判IPSEC

Const ICMP_STATUS_GENERAL_FAILURE = 11050                  '常规失败

4、主要代码分析:

①使用函数IcmpCreateFile创建一个Icmp句柄

IcmpHandle = IcmpCreateFile()

②构筑以下参数:定义一个ICMP_ECHO_REPLY类型、目的地IP地址的Long形式、要发送并会返回的数据、数据大小、ICMP_ECHO_REPLY类型的大小、超时设置:

Dim RBuffer As ICMP_ECHO_REPLY

DAddr = inet_addr("xxx.xxx.xxx.xxx")               ‘括号内为要Ping的目的地IP地址

RData = "Hi,Hello!"

RequestSize = Len(RData)

ReplySize = Len(RBuffer)

Timeout = 1000

③调用函数IcmpSendEcho:

r = IcmpSendEcho(IcmpHandle, DAddr, RData, RequestSize, 0, RBuffer, ReplySize, Timeout)

Print "状态", IcmpSta(RBuffer.Status)

Print "Ttl", RBuffer.Options.Ttl

④关闭由IcmpCreateFile获得的Icmp句柄:

r = IcmpCloseHandle(IcmpHandle)

⑤自定义函数IcmpSta获得Ping状态:

Private Function IcmpSta(icmpStatus As Long) As String

Select Case icmpStatus

Case ICMP_SUCCESS

IcmpSta = "成功"

Case ICMP_STATUS_DESTINATION_HOST_UNREACH

IcmpSta = "目的地主机不能到达"

Case ……             ‘参看本节中常量的说明

……

Case Else

IcmpSta = "错误信息"

End Select

End Function

5、运行时截图:

第二十节 测定到指定目的地往返时间和跳跃数

1、函数:

①Private Declare Function GetRTTAndHopCount Lib "iphlpapi.dll" (ByVal DestIpAddress As Long, HopCount As Long, MaxHops As Long, RTT As Long) As Long

DestIpAddress :[输入]要测定RTT和跳跃数的目的地IP地址。

HopCount:[输出] 指向一个ULONG变量。这个变量接收由DestIpAddress参数指定的到目的地的跳跃数。

MaxHops:[输入] 寻找目的地的最大跳跃数目。如果跳跃数超过这个数目,函数将终止搜寻并返回FALSE。

RTT:[输出] 到达DestIpAddress指定的目的地的往返时间(Round-trip time),单位毫秒。

返回值:成功返回 1,否则返回0。

②Private Declare Function inet_addr Lib "wsock32.dll" (ByVal cp As String) As Long

参见本章第十八节 1、 ③

2、使用到的类型:

3、使用到的常量:

4、主要代码分析:

①设置目标IP地址,要将“xxx.xxx.xxx.xxx”标准格式转换为长整型格式,指定最大跳跃数目,然后直接调用函数GetRTTAndHopCount:

Dip = inet_addr("220.181.27.5")     '这里是探测www.baidu.com

MaxH = 50

r = GetRTTAndHopCount(Dip, HC, MaxH, RTT)

Print "hopecount", HC

5、运行时截图:

第二十一节 增加和删除一个IP地址

1、函数:

①Private Declare Function AddIPAddress Lib "iphlpapi.dll" ( ByVal Address As Long, ByVal IpMask As Long, ByVal Ifindex As Long, NTEContext As Long, NTEInstance As Long) As Long

参数说明:

Address:[输入]要增加的IP地址

IpMask:[输入]IP地址的子网掩码

IfIndex:[输入]增加IP地址的适配器,实际值为MIB_IPADDRTABLE.table(适配器编号).dwIndex

NTEContext:[输出]成功则指向一个与这个IP地址关联的网络表接口(Net Table Entry:NTE)ULONG变量。调用者可以在稍后使用这个关系到调用DeleteIPAddress。

NTEInstance:[输出]成功则指向这个IP地址的网络表接口(Net Table Entry:NTE)实例。

返回值:成功,返回0;失败,返回错误代码。

备注:①增加的IP是临时的,当系统重新启动或者发生其它的PNP事件的时候这个IP就不存在了,比如将网卡禁用,然后启用,就会发现之前调用函数AddIPAddress增加的的IP地址不存在了。②有时候,调用这个函数,可能造成网络出错、系统Arp映射错误等,但可以禁用/启用网卡恢复成正常状态。。

②Private Declare Function DeleteIPAddress Lib "iphlpapi.dll" (ByVal NTEContext As Long) As Long

参数说明:

NTEContext:[输入] IP地址关联的网络表接口(Net Table Entry:NTE),这个关联是之前用AddIPAddress所创建的,在调用函数GetAdaptersInfo后,从获得的IP_ADAPTER_INFO. IpAddressList. Context 中也可获得这个参数的值

返回值:成功,返回0;失败,返回错误代码。

备注:实际上函数DeleteIPAddress只能删除由函数AddIPAddress创建的IP地址。

③Private Declare Function GetIpAddrTable Lib "iphlpapi.dll" (pIpAddrTable As MIB_IPADDRTABLE, pdwSize As Long, bOrder As Long) As Long

参看本章第九节 1、

④Private Declare Function GetAdaptersInfo Lib "iphlpapi.dll" (IpAdapterInfo As Any, pOutBufLen As Long) As Long

参看本章第一节 1、

2、使用到的类型:

①MIB_IPADDRTABLE 包含IP地址入口表
参看本章第九节 2、①

②MIB_IPADDRROW 指定特殊IP地址的信息

参看本章第九节 2、②

③IP_ADAPTER_INFO类型:包含本机网络适配器信息。

参看本章第一节 1、①

④IP_ADDR_STRING描述IP 地址链表的节点。

参看本章第一节 1、②

3、使用到的常量:

Const MAX_ADAPTER_NAME_LENGTH = 260

Const MAX_ADAPTER_ADDRESS_LENGTH = 8

Const MAX_ADAPTER_DESCRIPTION_LENGTH = 132

4、主要代码分析:

①使用函数GetIpAddrTable获取某个要增加IP的适配器的dwIndex:

Dim IpAddrTable As MIB_IPADDRTABLE

dwsize = Len(IpAddrTable)

r = GetIpAddrTable(IpAddrTable, dwsize, order)

②传入IP地址和Mask地址的长整数形式,使用函数AddIPAddress增加地址,返回的NteC 将用于函数DeleteIPAddress,函数的返回值为0表示成功 :

Addr = inet_addr("192.168.1.5")

IpM = inet_addr("255.255.255.0")

r = AddIPAddress(Addr, IpM, IpAddrTable.table(1).dwIndex, NteC, NteI)

③调用函数DeleteIPAddress,返回值为0表示成功:

r = DeleteIPAddress(NteC)

备注:增加删除IP地址最好的方法是将Ntec的值记录下来,如果实在没有记录,那么可以调用函数GetAdaptersInfo获得网络适配器信息,然后获得要删除的IP地址的网络接口表:IP_ADDR_STRING.Context,这个值实际就是Ntec的值。

5、运行时截图:

第三章 IPHLPAPI 的其它函数

第一节 IPHLPAPI 的其它函数

IPHLPAPI还有以下的函数,这里给出C语言的函数原型和参数说明,具体说明详见MSDN2003。

1、GetAdapterIndex:从名称获得一个适配器的序号

DWORD GetAdapterIndex( LPWSTR AdapterName, PULONG IfIndex);

AdapterName:[输入] 指定了适配器名称的Unicode字符串

IfIndex:[输出] 指向一个指向适配器序号的ULONG变量指针

返回值:成功,返回0;失败,返回错误代码。

2、GetAdaptersAddresses:返回和适配器关联的地址

DWORD WINAPI GetAdaptersAddresses( ULONG Family, DWORD Flags, PVOID Reserved,  PIP_ADAPTER_ADDRESSES pAdapterAddresses,  PULONG pOutBufLen);

Family:[输入] 获得地址族,必须是以下值之一:

AF_INET      仅返回IPv4地址

AF_INET6     仅返回IPv6地址

AF_UNSPEC 从所有的地址族返回地址

Flags:[输入]返回地址类型,这个参数为0或是以下值的联合值:

GAA_FLAG_INCLUDE_PREFIX        返回IPv6地址前缀

GAA_FLAG_SKIP_UNICAST            不返回unicast地址

GAA_FLAG_SKIP_ANYCAST           不返回anycast地址

GAA_FLAG_SKIP_FRIENDLY_NAME      不返回适配器的友好名称

GAA_FLAG_SKIP_MULTICAST        不返回多点传送(multicast)地址

GAA_FLAG_SKIP_DNS_SERVER      不返回DNS服务器地址

Reserved:[输入] 调用程序必须将此参数置为NULL

pAdapterAddresses:[输入,输出] 指向一段IP_ADAPTER_ADDRESSES缓存,成功的话,该缓存包含地址信息。

pOutBufLen:[输出] 返回pAdapterAddresses所在缓存的大小

返回值:成功,返回0;失败,返回错误代码。

3、GetPerAdapterInfo:返回与适配器相应的指定接口的信息

DWORD GetPerAdapterInfo(ULONG IfIndex,PIP_PER_ADAPTER_INFO pPerAdapterInfo,  PULONG pOutBufLen);

IfIndex:[输入] 一个接口的序号。函数将返回与这个序号相应的适配器接口信息。

pPerAdapterInfo:[输出]指向一个接收适配器信息的IP_PER_ADAPTER_INFO类型。

pOutBufLen:[输入]指向一个指定了IP_PER_ADAPTER_INFO类型ULONG变量。如果指定的大小不够大,将设置为须要的大小并返回ERROR_BUFFER_OVERFLOW错误。

返回值:成功,返回0;失败,返回错误代码。

备注:个人觉得实际使用时候,获取IfIndex比较困难,不如用GetAdaptersInfo。

4、GetUniDirectionalAdapterInfo:接收本机安装的单向适配器的信息

DWORD GetUniDirectionalAdapterInfo(PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS pIPIfInfo, PULONG dwOutBufLen);

pIPIfInfo:[输出]指向一个接收本机已安装的单向适配器的信息的IP_UNIDIRECTIONAL_ADAPTER_ADDRESS类型。

dwOutBufLen:[输出]指向一个ULONG变量用来保存pIPIfInfo参数缓存的大小。

返回值:成功,返回0;失败,返回错误代码。

5、CreateProxyArpEntry:为本地电脑指定的IP地址创建一个代理服务器地址解析协议(Proxy Address Resolution Protocol :PARP) 接口

DWORD CreateProxyArpEntry(DWORD dwAddress, DWORD dwMask, DWORD dwIfIndex);

dwAddress:[输入] 作为代理服务器的电脑的IP地址。

dwMask:[输入]指定了dwAddress的IP地址对应的子网掩码。

dwIfIndex:[输入]代理服务地址解析协议(ARP)接口的索引通过dwAddress识别IP地址。换句话说,当dwAddress一个地址解析协议(ARP)请求在这个接口上被收到的时候,本地电脑的物理地址的接口作出响应。如果接口类型不支持地址解析协议(ARP),比如:端对端协议(PPP),那么调用失败。

返回值:成功,返回0;失败,返回错误代码。

6、DeleteProxyArpEntry:删除由dwAddress和dwIfIndex参数指定的PARP接口

DWORD DeleteProxyArpEntry( DWORD dwAddress, DWORD dwMask, DWORD dwIfIndex);

dwAddress:[输入] 作为代理服务器的电脑的IP地址

dwMask:[输入] 对应dwAddress的子网掩码

dwIfIndex::[输入]对应IP 地址dwAddress指定的支持代理服务器地址解析协议(Proxy Address Resolution Protocol :PARP)的电脑的接口序号。

返回值:成功,返回0;失败,返回错误代码。

7、FlushIpNetTable:从ARP表中删除指定接口的ARP接口

DWORD FlushIpNetTable( DWORD dwIfIndex);

dwIfIndex:[输入] 将要删除的ARP接口的序号

返回值:成功,返回0;失败,返回错误代码。

8、GetFriendlyIfIndex:获得一个接口序号并返回一个反向兼容的接口序号

DWORD GetFriendlyIfIndex( DWORD IfIndex);

IfIndex:[输入] 来自反向兼容或者“友好”的接口序号

返回值:成功,返回0;失败,返回错误代码。

9、GetIfEntry:返回指定接口的信息

DWORD GetIfEntry( PMIB_IFROW pIfRow);

pIfRow:[输入,输出] 成功返回一个指向本机接口信息的MIB_IFROW类型;输出,需设置MIB_IFROW的dwIndex 为想要获取信息的接口的序号。

返回值:成功,返回0;失败,返回错误代码。

10、SetIfEntry:设置一个接口的管理状态

DWORD SetIfEntry( PMIB_IFROW pIfRow);

pIfRow:[输入] 指向一个MIB_IFROW类型。dwIndex成员指定了要设置管理状态的接口;dwAdminStatus成员指定了新的管理状态,为以下值之一:

MIB_IF_ADMIN_STATUS_UP   接口可被管理;

MIB_IF_ADMIN_STATUS_DOWN   接口不能被管理。

返回值:成功,返回0;失败,返回错误代码。

11、GetIcmpStatisticsEx:返回本机IPv4 ICMP或IPv6 ICMP统计表。

DWORD GetIcmpStatisticsEx( PMIB_ICMP_EX pStats, DWORD dwFamily);

pStats :[输出] 指向一个本机收到ICMP 统计表的MIB_ICMP类型。

dwFamily :[输入]返回ICMP 统计表的协议族,必须数以下值:

AF_INET      Internet Protocol version 4 (IPv4)

AF_INET6     Internet Protocol version 6 (IPv6)

返回值:成功,返回0;失败,返回错误代码。

12、GetIpStatisticsEx:返回IP统计表并支持IPv6协议族

DWORD GetIpStatisticsEx( PMIB_IPSTATS pStats, DWORD dwFamily);

pStats:[输出] 指向一个收到本机IP统计表的MIB_IPSTATS类型。

dwFamily:[输入]协议族,以下值之一:

AF_INET Internet Protocol version 4 (IPv4).

AF_INET6 Internet Protocol version 6 (IPv6).

返回值:成功,返回0;失败,返回错误代码。

13、Icmp6CreateFile打开一个句柄,使IPv6的 ICMP回应请求能被发出

HANDLE Icmp6CreateFile(void);

返回值:成功,返回一个句柄,失败,返回0。

14、IcmpParseReplies:解析提供的响应缓存,返回ICMP响应创建数目

DWORD IcmpParseReplies(LPVOID ReplyBuffer, DWORD ReplySize);

ReplyBuffer :[输入] 被IcmpSendEcho2传递的缓存。它被重写来保留ICMP_ECHO_REPLY类型的阵列,它的类型为PICMP_ECHO_REPLY。

ReplySize:[输入] ReplyBuffer的大小。

返回值:成功,返回ICMP响应创建的数目,失败,返回0。

备注:此函数不能被用于之前传递给IcmpSendEcho的响应缓存;IcmpSendEcho在返回给使用者前解析那些缓存。仅和IcmpSendEcho2一起使用此函数。

15、Icmp6ParseReplies:分析被供给答复的缓存,返回IPv6 ICMP数字响应发现

DWORD Icmp6ParseReplies( LPVOID ReplyBuffer, DWORD ReplySize);

ReplyBuffer:[输入]传给Icmp6SendEcho2的缓存,是被重写用来保留ICMP_ECHO_REPLY类型的阵列,它的类型是PICMP_ECHO_REPLY。

ReplySize:[输入] ReplyBuffer的大小。

返回值:成功,返回IPv6 ICMP响应创建的数目;失败,返回0。

16、IcmpSendEcho2:发送一个IPv6 ICMP Echo要求并立即返回或者超时返回

DWORD IcmpSendEcho2(HANDLE IcmpHandle,HANDLE Event,FARPROC ApcRoutine,PVOID ApcContext,IPAddr DestinationAddress,LPVOID RequestData,WORD RequestSize, PIP_OPTION_INFORMATION RequestOptions, LPVOID ReplyBuffer, DWORD ReplySize, DWORD Timeout);

IcmpHandle:[输入] 由IcmpCreateFile打开的句柄

Event:[输入]用来标志无论何时ICMP响应到达的事件

ApcRoutine:[输入] 被调用的程序当前正调用线程在一个警告线程(alertable thread)中并且一个ICMP回复到达。.

ApcContext:[输入] 当IcmpSendEcho2 成功调用后用于ApcRoutine的可选参数

DestinationAddress:[输入] 响应要求的目的地

RequestData:[输入] 包含于请求中要发送的数据的缓存

RequestSize:[输入] requestdata缓存的大小,字节

RequestOptions:[输入] 指向请求的IP头选项的IP_OPTION_INFORMATION类型的指针,可为空。

ReplyBuffer:[输出]保存请求响应得缓存。成功调用,缓存包含一个跟随选项和数据的ICMP_ECHO_REPLY类型的阵列。缓存必须足够大来保存至少一个ICMP_ECHO_REPLY 类型,它必须足够大至少保存9个或更多字节的数据。

ReplySize:[输出] replybuffer的大小,字节

Timeout:[输出] 等待回应时间,毫秒

返回值:成功,返回收到储存在ReplyBuffer中的回应的数目。失败,返回0。

备注:①当使用异步 (ApcRoutine或者Event被指定),ReplyBuffer和ReplySize必须同意响应。ICMP响应数据被拷贝到ReplyBuffer,函数调用者必须使用IcmpParseReplies解析异步。IPv6,使用Icmp6SendEcho2和Icmp6ParseReplies。

②对于Windows 95/98/Me,参数Event、ApcRoutine、ApcContext被忽略。

17、SetIpStatistics:启用或者禁止转发IP包或设置本机TTL值

DWORD SetIpStatistics( PMIB_IPSTATS pIpStats);

pIpStats:[输入] 指向一个MIB_IPSTATS类型。调用者应该为此类型的dwForwarding和dwDefaultTTL成员设置新值。保持某个成员的值,使用MIB_USE_CURRENT_TTL或者 MIB_USE_CURRENT_FORWARDING。

返回值:成功,返回0;失败,返回错误代码。

备注:①在实际使用中,好像只能设置TTL的值,别的值设置有可能导致错误87(参数错误)或者虽然调用成功,但是并没有达到预期那样设置成功;②设置默认的生存时间(TTL),也可以使用SetIpTTL函数。

18、IpReleaseAddress:释放一个之前通过DHCP获得的IP地址

DWORD IpReleaseAddress( PIP_ADAPTER_INDEX_MAP AdapterInfo);

AdapterInfo:[输入]指向一个IP_ADAPTER_INDEX_MAP类型,指定了要释放的和IP地址关联的适配器。

返回值:成功,返回0;失败,返回错误代码。

19、IpRenewAddress:更新一个之前通过DHCP获得的IP地址租期

DWORD IpRenewAddress( PIP_ADAPTER_INDEX_MAP AdapterInfo);

AdapterInfo:[输入]指向一个IP_ADAPTER_INDEX_MAP类型,指定了与适配器关联的IP地址更新。

返回值:成功,返回0;失败,返回错误代码。

20、NotifyAddrChange:当IP地址到接口的映射表发生改变,将引发一个通知

DWORD NotifyAddrChange( PHANDLE Handle, LPOVERLAPPED overlapped);

Handle:[输出]指向一个HANDLE变量,用来接收一个句柄handle使用到异步通知中。

警告:不能关掉这个句柄。

overlapped:[输入]指向一个OVERLAPPED类型,通知调用者任何IP地址到接口的映射表改变。

返回值:成功,如果调用者指定Handle和overlapped参数为空,返回NO_ERROR;如果调用者指定非空参数,返回ERROR_IO_PENDING。失败,使用FormatMessage获取错误信息。

备注:①如果调用者指定Handle和overlapped参数为空,对NotifyAddrChange的调用将会被阻止直到一个IP地址改变发生。

②调用者指定了一个handle变量和一个OVERLAPPED类型,调用者可以使用返回的handle以及OVERLAPPED类型来接收路由表改变的异步通知。

21、NotifyRouteChange:IP路由表发生改变将引起一个通知

DWORD NotifyRouteChange( PHANDLE Handle, LPOVERLAPPED overlapped);

Handle:[输出]指向一个HANDLE变量,此变量接收一个用作异步通知的句柄。

overlapped:[输入]指向一个OVERLAPPED类型,此类型通知调用者路由表的每一个改变。

返回值:成功,如果调用者指定Handle和overlapped参数为空,返回NO_ERROR;如果调用者指定非空参数,返回ERROR_IO_PENDING。失败,使用FormatMessage获取错误信息。

备注:①如果调用者指定Handle和overlapped参数为空,对NotifyRouteChange的调用将会被阻止直到一个路由表改变发生。

②调用者指定了一个handle变量和一个OVERLAPPED类型,调用者可以使用返回的handle以及OVERLAPPED类型来接收路由表改变的异步通知。

22、CreateIpForwardEntry:创建一个路由到本地电脑IP路由表

DWORD CreateIpForwardEntry( PMIB_IPFORWARDROW pRoute);

pRoute:[输入]指向指定了新路由信息的MIB_IPFORWARDROW类型的指针,调用者必须指定这个类型的所有成员值,必须指定PROTO_IP_NETMGMT作为MIB_IPFORWARDROW类型中dwForwardProto成员的值。

返回值:成功,返回0;失败,返回错误代码。

备注:①修改现有的路由表中的路由,使用SetIpForwardEntry函数。

②调用者不能指定路由协议,例如:PROTO_IP_OSPF作为MIB_IPFORWARDROW类型的dwForwardProto成员的值,路由协议标识符仅仅用来识别通过路由表接收到的路由信息。 例如:PROTO_IP_OSPF被用来识别通过OSPF路由表接收到的路由信息。

③MIB_IPFORWARDROW类型中的dwForwardPolicy成员在当前未使用,调用者应该将它设置为0。

④MIB_IPFORWARDROW类型中的 DwForwardAge成员仅仅用来当路由和远程数据服务(Remote Access Service :RRAS)正在运行,并且仅用于路由的PROTO_IP_NETMGMT类型。

⑤这个函数执行了一个特许操作,需要有必须的权限才能执行。

23、DeleteIpForwardEntry:从本地电脑的IP路由表中删除一个路由

DWORD DeleteIpForwardEntry( PMIB_IPFORWARDROW pRoute);

pRoute: [输入] 指向一个MIB_IPFORWARDROW类型。这个类型指定了识别将要删除的路由的信息。调用者必须指定类型中以下成员的值:dwForwardIfIndex;dwForwardDest;dwForwardMask;dwForwardNextHop;dwForwardPolicy。

返回值:成功,返回0;失败,返回错误代码。

备注:①MIB_IPFORWARDROW类型是GetIpForwardTable返回的。接下来,再将此类型投递给DeleteForwardEntry函数,便可删除指定的路由条目了。

② MIB_IPFORWARDROW类型的 dwForwardPolicy目前未使用,应该设置为0。

24、EnableRouter:增加涉及的enable-IP-forwarding要求的数目

DWORD WINAPI EnableRouter( HANDLE* pHandle, OVERLAPPED* pOverlapped);

pHandle:指向一个句柄

pOverlapped:指向一个OVERLAPPED类型。除了hEvent成员,类型中的其它成员必须设置为0。hEvent成员应该包含一个有效的事件对象的句柄。使用CreateEvent函数来创建这个事件对象。

返回值:成功,返回ERROR_IO_PENDING;失败,调用FormatMessage获取更多错误信息。

25、GetBestInterface:返回包含到指定IP地址的最佳路由接口序号

DWORD GetBestInterface( IPAddr dwDestAddr, PDWORD pdwBestIfIndex);

dwDestAddr:[输入]目标IP地址

pdwBestIfIndex:[输出] 指向一个包含到指定IP地址的最佳路由接口序号的DWORD变量

返回值:成功,返回0;失败,返回错误代码。

26、GetBestInterfaceEx:返回包含到指定IPv4或IPv6地址的最佳路由接口序号

DWORD GetBestInterface( struct sockaddr* pDestAddr, PDWORD pdwBestIfIndex);

dwDestAddr:[输入]目标IP地址,包含了一个sockaddr类型

pdwBestIfIndex:[输出] 指向一个包含到指定IP地址的最佳路由接口序号的DWORD变量

返回值:成功,返回0;失败,返回错误代码。

27、GetBestRoute:返回包含到指定IP地址的最佳路由

DWORD GetBestRoute(DWORD dwDestAddr,DWORD dwSourceAddr,PMIB_IPFORWARDROW pBestRoute);

dwDestAddr:[输入]目标IP地址

dwSourceAddr:[输入]源IP地址。这个Ip地址是本地电脑上相应的接口,如果有多个最佳路由存在,函数选择使用这个接口的路由。这个参数是可选的,调用者可以指定这个参数为0。

pBestRoute:[输出] 指向一个包含了最佳路由的MIB_IPFORWARDROW类型

返回值:成功,返回0;失败,返回错误代码。

28、SetIpForwardEntry:从本机IP路由表中修改一个现有的路由

DWORD SetIpForwardEntry( PMIB_IPFORWARDROW pRoute);

pRoute:[输入]指向一个为现有路由指定了新信息的MIB_IPFORWARDROW类型。调用者必须将此类型的dwForwardProto设置为PROTO_IP_NETMGMT。调用者同样必须指定该类型中以下成员的值:dwForwardIfIndex,dwForwardDest,dwForwardMask,dwForwardNextHop,dwForwardPolicy。

返回值:成功,返回0;失败,返回错误代码。

备注:①在IP路由表中创建一个新的路由,使用CreateIpForwardEntry函数;

②调用者不能指定一个路由协议,比如:不能将MIB_IPFORWARDROW的dwForwardProto 设置为PROTO_IP_OSPF。路由协议标识符(id)是用来标识通过指定的路由协议收到的路由信息。例如:PROTO_IP_OSPF是用来标识通过OSPF路有协议收到的路由信息;

③MIB_IPFORWARDROW类型中的dwForwardPolicy成员目前没有使用,指定为0。

29、UnenableRouter:减少涉及的enable-IP-forwarding要求数目

DWORD WINAPI UnenableRouter(OVERLAPPED* pOverlapped, LPDWORD lpdwEnableCount);

pOverlapped:指向一个OVERLAPPED类型。此类型必须和对EnableRouter的调用一样。

lpdwEnableCount:[out, optional]指向接收涉及剩余数目的DWORD变量。

备注:如果调用EnableRouter的进程没有调用UnenableRouter而终止,系统会减少IP推进涉及的数目就象调用了UnenableRouter一样。调用UnenableRouter后,使用CloseHandle来关闭OVERLAPPED类型中的事件对象的句柄。

返回值:成功,返回0;失败,返回错误代码。

30、GetTcpStatisticsEx:返回本机TCP 统计表并支持IPv6协议族

DWORD GetTcpStatisticsEx( PMIB_TCPSTATS pStats, DWORD dwFamily);

pStats:[输出]指向一个接收本机TCP统计表的MIB_TCPSTATS类型。

dwFamily:[输入]接收的统计表的协议族。为以下参数之一:

AF_INET Internet Protocol version 4 (IPv4);

AF_INET6 Internet Protocol version 6 (IPv6)。

返回值:成功,返回0;失败,返回错误代码。

31、GetUdpStatisticsEx:返回本机UDP统计表并支持IPv6协议族

DWORD GetUdpStatisticsEx( PMIB_UDPSTATS pStats, DWORD dwFamily);

pStats:[输出]指向一个接收到本机UDP统计表的MIB_UDPSTATS类型

dwFamily:[输入] 接收的统计表的协议族。为以下参数之一:

AF_INET Internet Protocol version 4 (IPv4).

AF_INET6 Internet Protocol version 6 (IPv6).

返回值:成功,返回0;失败,返回错误代码。

第二节 从C原型到Vb声明

1、Vb程序员为什么要了解C原型

很简单,因为无论MSDN还是网上所提供的资料大部分都是针对C语言的。我们要在Vb中使用这些资料,就需要我们将其从C翻译到Vb的。

2、如何实现C原型到Vb声明

重要的一点就是必须了解各种类型在内存中所占的实际字节长度。

比如:C中,DWORD型占用4个字节;Vb中相应的占用同样4字节长度的就是Long型。

因为这篇文章是介绍Iphlpapi的,因此这里将不会介绍从C原型到Vb声明的详细过程,请参考相应的书籍资料。

3、从C原型到Vb声明的一个例子

使用函数SetIpStatistics来设置本机TTL值

C原型:DWORD SetIpStatistics( PMIB_IPSTATS pIpStats);

Vb声明:Private Declare Function SetIpStatistics Lib "iphlpapi.dll" (pIpStats As MIB_IPSTATS) As Long

程序代码:

Dim ips As MIB_IPSTATS

ips.dwDefaultTTL = 63

r = SetIpStatistics(ips)

运行结果:

第一节 错误代码:

在Iphlpapi中调用函数常常是返回0表示调用成功,否则将返回错误代码,这里列举了部分常见的错误代码:

代码
 说明

31
 连接到系统的一个设备不能正常运转

50
 此函数不被本机系统支持

55
 指定的网络资源或设备不可用。如在只有一个网卡的机器上试图读取第二块网卡

87
 无效的参数,通常是进行API调用时传递了错误的参数

111
 缓冲区溢出

122
 缓冲区不是足够大

232
 无数据

第二节 一个重要函数

在本文所列举的代码中,有一个十分重要的函数CopyMemory,它简化了内存数据块间的拷贝,但是如果用的不当的话(比如对不可读写的内存块进行读写),则会出现致命的错误。

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

参数说明:

Destination:目标地址

Source:源地址

Length:要拷贝数据的长度

实例代码:

Dim a(9) As Long, b(9) As Long

For i = 0 To 9

a(i) = i

b(i) = 0

Next

CopyMemory b(0), a(0), 10 * 4           ‘将数组a的值拷贝到数组b

运行时截图:

第三节 实例一:网络数据流量图

在第二章第二节介绍了GetIfTable函数,通过这个函数可以获得总共收到和发出的数据字节数等信息。比较前后两次总共收到与发出的数据大小以及之间的时间,就可以获得当前网络传输数据的速率。

1、程序设置

一个Picture控件,width=5000;height=2000

Picture控件中设置一个Shape控件,index=0,背景色为红色

一个Timer控件,Interval=1000

两个按钮,caption分别为“开始”、“停止”

其余为Label控件,记录当前接收的数据字节、当前发送的数据字节、当前的传输速率,最大传输速率。

2、程序思路

设置Timer. Interval=1000,每隔一秒调用一次函数GetIfTable,获取一次数据。前后两次数据的差就是一秒内传输数据的大小。使用一组Shape控件构成柱状图来表示当前的数据流量。设置Picture的宽度为5000,相应的设置Shape控件的宽度为100,这样可以在图上显示50个shape控件,表示了50秒的网络数据流量状况。Shape控件的高度为当前网络数据流量大小(1=1k,此程序中最大显示为2M)。

3、主要代码(函数、类型说明请参看第二章第二节)

①公用变量:

Dim TotelRecv As Long        ‘当前接收的数据字节

Dim TotelSend As Long        ‘当前发送的数据字节

Dim LastRecv As Long         ‘之前接收的数据字节

Dim LastSend As Long         ‘之前发送的数据字节

Dim CurStream As Double    ‘当前的传输速率

Dim MaxStream As Double   ‘最大传输速率

Dim NewArray(49) As Long  ‘Shape控件的高度

②窗体载入时:

Timer1.Enabled = False               ‘不允许Timer控件运行

LastRecv = 0: LastSend = 0         ‘设置之前接收、发送的数据字节

CurStream = 0: MaxStream = 0    ‘设置当前的传输速率、最大传输速率

For i = 0 To 49                           ‘设置Shape控件的初始高度

NewArray(i) = 0

Next

For i = 1 To 49                           ‘载入Shape控件

Load Shape(i)

Next

For i = 0 To 49                           ‘设置Shape控件

Shape(i).Width = 100                          ‘宽度

Shape(i).Height = NewArray(i)            ‘高度

Shape(i).Top = 2000 - NewArray(i)     ‘与容器顶端的距离

Shape(i).Left = (49 - i) * 100                     ‘与容器左端的距离

Shape(i).Visible = True                       ‘可见

Next

③按下“开始”按钮:

TotelRecv = 0: TotelSend = 0        ‘设置当前接收、发送的数据字节

LenIfT = Len(ifT)

rvalue = GetIfTable(ifT, LenIfT, True)  ‘调用函数GetIfTable

For i = 0 To ifT.dwNumEntries – 1             ‘枚举每个网卡

If ifT.MIB_Table(i).dwType = 6 Then         ‘只对以太网卡类型进行统计

TotelRecv = TotelRecv + ifT.MIB_Table(i).dwInOctets      ‘当前接收的数据字节

TotelSend = TotelSend + ifT.MIB_Table(i).dwOutOctets    ‘当前发送的数据字节

End If

Next

CurStream = Format(CDbl(TotelRecv + TotelSend - LastRecv - LastSend) / (CDbl(1024)), "0000.00")         ‘当前流量为当前接收和发送数据大小减去之前接收和发送数据大小。这里获得的实际仅为当前接收和发送数据大小,不显示。

LastRecv = TotelRecv: LastSend = TotelSend      ‘设置之前接收、发送的数据字节

Timer1.Enabled = True         ‘允许Timer控件运行,开始正式进行数据统计

Command1.Enabled = False: Command2.Enabled = True

④Timer控件启动:

TotelRecv = 0: TotelSend = 0

LenIfT = Len(ifT)

rvalue = GetIfTable(ifT, LenIfT, True)

For i = 0 To ifT.dwNumEntries – 1

If ifT.MIB_Table(i).dwType = 6 Then

TotelRecv = TotelRecv + ifT.MIB_Table(i).dwInOctets

TotelSend = TotelSend + ifT.MIB_Table(i).dwOutOctets

End If

Next

LabelInfo1.Caption = TotelRecv           ‘显示当前接收的数据字节

LabelInfo2.Caption = TotelSend           ‘显示当前发送的数据字节

If LastRecv <> 0 And LastSend <> 0 Then

CurStream = Format(CDbl(TotelRecv + TotelSend - LastRecv - LastSend) / (CDbl(1024)), "0000.00")

For i = 49 To 1 Step -1                ‘设置Shape控件的高度

NewArray(i) = NewArray(i - 1)

Next

NewArray(0) = CLng(CurStream)

Call DrawStream                         ‘显示柱状图

End If

LabelInfo3.Caption = CurStream          ‘当前的传输速率

If CurStream > MaxStream Then         ‘设置最大传输速率

MaxStream = CurStream

LabelInfo4.Caption = MaxStream

End If

LastRecv = TotelRecv: LastSend = TotelSend      ‘设置之前接收、发送的数据字节

⑤绘制柱状图

Private Sub DrawStream()

For i = 0 To 49

Shape(i).Top = 2000 - NewArray(i)      ‘Shape控件的顶端距

Shape(i).Height = NewArray(i)            ‘Shape控件的高度

Next

End Sub

4、程序运行截图

第四节 实例二:探测到某个IP地址经过的路由列表

计算机在Internet中传递信息时,并不能直接从某一主机上得到去往另一主机的路径,必须通过路由将信息传到主机。发送ICMP报时,ICMP报头中包含了一个TTL设置,报文每当经过一个路由,TTL值相应的减1。当请求报文在传输过程中超时,即TTL被减为0,则该路由器返回一个目标不可达到报文;否则在TTL未被减少到0时,报文到达目标主机,则目标主机返回回应报文,表示数据可以正常到达。我们可以利用此原理,开始时将TTL设置为1,然后发出ICMP报,获得响应,检验地址是否是目标主机IP地址,是目标主机的话,表示到达目标主机;不是的话,返回的地址就是最后到达的路由器的地址,然后将TTL设置为2,重复以上过程,直至TTL设置为255。

在这个例子中,将使用第二章第十九节所用到的函数、类型及常量(请参看第二章第十九节中的介绍),但对IcmpSendEcho函数声明作一点变化。

Private Declare Function IcmpSendEcho Lib "icmp.dll" ( _

ByVal IcmpHandle As Long, ByVal DestinationAddress As Long, _

ByVal RequestData As String, ByVal RequestSize As Long, _

RequestOptions As IP_OPTION_INFORMATION, ReplyBuffer As ICMP_ECHO_REPLY, _

ByVal ReplySize As Long, ByVal Timeout As Long) As Long

其中RequestOptions是指向IP头请求选项的IP_OPTION_INFORMATION类型的指针,可以为空。如果没有具体的要求,那么就设置为Long,在调用的时候传0;如果要设定IP头请求选项,那么这里设置为IP_OPTION_INFORMATION类型,在调用的时候传定义为IP_OPTION_INFORMATION类型的变量。

主要代码如下:

Dim RBuffer As ICMP_ECHO_REPLY

Dim pIOI As IP_OPTION_INFORMATION

Dim Realip As String

IcmpHandle = IcmpCreateFile()    ‘创建一个Icmp句柄

RData = "Hi,Hello!"               ‘

RequestSize = Len(RData)            ‘

DAddr = inet_addr(Trim(Text1.Text))         ‘目标机IP地址的长整数形式

Timeout = 1000                          ‘超时设置,毫秒

ReplySize = Len(RBuffer)            ‘

For i = 1 To 255

pIOI.Ttl = I                         ‘设置TTL值

DoEvents

r = IcmpSendEcho(IcmpHandle, DAddr, RData, RequestSize, pIOI, RBuffer, ReplySize + 8, Timeout)                                             ‘发送Icmp报文

DoEvents

If r <> 1 Then List1.AddItem "错误,终止": Exit For        ‘检测是否出错

Realip = inversaip(RBuffer.Address)                   ‘将长整型IP转为点数格式字符串IP

List1.AddItem i & " IP " & Realip & ":" & RBuffer.RoundTripTime & "ms"

If Realip = Trim(Text1.Text) Then Exit For         ‘比较IP地址,如果相同则到达目标主机

Next

r = IcmpCloseHandle(IcmpHandle)       ‘关闭Icmp句柄

程序运行时截图:

第五章 结束语

Windows自身提供了一些在命令提示符下操作的命令可以获得网络信息,比如Ipconfig、Arp等,都可以使用Iphlpapi.dll的函数来获得同样效果,我们可以使用Iphlpapi函数来制作自己的Ipconfig程序、Arp程序或者别的程序。

以上总结了Iphlpapi.dll所提供大部分函数,虽然以上函数详细的说明和应用都是对Vb程序员的,但是也不失为C程序员的辅助资料。文章中所附代码均是源程序的关键代码,源程序附文后。由于各人的电脑网络情况不一(比如我的电脑就是通过局域网上网的),所附源代码的某些参数是与我的网络情况一致的,请认真查看源代码后,将参数修改成与自己的网络情况一致在做调用。另外,源代码中也未做防错处理,这个也需要注意。

Iphlpapi.dll函数极大的方便了程序员了解网络连接的信息,而且Iphlpapi.dll所提供的函数、功能也在不断增加中,相信在以后的程序开发中,程序员们会更多的使用这个有用的动态链接库。

有意见和建议,请发送邮件到urusei_ad@126.com,我将尽力解答。

 

参考资料:①Microsft  MSDN 2003

②《IP Helper API 使用方法详解》 作者:刘巍


VB部分相关文章推荐

※VB快速读取 TextBox 第 N 行的资料

※VB禁止使用 Alt-Tab 或 Ctrl-Alt-Del

※生成迷宫的程序

※另一方法转换大小写

※VB控件注册 - 利用资源文件将dll、ocx打包进exe文件

※VB利用资源文件进行工作

※[转]vb高效编程(优化)

※VB阳历转阴历

※纯VB代码取得硬盘的物理序列号

※VB获得磁盘的文件系统

※做VB的,经常注册和反注册OCX控件和DLL链

※VB从程序中生成Exe文件

※VB6监视/操作剪贴板示例(VB6.0代码)

※VB6里自动提交/自动填表的一种相对通用的方案

※VB移动没有标题的窗体

※VB随机字母的函数

※VB删除带子文件夹和文件的文件夹

※VB怎样屏蔽 Alt+F4键

※VB 隐藏进程

※vb屏蔽文本框点右键时的弹出菜单

※VB手控Combobox的打开或收起

※在VB中INI文件的读写、删除(对中文支持很好)

※vb全局热键的写法(占很少的资源)

※vb取消文本框的粘贴功能

※VB常用文件操作类

※VB获取特殊文件夹

※VB获取windows各常用目录的函数(模块)

※VB生成太极图

※VB:常用内部函数大全,你会了几个呢?

※vb中SendMessage函数

※精简VB程序的代码

※VB:将数字转换为大写中文

※VB:设定 MsgBox 在若干时间之后若无回应则自动关闭

※VB:读取及设定NumLock/CapsLock/ScrollLock的值

※VB:您知道 Mid$ 函量可以放在 '=' 的左方吗

※VB后台获得按键,并执行自己的函数(非钩子及热键)

※VB:将短文件名格式转成长文件名

※在vb中使用Iphlpapi.dll获取网络信息(上)

※在vb中使用Iphlpapi.dll获取网络信息(下)

更多精彩>>>

在vb中使用Iphlpapi.dll获取网络信息(下)相关推荐

  1. 在vb中使用Iphlpapi.dll获取网络信息(上)

    ※================================================================== ※本连载文章说明: ※1.连载首发于<软件报>(ht ...

  2. Linux编程获取网络信息总结

    Linux下C获取所有可用网卡信息 在Linux下开发网络程序时,经常会遇到需要取本地网络接口名.IP.广播地址 .子网掩码或者MAC地址等信息的需求,最常见的办法是配合宏SIOCGIFHWADDR. ...

  3. crashdumpandroid_Android 中Crash时如何获取异常信息详解及实例

    Android 中Crash时如何获取异常信息详解 前言: 大家都知道,Android应用不可避免的会发生crash,无论你的程序写的多完美,总是无法完全避免crash的发生,可能是由于Android ...

  4. 利用常见的网络命令获取网络信息

    利用常见的网络命令获取网络信息 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 利用常见的网络命令获取网络信息 前言 一.利用ipconfig命令获取本地网络信息 二.实训 ...

  5. 金融信息安全实训——利用常见的网络命令获取网络信息

    实训2 金融信息安全实训--利用常见的网络命令获取网络信息 实训目的 掌握常见网络命令使用方法. 学习使用网络命令嗅探网络信息. 学习使用网络命令判断和处理网络问题. 实训准备及注意事项 1.装有Wi ...

  6. ZMY_HTttpUtils获取网络信息

    //HTttpUtils获取网络信息 httpUtils = new HttpUtils(); httpUtils.send(HttpMethod.GET, path_2, new RequestCa ...

  7. VB中使用表查询法获取CRC16

    VB中CRC16获取方法 1. CRCHi函数实现 Function GetCRCHi(Ind As Long) As ByteGetCRCHi = Choose(Ind + 1, &H0, ...

  8. Android简易实战教程--第四十七话《使用OKhttp回调方式获取网络信息》

    在之前的小案例中写过一篇使用HttpUrlConnection获取网络数据的例子.在OKhttp盛行的时代,当然要学会怎么使用它,本篇就对其基本使用做一个介绍,然后再使用它的接口回调的方式获取相同的数 ...

  9. python中的platform模块获取平台信息

    利用该模块可以获取系统平台与python平台的信息. import platform'''python中,platform模块给我们提供了很多方法去获取操作系统的信息如:import platform ...

最新文章

  1. 看看人家 SpringBoot 的全局异常处理多么优雅...
  2. KDE vs GNOME: 设置,应用和小工具
  3. 一道笔试题(vue,react)
  4. C++11之异步调用
  5. 16位汇编 在代码段中使用数据
  6. ASP.NET组件设计Step by Step(8)
  7. oracle rac 高并发性能_高并发业务下 JVM 涉及的垃圾回收与性能问题分析与定位...
  8. java 查看虚拟机状态_深入理解java虚拟机学习笔记(四)虚拟机性能监控与故障处理工具...
  9. c语言流程图各个框的作用,C语言流程图的三种基本结构
  10. java table注解_java注解简单使用
  11. 体脂手环、体脂秤等产品的体脂测量原理及技术方案分析
  12. excel调用python编程-超简单:用Python让Excel飞起
  13. Oracle同义词总结
  14. 论字母导航的重要性,我们来实现一个联系人字母导航列表吧!
  15. 计算机网络维护日记,计算机网络维护实习日记.doc
  16. 1527编码协议_EV1527解码,我也贡献一个,抗干扰,自适应.....
  17. 山西太原开通直飞巴厘岛航线
  18. iOS热更新实现方式
  19. 驾考一点通维语版_驾考宝典维语版下载-驾考宝典维语版2019下载v1.0.0 安卓版-2265安卓网...
  20. mongrel和mongrel_cluster的区别是什么

热门文章

  1. 熊市投身区块链,程序员的出路在哪里?
  2. 我扒了 6730 个微信用户数据,得出了这些结论......
  3. 阿里全资收购饿了么,估值 95 亿美元
  4. 58 同城 iOS 客户端 iOS11 及 iPhone X 适配实践
  5. sqlexception: default 和 null 不允许作为显式标识值_我都把MySql啃得这么透彻了,你还不进来看一下吗?...
  6. android列表项点击事件,Android 开发 tips(2):监听 Listview 列表项点击事件
  7. java面试题jvm_经典面试题|讲一讲JVM的组成
  8. php将逗号替换成空格,php写的将逗号、空格、回车分隔的字符串转换为数组的函数...
  9. 查看邮箱号是否存在_腾讯企业邮箱--新版本
  10. Recoil 是 React 的状态管理库