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 応答が到着したときに通知されるイベント (最大 1 回)。 このパラメーターを指定する場合は、有効なイベント オブジェクトへのハンドルが必要です。 CreateEvent または CreateEventEx 関数を使用して、このイベント オブジェクトを作成します。
イベントの使用方法の詳細については、「 Event オブジェクト」を参照してください。
[in, optional] ApcRoutine
呼び出し元のスレッドがアラート可能なスレッドにあり、ICMPv4 応答が到着したときに呼び出されるルーチン。 このパラメーターのデータ型を FARPROC ではなくPIO_APC_ROUTINEするには、PIO_APC_ROUTINE_DEFINEDを定義する必要があります。
[in, optional] ApcContext
ICMP 応答が到着したとき、またはエラーが発生したときに ApcRoutine パラメーター (最大 1 回) で指定されたコールバック ルーチンに渡される省略可能なパラメーター。
[in] DestinationAddress
IPAddr 構造体の形式のエコー要求の IPv4 宛先。
[in] RequestData
要求で送信するデータを含むバッファーへのポインター。
[in] RequestSize
RequestData パラメーターが指す要求データ バッファーのサイズ (バイト単位)。
[in, optional] RequestOptions
要求の IP ヘッダー オプションへのポインター ( IP_OPTION_INFORMATION 構造体の形式)。
IP ヘッダー オプションを指定する必要がない場合、このパラメーターは NULL になります。
[out] ReplyBuffer
要求への応答を保持するバッファーへのポインター。 返されると、バッファーには 、ICMP_ECHO_REPLY 構造体の配列の後にオプションとデータが格納されます。
バッファーは、少なくとも 1 つの ICMP_ECHO_REPLY 構造体に加えて、 RequestSize バイトのデータに加え、さらに 8 バイトのデータ (ICMP エラー メッセージのサイズ) を保持するのに十分な大きさである必要があります。
[in] ReplySize
応答バッファーの割り当てられたサイズ (バイト単位)。
バッファーは、少なくとも 1 つの ICMP_ECHO_REPLY 構造体に加えて、 RequestSize バイトのデータに加え、さらに 8 バイトのデータ (ICMP エラー メッセージのサイズ) を保持するのに十分な大きさである必要があります。
[in] Timeout
応答を待機する時間 (ミリ秒単位)。
戻り値
同期的に呼び出されると、 IcmpSendEcho2 関数は 、ReplyBuffer で受信および格納された応答の数を返します。 戻り値が 0 の場合、拡張エラー情報の場合は GetLastError を呼び出します。
非同期で呼び出されると、 IcmpSendEcho2 関数は 0 を返します。 GetLastError の後続の呼び出しでは、操作が進行中であることを示す拡張エラー コード ERROR_IO_PENDINGが返されます。 結果は、後で Event パラメーターで指定されたイベントが通知されるか、 ApcRoutine パラメーターのコールバック関数が呼び出されたときに取得できます。
戻り値が 0 の場合、拡張エラー情報の場合は GetLastError を呼び出します。
関数が失敗した場合、 GetLastError によって返される拡張エラー コードは、次のいずれかの値になります。
リターン コード | 説明 |
---|---|
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 で受信および格納された応答の数が含まれます。 戻り値が 0 の場合、拡張エラー情報の場合は GetLastError を呼び出します。
ApcRoutine パラメーターまたは Event パラメーターが指定されている場合、IcmpSendEcho2 関数は非同期的に呼び出されます。 非同期で呼び出される場合は、応答を受け入れるために ReplyBuffer パラメーターと ReplySize パラメーターが必要です。 ICMP 応答データは、指定された ReplyBuffer にコピーされ、アプリケーションが通知されるか ( Event パラメーターが指定されている場合)、コールバック関数が呼び出されます ( ApcRoutine パラメーターが指定されている場合)。 アプリケーションでは、IcmpParseReplies 関数を使用して、ReplyBuffer パラメーターが指すデータを解析する必要があります。
Event パラメーターが指定されている場合、IcmpSendEcho2 関数は非同期的に呼び出されます。 Event パラメーターで指定されたイベントは、ICMP 応答が到着すると (最大で 1 回) 通知されます。 CreateEvent または CreateEventEx 関数を使用して、このイベント オブジェクトを作成します。
ApcRoutine パラメーターを指定すると、IcmpSendEcho2 関数が非同期的に呼び出されます。 ApcRoutine パラメーターは、ユーザー定義のコールバック関数を指している必要があります。 ApcRoutine パラメーターで指定されたコールバック関数は、ICMP 応答が到着すると (最大で 1 回) 呼び出されます。 ApcRoutine パラメーターで指定されたコールバック関数の呼び出しがシリアル化されます。
Event パラメーターと ApcRoutine パラメーターの両方が指定されている場合、ICMP 応答が到着したときに Event パラメーターで指定されたイベントは通知されます (最大 1 回)。 ApcRoutine パラメーターで指定されたコールバック関数は無視されます。
ApcRoutine パラメーターを使用して IcmpSendEcho2 関数を非同期的に呼び出すアプリケーションでは、ApcRoutine パラメーターのデータ型を FARPROC ではなくPIO_APC_ROUTINEするPIO_APC_ROUTINE_DEFINEDを定義する必要があります。
注意
Icmpapi.h ヘッダー ファイルを含む前に、PIO_APC_ROUTINE_DEFINEDを定義する必要があります。
ApcRoutine によって指されるコールバック関数は、次の構文を使用して VOID 型の関数として定義する必要があります。
typedef
VOID WINAPI
(*PIO_APC_ROUTINE) (
IN PVOID ApcContext,
IN PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG Reserved
);
コールバック関数に渡されるパラメーターには、次のものがあります。
パラメーター | 説明 |
---|---|
IN PVOID ApcContext | IcmpSendEcho2 関数に渡される AppContext パラメーター。 このパラメーターは、コールバック関数が応答している IcmpSendEcho2 要求を識別するためにアプリケーションで使用できます。 |
IN PIO_STATUS_BLOCK IoStatusBlock | IO_STATUS_BLOCKへのポインター。 この変数には、最終的な完了状態と操作に関する情報が含まれます。 応答で実際に受信したバイト数は、IO_STATUS_BLOCK 構造体の Information メンバーで返されます。 IO_STATUS_BLOCK構造体は、ヘッダー ファイルで Wdm.h 定義されます。 |
IN ULONG 予約済み | このパラメーターは予約されています。 |
ApcRoutine パラメーターで指定されたコールバック関数は、IcmpSendEcho2 関数を呼び出すアプリケーションと同じプロセスで実装する必要があります。 コールバック関数が別の DLL 内にある場合は、 IcmpSendEcho2 関数を呼び出す前に DLL を読み込む必要があります。
IcmpSendEcho2 関数は、 からIphlpapi.dll
エクスポートされます。
IPv6 の場合は、 Icmp6CreateFile、 Icmp6SendEcho2、 および Icmp6ParseReplies 関数を使用します。
ヘッダー ファイルの include ディレクティブは、 Iphlpapi.h
ヘッダー ファイルのインクルード ディレクティブの前に配置する Icmpapi.h
必要があります。
例
次の例では、 IcmpSendEcho2 関数を同期的に呼び出します。 この例では、コマンド ラインで指定された IP アドレスに ICMP エコー要求を送信し、最初の応答から受信した情報を出力します。
#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 Professional [デスクトップ アプリ |UWP アプリ] |
サポートされている最小のサーバー | Windows 2000 Server [デスクトップ アプリ |UWP アプリ] |
対象プラットフォーム | Windows |
ヘッダー | icmpapi.h |
Library | Iphlpapi.lib |
[DLL] | Windows Server 2008、Windows Vista、Windows Server 2003、Windows XP で Iphlpapi.dll。Windows 2000 Server と Windows 2000 Professional での Icmp.dll |