标题：IcmpSendEcho
IcmpSendEcho
用于ICMP( [ Internet Control Message Protocol ]Internet控制报文协议)测试,可以直观地测试本地计算机的网络速度,例如Ping就是一个很好的例子.
函数原型
C/C++:DWORD WINAPI IcmpSendEcho(
HANDLE IcmpHandle, 
IPAddr DestinationAddress,
LPVOID RequestData,
WORD RequestSize,
PIP_OPTION_INFORMATION RequestOptions,
LPVOID ReplyBuffer,
DWORD ReplySize,
DWORD Timeout);
VB: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
[in] 传入由IcmpCreateFile创建的一个测试句柄
DestinationAddress
[in] 要测试的IP地址,(需要用到inet_addr() 函数来转换)
RequestData
[in] 需要发送到IP地址的数据,传入指针
RequestSize
[in] 发送的数据大小
RequestOptions
[in] IP头选项,传入指针
ReplyBuffer
[out] 测试后返回的数据,用icmp_echo_reply来接收
ReplySize
[out] ReplyBuffer的大小,一般是 sizeof(icmp_echo_reply) ,VB的话用 Len(ReplyBuffer)
Timeout
[in] 一个以MS为单位的值,代表着一个超时值
需要用到的数据类型:C++ ip_option_information :
typedef struct ip_option_information {
UCHAR Ttl;
UCHAR Tos;
UCHAR Flags;
UCHAR OptionsSize;
PUCHAR OptionsData;
} IP_OPTION_INFORMATION, *PIP_OPTION_INFORMATION;
VB ip_option_information :
Type IP_OPTION_INFORMATION
ttl As Byte ' ‘生存时间
Tos As Byte ' ‘服务类型
Flags As Byte ' ‘IP头标志
OptionsSize As Byte ' ‘选项数据的大小，字节
OptionsData As Long ' ‘指向选项数据的指针
End Type
C++ icmp_echo_reply:
typedef struct icmp_echo_reply {
IPAddr Address;
ULONG Status;
ULONG RoundTripTime;
USHORT DataSize;
USHORT Reserved;
PVOID Data;
struct ip_option_information Options;
} ICMP_ECHO_REPLY, *PICMP_ECHO_REPLY;
VB 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
如何判断测试成功?
你可能会发现,用IcmpSendEcho 测试 127.0.0.1的时候,ICMP_ECHO_REPLY.RoundTripTime 会等于0
  其实,这个函数是没有出错的,即使用Ping 127.0.0.1也是可以的
那么应该怎么去判断这个函数出错呢?
用 ICMP_ECHO_REPLY.Status 来获得测试状态(记住,当Status为0的时候,函数是正确运行的)
常量名值含义IP_SUCCESS0状态是成功。IP_BUF_TOO_SMALL11001答复缓冲区太小。IP_DEST_NET_UNREACHABLE11002目标网络不可达。IP_DEST_HOST_UNREACHABLE11003目标主机不可达。IP_DEST_PROT_UNREACHABLE11004目的地的协议是遥不可及。IP_DEST_PORT_UNREACHABLE11005目标端口不可达。IP_NO_RESOURCES11006IP资源不足是可用的。IP_BAD_OPTION11007指定了错误的IP选项。IP_HW_ERROR11008一个硬件错误。IP_PACKET_TOO_BIG11009包太大。IP_REQ_TIMED_OUT11010请求超时。IP_BAD_REQ11011一个坏的请求。IP_BAD_ROUTE11012一个糟糕的路线。IP_TTL_EXPIRED_TRANSIT11013在传输过程中的生存时间（TTL）的过期。IP_TTL_EXPIRED_REASSEM11014在碎片重组过程中的生存时间过期。IP_PARAM_PROBLEM11015一个参数的问题。IP_SOURCE_QUENCH11016数据报到达太快，处理和数据报可能被丢弃。IP_OPTION_TOO_BIG11017一个IP选项是太大了。IP_BAD_DESTINATION11018一个坏的目的地。IP_GENERAL_FAILURE11050一般故障。这个错误可以返回一些畸形的ICMP数据包
一段C++控制台示例代码:
void Ping(char *pIPAddr)
{
HANDLE iHwnd;
iHwnd=IcmpCreateFile();
IPAddr pAddr;
pAddr=(IPAddr)inet_addr (pIPAddr);
icmp_echo_reply pData;
for(int i=1;i<=LoopSend;i++)
{
IcmpSendEcho(iHwnd,pAddr,NULL,0,NULL,(LPVOID)&pData,sizeof(icmp_echo_reply),0);
if (pData.Status==0)
{
printf("Ping测试返回的结果: Time=%dms TTL=%d \n",(int)pData.RoundTripTime(int)pData.Options.Ttl);
}
else
{
printf("Ping测试失败...\n");
}
}
if (!IcmpCloseHandle(iHwnd)) printf("Close handle has Error!\n");
}