icmpSendEcho2 函式 (icmpapi.h)
IcmpSendEcho2 函式會傳送 IPv4 ICMP 回應要求,並在 Event 或 ApcRoutine 為非 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 取得傳回錯誤的訊息字串。 |
備註
如果 ApcRoutine 或 Event 參數為 NULL,IcmpSendEcho2 函式會以同步方式呼叫。 以同步方式呼叫時,傳回值會包含在等候 Timeout 參數中指定的時間之後,接收並儲存在 ReplyBuffer 中的回覆數目。 如果傳回值為零,則針對擴充錯誤資訊呼叫 GetLastError。
指定 ApcRoutine 或 Event 參數時,會以異步方式呼叫 IcmpSendEcho2 函式。 以異步方式呼叫時,需要 ReplyBuffer 和 ReplySize 參數才能接受回應。 ICMP 回應數據會複製到提供的 ReplyBuffer ,並在指定 Event 參數) 時發出 (訊號,或在指定 ApcRoutine 參數時呼叫回呼函式 () 。 應用程式必須使用IcmpParseReplies函式來剖析 ReplyBuffer 參數所指向的數據。
如果指定 Event 參數,則會以異步方式呼叫 IcmpSendEcho2 函式。 在ICMP回應送達時,事件參數中指定的事件最多 (一次) 發出訊號。 使用 CreateEvent 或 CreateEventEx函 式來建立此事件物件。
如果指定 了 ApcRoutine 參數,則會以異步方式呼叫 IcmpSendEcho2 函式。 ApcRoutine 參數應該指向使用者定義的回呼函式。 ApcRoutine 參數中指定的回呼函式最多會在ICMP回應送達時) 呼叫 (一次。 ApcRoutine 參數中指定的回呼函式調用會串行化。
如果同時指定 Event 和 ApcRoutine 參數,則 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,請使用 Icmp6CreateFile、 Icmp6SendEcho2 和 Icmp6ParseReplies 函式。
頭檔的 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 |