Поделиться через


Функция 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 .

Этот параметр может иметь значение NULL , если не нужно указывать параметры заголовка IP-адресов.

[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 , чтобы указать, что операция выполняется. Результаты можно получить позже при вызове события, указанного в параметре Event , или при вызове функции обратного вызова в параметре ApcRoutine .

Если возвращаемое значение равно нулю, для получения расширенных сведений об ошибке вызовите Метод 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 Размер объекта ReplyBuffer , указанный в параметре ReplySize , был слишком мал.
Другое Используйте FormatMessage , чтобы получить строку сообщения для возвращенной ошибки.

Комментарии

Функция IcmpSendEcho2 вызывается синхронно, если параметры ApcRoutine или Event имеют значение NULL. При синхронном вызове возвращаемое значение содержит количество ответов, полученных и сохраненных в ReplyBuffer после ожидания времени, указанного в параметре Timeout . Если возвращаемое значение равно нулю, для получения расширенных сведений об ошибке вызовите Метод GetLastError.

Функция IcmpSendEcho2 вызывается асинхронно при указании параметров ApcRoutine или Event . При асинхронном вызове для принятия ответа требуются параметры ReplyBuffer и ReplySize . Данные ответа ICMP копируются в предоставленный ReplyBuffer , и приложение получает сигнал (при указании параметра Event ) или вызывается функция обратного вызова (при указании параметра ApcRoutine ). Приложение должно проанализировать данные, на которые указывает параметр ReplyBuffer , с помощью функции IcmpParseReplies .

Если указан параметр Event , то функция IcmpSendEcho2 вызывается асинхронно. Событие, указанное в параметре Event , сигнализируется (не более одного раза) при поступлении ответа ICMP. Для создания этого объекта события используйте функцию CreateEvent или CreateEventEx .

Если указан параметр ApcRoutine , функция IcmpSendEcho2 вызывается асинхронно. Параметр ApcRoutine должен указывать на определяемую пользователем функцию обратного вызова. Функция обратного вызова, указанная в параметре ApcRoutine , вызывается (не более одного раза) при поступлении ответа ICMP. Вызов функции обратного вызова, указанной в параметре ApcRoutine , сериализуется.

Если указаны параметры Event и ApcRoutine , то событие, указанное в параметре Event , сигнализируется (не более одного раза) при поступлении ответа ICMP, но функция обратного вызова, указанная в параметре ApcRoutine , игнорируется.

Любое приложение, которое асинхронно вызывает функцию IcmpSendEcho2 с помощью параметра ApcRoutine, должно определить PIO_APC_ROUTINE_DEFINED принудительное PIO_APC_ROUTINE для параметра ApcRoutine, а не 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
    );

В функцию обратного вызова передаются следующие параметры:

Параметр Описание
IN PVOID ApcContext Параметр AppContext , передаваемый в функцию IcmpSendEcho2 . Этот параметр может использоваться приложением для идентификации запроса IcmpSendEcho2 , на который отвечает функция обратного вызова.
IN PIO_STATUS_BLOCK IoStatusBlock Указатель на IO_STATUS_BLOCK. Эта переменная содержит окончательное состояние завершения и сведения об операции. Количество байтов, фактически полученных в ответе, возвращается в элементе Informationструктуры IO_STATUS_BLOCK .

Структура IO_STATUS_BLOCK определяется в файле заголовка Wdm.h .
IN ULONG Reserved Этот параметр зарезервирован.

Функция обратного вызова, указанная в параметре 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
Header icmpapi.h
Библиотека Iphlpapi.lib
DLL Iphlpapi.dll в Windows Server 2008, Windows Vista, Windows Server 2003 и Windows XP; Icmp.dll в Windows 2000 Server и Windows 2000 Профессиональная

См. также раздел