يستخدم Delphi ICMP لاكتشاف ما إذا كان المضيف البعيد على قيد الحياة
2005-03-10 JLBNET
في اتصال الشبكة ، غالبًا ما يكون من الضروري تحديد ما إذا كان المضيف البعيد على قيد الحياة لتحديد العملية التي تم تنفيذها في الجزء التالي. يمكن تنفيذها مباشرة باستخدام بروتوكول ICMP ، ولكن يجب النظر في العديد من تفاصيل البروتوكول ، وهو أمر أكثر إزعاجًا للتنفيذ. هناك وظائف جاهزة في مكتبة ICMP التي تأتي مع Windows ، ما عليك سوى ملء بنية البيانات المقابلة قبل الاستخدام.
فيما يلي هيكل البيانات المراد استخدامه. هذه الهياكل MSDN لها إعلانات في النموذج C ، ويتم تقديم شكل Delphi هنا.
// هيكل بيانات البروتوكول المستخدم
PIPOPTIONFO = ^tipoptioninfo ؛
TipoptionInfo = سجل معبأ
TTL: بايت ؛ // وقت الحياة
TOS: byte ؛ // نوع الخدمة ، نوع الطلب
الأعلام: بايت ؛ // اليانصيب
الخيارات: بايت ؛ // طول الخيار
OptionsData: بيانات PRARA ؛ // خيارات
نهاية؛
picmpechoreply = ^ticmpechoreply ؛
ticmpechoreply = سجل معبأة // ICMP معلومات الإرجاع
العنوان: DWORD ؛ // عنوان IP
الحالة: DWORD ؛ // الحالة
RTT: DWORD ؛
Datasize: Word ؛ // طول البيانات
محفوظة: كلمة ؛ // الاحتياطي
البيانات: مؤشر ؛ // البيانات
الخيارات: منطقة خيارات tipoptioninfo ؛ //
نهاية؛
// إعلان الوظيفة في المكتبة الديناميكية
ticmpcreatefile = وظيفة: Thandle ؛
ticmpclosehandle = icmphandle: thandle): stdcall ؛
ticmpsendecho = وظيفة (icmphandle: thandle ؛ DestinationAddress: dword ؛
requestData: طلب ؛
Replybuffer: Pointer ؛
// إعلان متغير لاستخدامه
HICMPDLL ، HICMP: Thandle ؛
Wsadata: Twsadata ؛
icmpcreatefile: ticmpcreatefile ؛
icmpclosehandle: ticmpclosehandle ؛
ICMPSENDECHO: TICMPSENDECHO ؛
// destip: العنوان البعيد الذي سيتم اكتشافه هو 192.168.1.1
الإجراء f_checkonline (destip: string) ؛
var
iPopt: TipoptionInfo ؛ // Package IP Options
ipaddr: dword ؛
Preqdata ، Prevdata: Pchar ؛
الأنابيب: picmpechoreply ؛ // icmp echo Reply Buffer
fsize: dword ؛
mystring: سلسلة.
ftimeout: dword ؛
المخزن المؤقت: 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 ؛
مخازن مؤقت: = sizeof (ticmpechoreply) + fsize ؛
getMem (prevdata ، fsize) ؛
getMem (الأنابيب ، المخزن المؤقت) ؛
FillChar (pipe^، sizeof (pipe^) ، 0) ؛
PIPE^.DATA: = PrevData ؛
mystring: = "مرحبًا ، عبر الإنترنت؟" ؛ // سلسلة تعسفية
preqdata: = pchar (mystring) ؛
FillChar (ipopt ، sizeof (ipopt) ، 0) ؛
ipopt.ttl: = 64 ؛
ftimeout: = 500 ؛ // وقت الانتظار
i: = icmpsendecho (HICMP ، iPaddr ، preqdata ، الطول (myString) ، @ipopt ، الأنابيب ، المخزن المؤقت ، ftimeout) ؛ // إذا كان هناك عائد ، تشير قيمة الإرجاع إلى عدد الردود المستلمة. إذا كان 0 يعني عدم الرد ، فلن يتمكن المضيف من الوصول إليه
Freemem (Prevdata) ؛
Freemem (الأنابيب) ؛
ICMPCloseHandle (HICMP) ؛
Freelibrary (HICMPDLL) ؛ // إطلاق مكتبة ديناميكية
wsacleanup () ؛ // تنظيف كومة البروتوكول
نهاية؛
نهاية؛