Delphi использует ICMP, чтобы определить, жив ли удаленный хост
2005-03-10 jlbnet
При сетевой связи часто необходимо определить, жив ли удаленный хост, чтобы определить операцию, выполненную в следующей части.可以直接使用ICMP协议来实现,但是要考虑许多协议细节,实现起来比较麻烦。 Windows 自带的ICMP库里有现成的函数可以使用,只要在使用前填充相应的数据结构就可以了。
Ниже приведена структура данных, которая будет использоваться. Эти структуры MSDN имеют объявления в форме C, и форма Delphi приведена здесь.
// используемая структура данных протокола
PipoPtionInfo = ^TipoPtionInfo;
TipoPtionInfo = упакованная запись
TTL: Byte; // Life Time
TOS: Byte; // Тип обслуживания, тип запроса
Флаги: байт; // лотерея
Optionsize: Byte; // Длина опции
OptionsData: pchar; // Data Options
конец;
Picmpechoreply = ^ticmpechoreply;
Ticmpechoreply = упакованная запись // incmp return information
Адрес: DWORD; // IP -адрес
Статус: DWORD; // Статус
RTT: DWORD;
DataSize: Word; // Длина данных
Зарезервировано: слово; // резерв
Данные: указатель; // данные
Варианты: TipoPtionInfo; // Опции Область
конец;
// объявление функций в динамической библиотеке
Ticmpcreatefile = function: thandle;
Ticmpclosehandle = функция (iCmPhandle: Thandle): Boolean;
Ticmpsendecho = function (icmphandle: thandle; destinationAddress: dword;
Запрос: указатель;
Ответить
// Объявление переменной, которая будет использоваться
hicmpdll, hicmp: thandle;
Wsadata: Twsadata;
ICmpcreatefile: ticmpcreatefile;
IcmpCloseHandle:TIcmpCloseHandle;
IcmpSendEcho:TIcmpSendEcho;
// Destip: Удаленный адрес, который должен быть обнаружен как 192.168.1.1
Процедура f_checkonline (destip: string);
вар
IPopt: tipoPtionInfo; // Пакет IP -параметров
IPaddr: dword;
preqdata, prevdata: pchar;
труба: picmpechoreply; // icmp echo reply Buffer
Fsize: dword;
MyString: String;
Ftimeout: dword;
BufferSize: DWORD;
я: целое число;
Начинать
hicmpdll: = loadlibrary ('icmp.dll'); // Нажмите на динамическую библиотеку ICMP
Если hicmpdll <> null, тогда
Начинать
WsaStartup ($ 101, Wsadata); // Инициализировать стек сетевого протокола
@Icmpcreatefile: = getprocaddress (hicmpdll, 'icmpcreatefile'); // пожалуйста функция экспорта в динамической библиотеке
@Icmpclosehandle: = getprocaddress (hicmpdll, 'icmpclosehandle');
@Icmpsendecho: = getprocaddress (hicmpdll, 'icmpsendecho');
hicmp: = icmpcreatefile; // Создать ручку ICMP
IPaddr: = inet_addr (pchar (destip)); // Получить IP -адрес удаленного хоста, который будет обнаружен
Fsize: = 40;
Buffersize: = sizeof (ticmpechoreply) + fsize;
GetMem (prevdata, fsize);
GetMem (труба, буферизация);
FillChar(pIPE^, SizeOf(pIPE^), 0);
труба^.data: = prevdata;
MyString: = 'Привет, онлайн?'; // произвольная строка
preqdata: = pchar (mystring);
Fillchar (ipopt, sizeof (ipopt), 0);
Ipopt.ttl: = 64;
Ftimeout: = 500; // время ожидания
i: = icmpsendecho (hicmp, ipaddr, preqdata, длина (mystring), @ipopt, pipe, buffersize, ftimeout); // Если есть возврат, возвращаемое значение указывает количество полученных ответов. Если 0 не означает ответа, хост не может достичь
Freemem (prevdata);
Freemem (труба);
ICMPCloseHandle (HICMP);
Freeliabrary (hicmpdll); // Выпуск динамической библиотеки
Wsacleanup (); // Очистить стек протоколов
конец;
конец;