bestlong 怕失憶論壇

 

 

搜索
bestlong 怕失憶論壇 論壇 Delphi 用 ICMP 通訊協定探測遠端主機狀態
查看: 3538|回復: 0
go

用 ICMP 通訊協定探測遠端主機狀態 [複製鏈接]

Rank: 9Rank: 9Rank: 9

1#
發表於 2006-6-23 18:16 |只看該作者 |倒序瀏覽 |打印
网络通讯中经常需要确定远程主机是否存活,以决定下一部进行的操作。可以直接使用 ICMP 协议来实现,但是要考虑许多协议细节,实现起来比较麻烦。Windows 自带的 ICMP 库里有现成的函数可以使用,只要在使用前填充相应的数据结构就可以了。

以下是要使用的数据结构。这些结构 MSDN 里有 C 形式的声明,这里给出的是 Delphi 的形式。
  1. //用到的协议数据结构
  2. PIPOptionInfo = ^TIPOptionInfo; // IP 头选项
  3. TIPOptionInfo = packed record
  4.   TTL: Byte;//存活时间
  5.   TOS: Byte;//Type of Service,请求类型
  6.   Flags: Byte;//标志
  7.   OptionsSize: Byte;//选项长度
  8.   OptionsData: PChar;//选项数据
  9. end;
  10. PIcmpEchoReply = ^TIcmpEchoReply;
  11. TIcmpEchoReply = packed record // ICMP 返回信息
  12.   Address: DWORD;//IP地址
  13.   Status: DWORD;//状态
  14.   RTT: DWORD;
  15.   DataSize: Word;//数据长度
  16.   Reserved: Word;//保留
  17.   Data: Pointer;//数据
  18.   Options: TIPOptionInfo;//选项区
  19. end;

  20. //动态库中的函数声明
  21. TIcmpCreateFile = function: THandle; stdcall; //创建ICMP句柄
  22. TIcmpCloseHandle = function(IcmpHandle: THandle): Boolean; stdcall; //关闭ICMP句柄
  23. TIcmpSendEcho = function(IcmpHandle:THandle; DestinationAddress:DWORD;
  24. RequestData:Pointer; RequestSize:Word; RequestOptions:PIPOptionInfo;
  25. ReplyBuffer:Pointer; ReplySize:DWord; Timeout:DWord):DWord; stdcall;//发送ICMP探测数据报

  26. //要用到的变量声明
  27. hICMPDll,hICMP:THandle;
  28. wsaData:TWSADATA;
  29. ICMPCreateFile: TICMPCreateFile;
  30. IcmpCloseHandle: TIcmpCloseHandle;
  31. IcmpSendEcho:TIcmpSendEcho;

  32. //destip: 要探测的远程地址,形如 192.168.1.1
  33. procedure f_CheckOnline(destip:string);
  34. var
  35.   IPOpt:TIPOptionInfo;// 发包的 IP 选项
  36.   IPAddr:DWORD;
  37.   pReqData,pRevData:PChar;
  38.   pIPE:PIcmpEchoReply;// ICMP Echo 回复缓冲区
  39.   FSize: DWORD;
  40.   MyString:string;
  41.   FTimeOut:DWORD;
  42.   BufferSize:DWORD;
  43.   i:integer;
  44. begin
  45.   hICMPdll := LoadLibrary('icmp.dll'); //调取icmp 动态库
  46.   if hICMPDll<>NULL then
  47.   begin
  48.     WSAStartup($101,wsaData);//初始化网络协议栈
  49.     @ICMPCreateFile := GetProcAddress(hICMPdll, 'IcmpCreateFile'); //取动态库中的导出函数
  50.     @IcmpCloseHandle := GetProcAddress(hICMPdll, 'IcmpCloseHandle');
  51.     @IcmpSendEcho := GetProcAddress(hICMPdll, 'IcmpSendEcho');
  52.     hICMP := IcmpCreateFile; //创建 icmp句柄
  53.     IPAddr:= inet_addr(PChar(destip)); //取要探测的远端主机ip地址

  54.     FSize := 40;
  55.     BufferSize := SizeOf(TICMPEchoReply) + FSize;
  56.     GetMem(pRevData,FSize);
  57.     GetMem(pIPE,BufferSize);
  58.     FillChar(pIPE^, SizeOf(pIPE^), 0);
  59.     pIPE^.Data := pRevData;
  60.     MyString := 'Hi, OnLine?';//任意字符串
  61.     pReqData := PChar(MyString);
  62.     FillChar(IPOpt, Sizeof(IPOpt), 0);
  63.     IPOpt.TTL := 64;
  64.     FTimeOut := 500;//等待时长
  65.     i := IcmpSendEcho(hICMP, IPAddr, pReqData, Length(MyString), @IPOpt, pIPE, BufferSize, FTimeOut);//如果有返回,返回值表示收到的回复的个数。如果为0表示没有回复,主机无法到达
  66.     FreeMem(pRevData);
  67.     FreeMem(pIPE);
  68.     IcmpCloseHandle(hicmp);
  69.     FreeLibrary(hICMPdll);//释放动态库
  70.     WSAcleanup();//清理协议栈
  71.   end;
  72. end;
複製代碼
我是雪龍
http://blog.bestlong.idv.tw
http://www.bestlong.idv.tw
‹ 上一主題|下一主題

Archiver|怕失憶論壇

GMT+8, 2024-5-5 05:27 , Processed in 0.011380 second(s), 10 queries .

Powered by Discuz! X1.5

© 2001-2010 Comsenz Inc.