IcmpSendEcho 函数 (icmpapi.h)

IcmpSendEcho 函数发送 IPv4 ICMP 回显请求并返回任何回显响应回复。 当超时已过期或回复缓冲区已满时,调用将返回。

语法

IPHLPAPI_DLL_LINKAGE DWORD IcmpSendEcho(
  [in]           HANDLE                 IcmpHandle,
  [in]           IPAddr                 DestinationAddress,
  [in]           LPVOID                 RequestData,
  [in]           WORD                   RequestSize,
  [in, optional] PIP_OPTION_INFORMATION RequestOptions,
  [out]          LPVOID                 ReplyBuffer,
  [in]           DWORD                  ReplySize,
  [in]           DWORD                  Timeout
);

parameters

[in] IcmpHandle

IcmpCreateFile 函数返回的打开句柄。

[in] DestinationAddress

回显请求的 IPv4 目标地址,采用 IPAddr 结构的形式。

[in] RequestData

指向缓冲区的指针,该缓冲区包含请求中要发送的数据。

[in] RequestSize

RequestData 参数指向的请求数据缓冲区的大小(以字节为单位)。

[in, optional] RequestOptions

指向请求的 IP 标头选项的指针,采用 IP_OPTION_INFORMATION 结构的形式。 在 64 位平台上,此参数采用 IP_OPTION_INFORMATION32 结构的形式。

如果不需要指定 IP 标头选项,此参数可能为 NULL 。

[out] ReplyBuffer

一个缓冲区,用于保存对回显请求的任何答复。 返回时,缓冲区包含 ICMP_ECHO_REPLY 结构的数组,后跟答复的选项和数据。 缓冲区应足够大,以容纳至少一个 ICMP_ECHO_REPLY 结构加上 RequestSize 数据字节。

[in] ReplySize

回复缓冲区的分配大小(以字节为单位)。 缓冲区应足够大,以容纳至少一个 ICMP_ECHO_REPLY 结构加上 RequestSize 数据字节。

此缓冲区还应足够大,以容纳 8 个字节的数据, (ICMP 错误消息) 的大小。

[in] Timeout

等待回复的时间(以毫秒为单位)。

返回值

IcmpSendEcho 函数返回存储在 ReplyBuffer 中的ICMP_ECHO_REPLY结构的数目。 每个回复的状态都包含在 结构中。 如果返回值为零,请调用 GetLastError 以获取其他错误信息。

如果函数失败, GetLastError 返回的扩展错误代码可以是以下值之一。

返回代码 说明
ERROR_INSUFFICIENT_BUFFER
传递给系统调用的数据区域太小。 如果 ReplySize 参数指示 ReplyBuffer 参数指向的缓冲区太小,则返回此错误。
ERROR_INVALID_PARAMETER
向该函数传递了无效参数。 如果 IcmpHandle 参数包含无效句柄,则返回此错误。 如果 ReplySize 参数指定的值小于 ICMP_ECHO_REPLY 结构的大小,则也可能返回此错误。
ERROR_NOT_ENOUGH_MEMORY
没有足够的可用内存来完成该操作。
ERROR_NOT_SUPPORTED
不支持该请求。 如果本地计算机上没有 IPv4 堆栈,则返回此错误。
IP_BUF_TOO_SMALL
ReplySize 参数中指定的 ReplyBuffer 的大小太小。
其他
使用 FormatMessage 获取返回错误的消息字符串。

注解

IcmpSendEcho 函数将 ICMP 回显请求发送到指定地址,并返回在 ReplyBuffer 中接收和存储的答复数。 IcmpSendEcho 函数是一个同步函数,在等待 Timeout 参数中指定的响应时间后返回 。 如果返回值为零,请调用 GetLastError 以获取扩展错误信息。

IcmpSendEcho2 和 IcmpSendEcho2Ex 函数是支持异步操作的 IcmpSendEcho 的增强版本。 IcmpSendEcho2Ex 函数还允许指定源 IP 地址。 此功能在具有多个网络接口的计算机上很有用。

对于 IPv6,请使用 Icmp6CreateFile、 Icmp6SendEcho2 和 Icmp6ParseReplies 函数。

IcmpSendEcho 函数是从 Windows 2000 上的 Icmp.dll 导出的。 IcmpSendEcho 函数是从 Windows XP 和更高版本的 Iphlpapi.dll 导出的。 建议不要使用此函数进行 Windows 版本检查。 需要跨 Windows 2000、Windows XP、Windows Server 2003 及更高 Windows 版本的此功能可移植性的应用程序不应静态链接到 Icmp.lib 或 Iphlpapi.lib 文件。 相反,应用程序应检查 icmpSendEcho 在调用 LoadLibrary 和 GetProcAddress 的Iphlpapi.dll 中是否存在 IcmpSendEcho。 否则,应用程序应在调用 LoadLibrary 和 GetProcAddress 的 Icmp.dll 中检查 IcmpSendEcho。

请注意, Iphlpapi.h 头文件的 include 指令必须放在 Icmpapi.h 头文件之前。

示例

以下示例将 ICMP 回显请求发送到命令行中指定的 IP 地址,并打印从第一个响应接收的信息。

#include <winsock2.h>
#include <iphlpapi.h>
#include <icmpapi.h>
#include <stdio.h>

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")

int __cdecl main(int argc, char **argv)  {

    // Declare and initialize variables
    
    HANDLE hIcmpFile;
    unsigned long ipaddr = INADDR_NONE;
    DWORD dwRetVal = 0;
    char SendData[32] = "Data Buffer";
    LPVOID ReplyBuffer = NULL;
    DWORD ReplySize = 0;
    
    // Validate the parameters
    if (argc != 2) {
        printf("usage: %s IP address\n", argv[0]);
        return 1;
    }

    ipaddr = inet_addr(argv[1]);
    if (ipaddr == INADDR_NONE) {
        printf("usage: %s IP address\n", argv[0]);
        return 1;
    }
    
    hIcmpFile = IcmpCreateFile();
    if (hIcmpFile == INVALID_HANDLE_VALUE) {
        printf("\tUnable to open handle.\n");
        printf("IcmpCreatefile returned error: %ld\n", GetLastError() );
        return 1;
    }    

    ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
    ReplyBuffer = (VOID*) malloc(ReplySize);
    if (ReplyBuffer == NULL) {
        printf("\tUnable to allocate memory\n");
        return 1;
    }    
    
    
    dwRetVal = IcmpSendEcho(hIcmpFile, ipaddr, SendData, sizeof(SendData), 
        NULL, ReplyBuffer, ReplySize, 1000);
    if (dwRetVal != 0) {
        PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
        struct in_addr ReplyAddr;
        ReplyAddr.S_un.S_addr = pEchoReply->Address;
        printf("\tSent icmp message to %s\n", argv[1]);
        if (dwRetVal > 1) {
            printf("\tReceived %ld icmp message responses\n", dwRetVal);
            printf("\tInformation from the first response:\n"); 
        }    
        else {    
            printf("\tReceived %ld icmp message response\n", dwRetVal);
            printf("\tInformation from this response:\n"); 
        }    
        printf("\t  Received from %s\n", inet_ntoa( ReplyAddr ) );
        printf("\t  Status = %ld\n", 
            pEchoReply->Status);
        printf("\t  Roundtrip time = %ld milliseconds\n", 
            pEchoReply->RoundTripTime);
    }
    else {
        printf("\tCall to IcmpSendEcho failed.\n");
        printf("\tIcmpSendEcho returned error: %ld\n", GetLastError() );
        return 1;
    }
    return 0;
}    
    

要求

   
最低受支持的客户端 Windows 2000 Professional [仅限桌面应用]
最低受支持的服务器 Windows 2000 Server [仅限桌面应用]
目标平台 Windows
标头 icmpapi.h
Library Iphlpapi.lib
DLL 在 Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP 上 Iphlpapi.dll;Windows 2000 Server 和 Windows 2000 专业版上的 Icmp.dll

另请参阅

GetLastError

ICMP_ECHO_REPLY

IPAddr

IP_OPTION_INFORMATION

IP_OPTION_INFORMATION32

Icmp6CreateFile

Icmp6ParseReplies

Icmp6Sendecho2

IcmpCloseHandle

IcmpCreateFile

IcmpParseReplies

IcmpSendecho2

Icmpsendecho2Ex