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 以获取扩展错误信息。

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

对于 IPv6,请使用 Icmp6CreateFileIcmp6SendEcho2Icmp6ParseReplies 函数。

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