※==================================================================
※本连载文章说明:
※1、连载首发于《软件报》(http://www.sweek.com)2006年21期(2006年5月22日);
※2、此次网上连载采用的是原稿件结构,内容与《软件报》发表略有不同;
※3、谢绝除《软件报》及其相关刊物之外的传统媒体部分或全部转载;
※4、谢绝任何收费媒体、网络转载;
※5、原作者:uruseibest ,blog:http://blog.csdn.net/uruseibest;
※6、如有其它疑问,请联系作者;
※7、如有转载,必须连同本说明一并发表,否则将追究转载者责任。
※======================================================================
第十九节 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、运行时截图:
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/UruseiBest/archive/2006/12/20/1450395.aspx