共用方式為


icmpSendEcho2 函式 (icmpapi.h)

IcmpSendEcho2 函式會傳送 IPv4 ICMP 回應要求,並在 EventApcRoutine 為非 NULL) 時 (立即傳回,或在指定的逾時之後傳回 。ReplyBuffer 包含ICMP回應回應,如果有的話。

語法

IPHLPAPI_DLL_LINKAGE DWORD IcmpSendEcho2(
  [in]           HANDLE                 IcmpHandle,
  [in, optional] HANDLE                 Event,
  [in, optional] PIO_APC_ROUTINE        ApcRoutine,
  [in, optional] PVOID                  ApcContext,
  [in]           IPAddr                 DestinationAddress,
  [in]           LPVOID                 RequestData,
  [in]           WORD                   RequestSize,
  [in, optional] PIP_OPTION_INFORMATION RequestOptions,
  [out]          LPVOID                 ReplyBuffer,
  [in]           DWORD                  ReplySize,
  [in]           DWORD                  Timeout
);

參數

[in] IcmpHandle

ICMPCreateFile 函式所傳回的開啟句柄。

[in, optional] Event

當ICMP回應送達時,最多 (一次發出訊號的事件) 。 如果指定此參數,則需要有效事件物件的句柄。 使用 CreateEvent 或 CreateEventEx 式來建立此事件物件。

如需使用事件的詳細資訊,請參閱 事件物件

[in, optional] ApcRoutine

當呼叫線程位於可警示的線程中,且ICMPv4 回復送達時所呼叫的例程。 PIO_APC_ROUTINE_DEFINED 必須定義,才能強制此參數的數據類型 PIO_APC_ROUTINE 而非 FARPROC

[in, optional] ApcContext

傳遞至 ApcRoutine 參數中所指定回呼例程的選擇性 (參數,最多一次) ICMP 回應送達時,或發生錯誤。

[in] DestinationAddress

回應要求的 IPv4 目的地,格式為 IPAddr 結構。

[in] RequestData

緩衝區的指標,其中包含要求中要傳送的數據。

[in] RequestSize

RequestData 參數所指向之要求數據緩衝區的大小,以位元組為單位。

[in, optional] RequestOptions

要求IP標頭選項的指標,格式為 IP_OPTION_INFORMATION 結構。

如果不需要指定任何IP標頭選項,此參數可能是 NULL

[out] ReplyBuffer

緩衝區的指標,用來保存對要求的任何回復。 傳回時,緩衝區包含 ICMP_ECHO_REPLY 結構的陣列,後面接著選項和數據。

緩衝區必須夠大,才能保存至少一個 ICMP_ECHO_REPLY 結構,加上 RequestSize 位元組的數據,再加上額外的 8 個字節數據, (ICMP 錯誤訊息的大小) 。

[in] ReplySize

回復緩衝區的配置大小,以位元組為單位。

緩衝區必須夠大,才能保存至少一個 ICMP_ECHO_REPLY 結構,加上 RequestSize 位元組的數據,再加上額外的 8 個字節數據, (ICMP 錯誤訊息的大小) 。

[in] Timeout

等候回復的毫秒時間。

傳回值

以同步方式呼叫時, IcmpSendEcho2 函式會傳回接收並儲存在 ReplyBuffer 中的回復數目。 如果傳回值為零,則針對擴充錯誤資訊呼叫 GetLastError

以異步方式呼叫時, IcmpSendEcho2 函式會傳回零。 後續呼叫 GetLastError傳回擴充的錯誤碼ERROR_IO_PENDING,以指出作業正在進行中。 呼叫 ApcRoutine 參數中的呼函式時,稍後可以擷取結果。

如果傳回值為零,則針對擴充錯誤資訊呼叫 GetLastError

如果函式失敗, GetLastError 傳回的擴充錯誤碼可以是下列其中一個值。

傳回碼 Description
ERROR_INVALID_PARAMETER 無效的參數已傳遞至 函式。 如果 IcmpHandle 參數包含無效的句柄,就會傳回此錯誤。 如果 ReplySize 參數指定的值小於 ICMP_ECHO_REPLY 結構的大小,也可以傳回此錯誤。
ERROR_IO_PENDING 作業正在進行中。 這個值是由 IcmpSendEcho2 的成功異步呼叫所傳回,而且不是錯誤的指示。
ERROR_NOT_ENOUGH_MEMORY 可用的記憶體不足,無法完成作業。
ERROR_NOT_SUPPORTED 不支援此要求。 如果本機計算機上沒有IPv4堆疊,則會傳回此錯誤。
IP_BUF_TOO_SMALL ReplySize 參數中指定的 ReplyBuffer 大小太小。
其他 使用 FormatMessage 取得傳回錯誤的訊息字串。

備註

如果 ApcRoutineEvent 參數為 NULL,IcmpSendEcho2 函式會以同步方式呼叫。 以同步方式呼叫時,傳回值會包含在等候 Timeout 參數中指定的時間之後,接收並儲存在 ReplyBuffer 中的回覆數目。 如果傳回值為零,則針對擴充錯誤資訊呼叫 GetLastError

指定 ApcRoutineEvent 參數時,會以異步方式呼叫 IcmpSendEcho2 函式。 以異步方式呼叫時,需要 ReplyBufferReplySize 參數才能接受回應。 ICMP 回應數據會複製到提供的 ReplyBuffer ,並在指定 Event 參數) 時發出 (訊號,或在指定 ApcRoutine 參數時呼叫回呼函式 () 。 應用程式必須使用IcmpParseReplies函式來剖析 ReplyBuffer 參數所指向的數據。

如果指定 Event 參數,則會以異步方式呼叫 IcmpSendEcho2 函式。 在ICMP回應送達時,事件參數中指定的事件最多 (一次) 發出訊號。 使用 CreateEvent 或 CreateEventEx 式來建立此事件物件。

如果指定 了 ApcRoutine 參數,則會以異步方式呼叫 IcmpSendEcho2 函式。 ApcRoutine 參數應該指向使用者定義的回呼函式。 ApcRoutine 參數中指定的回呼函式最多會在ICMP回應送達時) 呼叫 (一次。 ApcRoutine 參數中指定的回呼函式調用會串行化。

如果同時指定 EventApcRoutine 參數,則 Event 參數中指定的事件最多會在 ICMP 回應送達時 () 一次,但會忽略 ApcRoutine 參數中指定的回呼函式。

任何使用 ApcRoutine 參數異步呼叫 IcmpSendEcho2 函式的應用程式都必須定義PIO_APC_ROUTINE_DEFINED,以強制 ApcRoutine 參數的數據類型PIO_APC_ROUTINE而非 FARPROC

注意

PIO_APC_ROUTINE_DEFINED 必須在 包含Icmpapi.h 頭檔之前定義。

ApcRoutine 所指向的回調函式必須定義為 VOID 類型的函式,其語法如下:

typedef
VOID WINAPI
(*PIO_APC_ROUTINE) (
    IN PVOID ApcContext,
    IN PIO_STATUS_BLOCK IoStatusBlock,
    IN ULONG Reserved
    );

傳遞至回調函式的參數包括下列各項:

參數 Description
IN PVOID ApcContext 傳遞至 IcmpSendEcho2 函式的 AppContext 參數。 應用程式可以使用此參數來識別回呼函式回應的 IcmpSendEcho2 要求。
IN PIO_STATUS_BLOCK IoStatusBlock IO_STATUS_BLOCK的指標。 此變數包含最終完成狀態和作業的相關信息。 在IO_STATUS_BLOCK結構的信息成員中,會傳回回復中實際收到的位元元組數目。

IO_STATUS_BLOCK結構定義於Wdm.h頭檔中。
在 ULONG 中保留 此參數已保留備用。

ApcRoutine 參數中指定的回調函式必須與呼叫 IcmpSendEcho2 函式的應用程式在相同的進程中實作。 如果回呼函式位於個別的 DLL 中,則應該先載入 DLL,再呼叫 IcmpSendEcho2 函式。

IcmpSendEcho2 函式會從 Iphlpapi.dll導出。

針對 IPv6,請使用 Icmp6CreateFileIcmp6SendEcho2Icmp6ParseReplies 函式。

頭檔的 include 指示詞 Iphlpapi.h 必須放在頭檔的第一個 Icmpapi.h 之前。

範例

下列範例會同步呼叫 IcmpSendEcho2 函式。 此範例會將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;
    DWORD dwError = 0;
    char SendData[] = "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;
    }

    // Allocate space for a single reply.
    ReplySize = sizeof (ICMP_ECHO_REPLY) + sizeof (SendData) + 8;
    ReplyBuffer = (VOID *) malloc(ReplySize);
    if (ReplyBuffer == NULL) {
        printf("\tUnable to allocate memory for reply buffer\n");
        return 1;
    }

    dwRetVal = IcmpSendEcho2(hIcmpFile, NULL, NULL, NULL,
                             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  ", pEchoReply->Status);
        switch (pEchoReply->Status) {
        case IP_DEST_HOST_UNREACHABLE:
            printf("(Destination host was unreachable)\n");
            break;
        case IP_DEST_NET_UNREACHABLE:
            printf("(Destination Network was unreachable)\n");
            break;
        case IP_REQ_TIMED_OUT:
            printf("(Request timed out)\n");
            break;
        default:
            printf("\n");
            break;
        }

        printf("\t  Roundtrip time = %ld milliseconds\n",
               pEchoReply->RoundTripTime);
    } else {
        printf("Call to IcmpSendEcho2 failed.\n");
        dwError = GetLastError();
        switch (dwError) {
        case IP_BUF_TOO_SMALL:
            printf("\tReplyBufferSize too small\n");
            break;
        case IP_REQ_TIMED_OUT:
            printf("\tRequest timed out\n");
            break;
        default:
            printf("\tExtended error returned: %ld\n", dwError);
            break;
        }
        return 1;
    }
    return 0;
}

規格需求

需求
最低支援的用戶端 Windows 2000 專業版 [傳統型應用程式 |UWP 應用程式]
最低支援的伺服器 Windows 2000 Server [傳統型應用程式 |UWP 應用程式]
目標平台 Windows
標頭 icmpapi.h
程式庫 Iphlpapi.lib
Dll windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP 上的 Iphlpapi.dll;Windows 2000 Server 和 Windows 2000 專業版上的 Icmp.dll

另請參閱