如何用delphi编写ping.exe程序(200分)

  • 主题发起人 主题发起人 shangjintong
  • 开始时间 开始时间
S

shangjintong

Unregistered / Unconfirmed
GUEST, unregistred user!
如何用delphi编写ping.exe程序
 
来自:garden_wood 时间:2000-6-22 8:50:15 ID:269817 <br>see it:<br><br>Delphi编程实现Ping操作<br><br>&nbsp;  张泰立<br><br>&nbsp;  使用过网络的用户都熟悉“Ping”这个指令,它是一个DOS下的可执行文件,一般用<br>&nbsp;它来检查网络连接的好坏程度。其基本原理是利用TCP/IP协议包中ICMP协议中的一个功<br>&nbsp;能,即向所指定的计算机发送一个请求,收到请求的计算机返回一个应答,借此来判断该<br>&nbsp;计算机是否在网上运行或者检查网络连接是否稳定可靠。在Ping程序执行过程中,双方<br>&nbsp;计算机所耗费的资源都很少,因此,它是一个非常实用的工具。<br><br><br>&nbsp;  我们可以通过编程来实现“Ping”操作,对其加以改进,使之具有Windows的界面<br>&nbsp;风格,显示比DOS更加直观。<br><br>&nbsp;  首先,对编程中需要的动态链接库作一简要说明:在Windows的System目录下,你<br>&nbsp;可以找到Icmp.dll文件,该动态链接库提供了ICMP协议的所有功能,我们的编程就建立<br>&nbsp;在<br><br>&nbsp;  对该动态链接库的调用上。<br><br>&nbsp;  Icmp.dll文件内的调用函数说明如下:<br><br>&nbsp;  1、IcmpCreateFile<br><br>&nbsp;  打开一个句柄,通过该句柄你可以发送ICMP的请求回送报文。<br><br>&nbsp;  2、IcmpCloseHandle<br><br>&nbsp;  关闭你通过IcmpCreateFile函数打开的句柄。<br><br>&nbsp;  3、IcmpSendEcho<br><br>&nbsp;  通过你打开的句柄发送ICMP请求,在超时或应答报文接收后返回。其参数基本上和<br>&nbsp;它的帧结构一致,可参看下面的程序部分,其具体含意你可以参看有关ICMP协议的书<br>&nbsp;籍。<br><br>&nbsp;  初步了解了上述的三个函数后,我们就可以开始编程了。<br><br>&nbsp;  首先,我们的程序运行后应该有如图1所示的基本功能。为此,我们可先在Delphi的<br>&nbsp;窗口中放入右上图中所示的控件,如按钮、编辑框和文本显示框等。<br><br>&nbsp;  (G72.JPG)<br><br>&nbsp;  例程运行示意图<br><br>&nbsp;  然后,在程序的开始部分(FormCreate)对WinSocket进行初始化,其作用是申明<br>&nbsp;使用的版本信息,同时调入Icmp.dll库。<br><br>&nbsp;  type<br><br>&nbsp;   PIPOptionInformation = ^TIPOptionInformation;<br><br>&nbsp;   TIPOptionInformation = packed record<br><br>&nbsp;   TTL: Byte;<br><br>&nbsp;   TOS: Byte;<br><br>&nbsp;   Flags: Byte;<br><br>&nbsp;   OptionsSize: Byte;<br><br>&nbsp;   OptionsData: PChar;<br><br>&nbsp;   end;<br><br>&nbsp;   PIcmpEchoReply = ^TIcmpEchoReply;<br><br>&nbsp;   TIcmpEchoReply = packed record<br><br>&nbsp;   Address: DWORD;<br><br>&nbsp;   Status: DWORD;<br><br>&nbsp;   RTT: DWORD;<br><br>&nbsp;   DataSize: Word;<br><br>&nbsp;   Reserved: Word;<br><br>&nbsp;   Data: Pointer;<br><br>&nbsp;   Options: TIPOptionInformation;<br><br>&nbsp;   end;<br><br>&nbsp;   TIcmpCreateFile = function: THandle; stdcall;<br><br>&nbsp;   TIcmpCloseHandle = function(IcmpHandle: THandle): Boolean;<br>&nbsp;stdcall;<br><br>&nbsp;   TIcmpSendEcho = function(IcmpHandle:THandle;<br><br>&nbsp;   DestinationAddress: DWORD;<br><br>&nbsp;   RequestData: Pointer;<br><br>&nbsp;   RequestSize: Word;<br><br>&nbsp;   RequestOptions: PIPOptionInformation;<br><br>&nbsp;   ReplyBuffer: Pointer;<br><br>&nbsp;   ReplySize: DWord;<br><br>&nbsp;   Timeout: DWord<br><br>&nbsp;   ): DWord; stdcall;<br><br>&nbsp;   TMyPing = class(TForm)<br><br>&nbsp;   Panel1: TPanel;<br><br>&nbsp;   Label1: TLabel;<br><br>&nbsp;   PingEdit: TEdit;<br><br>&nbsp;   ExeBtn: TButton;<br><br>&nbsp;   Button2: TButton;<br><br>&nbsp;   Button3: TButton;<br><br>&nbsp;   StatusShow: TMemo;<br><br>&nbsp;   procedure Button3Click(Sender: TObject);<br><br>&nbsp;   procedure FormCreate(Sender: TObject);<br><br>&nbsp;   procedure ExeBtnClick(Sender: TObject);<br><br>&nbsp;   private<br><br>&nbsp;   { Private declarations }<br><br>&nbsp;   hICMP: THANDLE;<br><br>&nbsp;   IcmpCreateFile : TIcmpCreateFile;<br><br>&nbsp;   IcmpCloseHandle: TIcmpCloseHandle;<br><br>&nbsp;   IcmpSendEcho: TIcmpSendEcho;<br><br>&nbsp;   public<br><br>&nbsp;   { Public declarations }<br><br>&nbsp;  end;<br><br>&nbsp;  procedure TMyPing.FormCreate(Sender: TObject);<br><br>&nbsp;  var<br><br>&nbsp;   WSAData: TWSAData;<br><br>&nbsp;   hICMPdll: HMODULE;<br><br>&nbsp;  begin<br><br>&nbsp;?<br>&nbsp;   // Load the icmp.dll stuff<br><br>&nbsp;   hICMPdll := LoadLibrary('icmp.dll');<br><br>&nbsp;   @ICMPCreateFile := GetProcAddress(hICMPdll, 'IcmpCreateFile');<br><br>&nbsp;   @IcmpCloseHandle := GetProcAddress(hICMPdll,<br>&nbsp;'IcmpCloseHandle');<br><br>&nbsp;   @IcmpSendEcho := GetProcAddress(hICMPdll, 'IcmpSendEcho');<br><br>&nbsp;   hICMP := IcmpCreateFile;<br><br>&nbsp;   StatusShow.Text := '';<br><br>&nbsp;   StatusShow.Lines.Add('目的IP地址 字节数 返回时间(毫秒)');<br><br>&nbsp;  end;<br><br>&nbsp;  接下来,就要进行如下所示的Ping操作的实际编程过程了。<br><br>&nbsp;  procedure TMyPing.ExeBtnClick(Sender: TObject);<br><br>&nbsp;  var<br><br>&nbsp;   IPOpt:TIPOptionInformation;// IP Options for packet to send<br><br>&nbsp;   FIPAddress:DWORD;<br><br>&nbsp;   pReqData,pRevData:PChar;<br><br>&nbsp;   pIPE:PIcmpEchoReply;// ICMP Echo reply buffer<br><br>&nbsp;   FSize: DWORD;<br><br>&nbsp;   MyString:string;<br><br>&nbsp;   FTimeOut:DWORD;<br><br>&nbsp;   BufferSize:DWORD;<br><br>&nbsp;  begin<br><br>&nbsp;   if PingEdit.Text &lt;&gt; '' then<br><br>&nbsp;   begin<br><br>&nbsp;   FIPAddress := inet_addr(PChar(PingEdit.Text));<br><br>&nbsp;   FSize := 40;<br><br>&nbsp;   BufferSize := SizeOf(TICMPEchoReply) + FSize;<br><br>&nbsp;   GetMem(pRevData,FSize);<br><br>&nbsp;   GetMem(pIPE,BufferSize);<br><br>&nbsp;   FillChar(pIPE^, SizeOf(pIPE^), 0);<br><br>&nbsp;   pIPE^.Data := pRevData;<br><br>&nbsp;   MyString := 'Hello,World';<br><br>&nbsp;   pReqData := PChar(MyString);<br><br>&nbsp;   FillChar(IPOpt, Sizeof(IPOpt), 0);<br><br>&nbsp;   IPOpt.TTL := 64;<br><br>&nbsp;   FTimeOut := 4000;<br><br>&nbsp;   IcmpSendEcho(hICMP, FIPAddress, pReqData, Length(MyString),<br>&nbsp;@IPOpt, pIPE, BufferSize, FTimeOut);<br><br>&nbsp;   if pReqData^ = pIPE^.Options.OptionsData^ then<br><br>&nbsp;   begin<br><br>&nbsp;   StatusShow.Lines.Add(PChar(PingEdit.Text) + ' '<br>&nbsp;+IntToStr(pIPE^.DataSize) + ' ' +IntToStr(pIPE^.RTT));<br><br>&nbsp;   end;<br><br>&nbsp;   begin<br><br>&nbsp;   StatusShow.Lines.Add(PChar(PingEdit.Text) + ' '<br>&nbsp;+IntToStr(pIPE^.DataSize) + ' ' +IntToStr(pIPE^.RTT));<br><br>&nbsp;   end;<br><br>&nbsp;   FreeMem(pRevData);<br><br>&nbsp;   FreeMem(pIPE);<br><br>&nbsp;   end<br><br>&nbsp;  end;<br><br>&nbsp;  通过上面的编程,我们就实现了Ping功能的界面操作。实际上,ICMP协议的功能还<br>&nbsp;有很<br><br>&nbsp;  多,都可以通过对Icmp.dll的函数调用来实现。<br><br><br><br>&nbsp;<br>&nbsp;<br>
 
调用icmp.dll中的函数
 
ICS中有个PING的控件。
 
以下是我从www.delphi3000.com上paste来的,用icmp.dll,也可以用ics里的ping,不错<br>Question/Problem/Abstract:<br>How to create the PING functionality from ICMP.DLL <br>Answer:<br>A Little PING application. <br><br>Once a received a email from a VB developer asking how we can ping a host from a delphi application. <br>But Whats&amp;acute;s PING ? <br>Ping is a protocol for testing whether a particular computer is connected to the Internet by sending a packet to its Internet Protocol (IP) address and waiting for a response. <br>We build a little application that implements the ping funcionality. To do that we use the ICMP protocol implemented on ICMP.DLL. <br>ICMP - Internet Control Message Protocol. The ICMP delivers error and control messages from hosts to the requesters. &nbsp;An ICMP test can determine whether a destination is reachable and responding. <br><br>1. open Delphi; <br>2. On a new project, Add a Tbutton, a Tedit and a Tmemo in your form; <br>3. Insert the “winsock” in the uses clausule; <br>4. Declare a record constant to put the IP head: <br>type <br>&nbsp; IPINFO = record <br>&nbsp; Ttl &nbsp; &nbsp; :char; <br>&nbsp; Tos &nbsp; &nbsp; :char; <br>&nbsp; IPFlags :char; <br>&nbsp; OptSize :char; <br>&nbsp; Options :^char; <br>end; <br>5. Declare a record constant to put the ICMP package: <br>type <br>ICMPECHO = record <br>Source &nbsp;:longint; <br>Status &nbsp;:longint; <br>RTTime &nbsp;:longint; <br>DataSize:Shortint; <br>Reserved:Shortint; <br>pData &nbsp; :^variant; <br>i_ipinfo:IPINFO; <br>end; <br><br>6. Declare the functions/procedures that you wiil call from ICMP.DLL <br>TIcmpCreateFile = function():integer; {$IFDEF WIN32} stdcall; {$ENDIF} <br>TIcmpCloseHandle = procedure(var handle:integer);{$IFDEF WIN32} stdcall; {$ENDIF} <br>TIcmpSendEcho = function(var handle:integer; endereco:DWORD; buffer:variant; tam:WORD; IP:IPINFO; ICMP:ICMPECHO; tamicmp:DWORD; tempo:DWORD):DWORD;{$IFDEF WIN32} stdcall; {$ENDIF} <br><br>7. In the Tbutton&amp;acute;s Onclick event insert this code:: <br><br>procedure TForm1.Button1Click(Sender: TObject); <br>var <br>wsadt : wsadata; <br>icmp &nbsp;:icmpecho; <br>HNDicmp : integer; <br>hndFile :integer; <br>Host :PHostEnt; <br>Destino :in_addr; <br>Endereco :^DWORD; <br>IP : ipinfo; <br>Retorno :integer; <br>dwRetorno :DWORD; <br>x :integer; <br><br>IcmpCreateFile : TIcmpCreateFile; <br>IcmpCloseHandle : TIcmpCloseHandle; <br>IcmpSendEcho : TIcmpSendEcho; <br><br>begin <br>&nbsp; &nbsp; if (edit1.Text = '') then begin <br>&nbsp; &nbsp; &nbsp;Application.MessageBox('Enter a HostName ro a IP Adress', <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'Error', MB_OK); <br>&nbsp; &nbsp; &nbsp;exit; <br>&nbsp; &nbsp; end; <br>&nbsp; &nbsp; HNDicmp := LoadLibrary('ICMP.DLL'); <br>&nbsp; &nbsp; if (HNDicmp &lt;&gt; 0) then begin <br>&nbsp; &nbsp; &nbsp; &nbsp;@IcmpCreateFile := GetProcAddress(HNDicmp,'IcmpCreateFile'); <br>&nbsp; &nbsp; &nbsp; &nbsp;@IcmpCloseHandle := GetProcAddress(HNDicmp,'IcmpCloseHandle'); <br>&nbsp; &nbsp; &nbsp; &nbsp;@IcmpSendEcho := GetProcAddress(HNDicmp,'IcmpSendEcho'); <br>&nbsp; &nbsp; &nbsp; &nbsp;if (@IcmpCreateFile=nil) or (@IcmpCloseHandle=nil) or (@IcmpSendEcho=nil) then &nbsp;begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Application.MessageBox('Error getting ICMP Adress’,'Error', MB_OK); <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FreeLibrary(HNDicmp); <br>&nbsp; &nbsp; &nbsp; &nbsp;end; <br>&nbsp; &nbsp; end; <br>&nbsp; &nbsp; Retorno := WSAStartup($0101,wsadt); <br><br>&nbsp; &nbsp; if (Retorno &lt;&gt; 0) then begin <br>&nbsp; &nbsp; &nbsp; Application.MessageBox('Can&amp;acute;t Load WinSockets','WSAStartup', MB_OK); <br>&nbsp; &nbsp; &nbsp; WSACleanup(); <br>&nbsp; &nbsp; &nbsp; FreeLibrary(HNDicmp); <br>&nbsp; &nbsp; end; <br><br>&nbsp; &nbsp; Destino.S_addr := inet_addr(Pchar(Edit1.text)); <br>&nbsp; &nbsp; if (Destino.S_addr = 0) then begin <br>&nbsp; &nbsp; &nbsp; &nbsp;Host := GetHostbyName(PChar(Edit1.text)); <br>&nbsp; &nbsp; &nbsp; &nbsp;end <br>&nbsp; &nbsp; else begin <br>&nbsp; &nbsp; &nbsp; &nbsp;Host := GetHostbyAddr(@Destino,sizeof(in_addr), AF_INET); <br>&nbsp; &nbsp; end; <br><br>&nbsp; &nbsp; if (host = nil) then begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Application.MessageBox('Host not found','Error', MB_OK); <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;WSACleanup(); <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FreeLibrary(HNDicmp); <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exit; <br>&nbsp; &nbsp; end; <br>&nbsp; &nbsp; memo1.Lines.Add('Pinging ' + Edit1.text); <br><br>&nbsp; &nbsp; Endereco := @Host.h_addr_list; <br><br>&nbsp; &nbsp; HNDFile := IcmpCreateFile(); <br>&nbsp; &nbsp; for x:= 0 to 4 do begin <br>&nbsp; &nbsp; &nbsp; Ip.Ttl := char(255); <br>&nbsp; &nbsp; &nbsp; Ip.Tos := char(0); <br>&nbsp; &nbsp; &nbsp; Ip.IPFlags := char(0); <br>&nbsp; &nbsp; &nbsp; Ip.OptSize := char(0); <br>&nbsp; &nbsp; &nbsp; Ip.Options := nil; <br><br>&nbsp; &nbsp; &nbsp; dwRetorno := IcmpSendEcho( <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;HNDFile, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Endereco^, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;null, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Ip, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Icmp, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sizeof(Icmp), <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DWORD(5000)); <br>&nbsp; &nbsp; &nbsp; Destino.S_addr := icmp.source; <br>&nbsp; &nbsp; &nbsp; Memo1.Lines.Add('Ping ' + Edit1.text); <br>&nbsp; &nbsp; &nbsp;end; <br><br><br>&nbsp; &nbsp;IcmpCLoseHandle(HNDFile); <br>&nbsp; &nbsp;FreeLibrary(HNDicmp); <br>&nbsp; &nbsp;WSACleanup(); <br>end; <br><br>This code is not complete functional, sometimes it&amp;acute;s doesn&amp;acute;t work with Hostnames, only with IP adresses. For NT users don&amp;acute;t use the IcmpCloseHandle function. If you have some idea to make this code work better, mail me. <br><br>That&amp;acute;s All….. <br><br>Now, the complete unit &amp;acute;s code: <br><br>---------------------------------- <br>unit Unit1; <br><br>interface <br><br>uses <br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, <br>&nbsp; winsock, StdCtrls; <br><br>type <br>&nbsp; IPINFO = record <br>&nbsp; Ttl &nbsp; &nbsp; :char; <br>&nbsp; Tos &nbsp; &nbsp; :char; <br>&nbsp; IPFlags :char; <br>&nbsp; OptSize :char; <br>&nbsp; Options :^char; <br>end; <br><br>type <br>ICMPECHO = record <br>Source &nbsp;:longint; <br>Status &nbsp;:longint; <br>RTTime &nbsp;:longint; <br>DataSize:Shortint; <br>Reserved:Shortint; <br>pData &nbsp; :^variant; <br>i_ipinfo:IPINFO; <br>end; <br><br>TIcmpCreateFile = function():integer; {$IFDEF WIN32} stdcall; {$ENDIF} <br>TIcmpCloseHandle = procedure(var handle:integer);{$IFDEF WIN32} stdcall; {$ENDIF} <br>TIcmpSendEcho = function(var handle:integer; endereco:DWORD; buffer:variant; tam:WORD; IP:IPINFO; ICMP:ICMPECHO; tamicmp:DWORD; tempo:DWORD):DWORD;{$IFDEF WIN32} stdcall; {$ENDIF} <br><br><br>type <br>&nbsp; TForm1 = class(TForm) <br>&nbsp; &nbsp; Button1: TButton; <br>&nbsp; &nbsp; Button2: TButton; <br>&nbsp; &nbsp; Edit1: TEdit; <br>&nbsp; &nbsp; Memo1: TMemo; <br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject); <br>&nbsp; &nbsp; procedure Button2Click(Sender: TObject); <br>&nbsp; private <br>&nbsp; &nbsp; { Private declarations } <br>&nbsp; public <br><br>&nbsp; end; <br><br>var <br>&nbsp; Form1: TForm1; <br><br>implementation <br><br>{$R *.DFM} <br><br>procedure TForm1.Button1Click(Sender: TObject); <br>var <br>wsadt : wsadata; <br>icmp &nbsp;:icmpecho; <br>HNDicmp : integer; <br>hndFile :integer; <br>Host :PHostEnt; <br>Destino :in_addr; <br>Endereco :^DWORD; <br>IP : ipinfo; <br>Retorno :integer; <br>dwRetorno :DWORD; <br>x :integer; <br><br>IcmpCreateFile : TIcmpCreateFile; <br>IcmpCloseHandle : TIcmpCloseHandle; <br>IcmpSendEcho : TIcmpSendEcho; <br><br>begin <br>&nbsp; &nbsp; if (edit1.Text = '') then begin <br>&nbsp; &nbsp; &nbsp;Application.MessageBox('Digite um HostName ou um End. IP', <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'Error', MB_OK); <br>&nbsp; &nbsp; &nbsp;exit; <br>&nbsp; &nbsp; end; <br>&nbsp; &nbsp; HNDicmp := LoadLibrary('ICMP.DLL'); <br>&nbsp; &nbsp; if (HNDicmp &lt;&gt; 0) then begin <br>&nbsp; &nbsp; &nbsp; &nbsp;@IcmpCreateFile := GetProcAddress(HNDicmp,'IcmpCreateFile'); <br>&nbsp; &nbsp; &nbsp; &nbsp;@IcmpCloseHandle := GetProcAddress(HNDicmp,'IcmpCloseHandle'); <br>&nbsp; &nbsp; &nbsp; &nbsp;@IcmpSendEcho := GetProcAddress(HNDicmp,'IcmpSendEcho'); <br>&nbsp; &nbsp; &nbsp; &nbsp;if (@IcmpCreateFile=nil) or (@IcmpCloseHandle=nil) or (@IcmpSendEcho=nil) then &nbsp;begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Application.MessageBox('Erro pegando endere&amp;ccedil;os ICMP','Error', MB_OK); <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FreeLibrary(HNDicmp); <br>&nbsp; &nbsp; &nbsp; &nbsp;end; <br>&nbsp; &nbsp; end; <br>&nbsp; &nbsp; Retorno := WSAStartup($0101,wsadt); <br><br>&nbsp; &nbsp; if (Retorno &lt;&gt; 0) then begin <br>&nbsp; &nbsp; &nbsp; Application.MessageBox('N&amp;atilde;o foi possível carregar WinSockets','WSAStartup', MB_OK); <br>&nbsp; &nbsp; &nbsp; WSACleanup(); <br>&nbsp; &nbsp; &nbsp; FreeLibrary(HNDicmp); <br>&nbsp; &nbsp; end; <br><br>&nbsp; &nbsp; Destino.S_addr := inet_addr(Pchar(Edit1.text)); <br>&nbsp; &nbsp; if (Destino.S_addr = 0) then begin <br>&nbsp; &nbsp; &nbsp; &nbsp;Host := GetHostbyName(PChar(Edit1.text)); <br>&nbsp; &nbsp; &nbsp; &nbsp;end <br>&nbsp; &nbsp; else begin <br>&nbsp; &nbsp; &nbsp; &nbsp;Host := GetHostbyAddr(@Destino,sizeof(in_addr), AF_INET); <br>&nbsp; &nbsp; end; <br><br>&nbsp; &nbsp; if (host = nil) then begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Application.MessageBox('Host n&amp;atilde;o encontrado','Error', MB_OK); <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;WSACleanup(); <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FreeLibrary(HNDicmp); <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exit; <br>&nbsp; &nbsp; end; <br>&nbsp; &nbsp; memo1.Lines.Add('Pinging ' + Edit1.text); <br><br>&nbsp; &nbsp; Endereco := @Host.h_addr_list; <br><br>&nbsp; &nbsp; HNDFile := IcmpCreateFile(); <br>&nbsp; &nbsp; for x:= 0 to 4 do begin <br>&nbsp; &nbsp; &nbsp; Ip.Ttl := char(255); <br>&nbsp; &nbsp; &nbsp; Ip.Tos := char(0); <br>&nbsp; &nbsp; &nbsp; Ip.IPFlags := char(0); <br>&nbsp; &nbsp; &nbsp; Ip.OptSize := char(0); <br>&nbsp; &nbsp; &nbsp; Ip.Options := nil; <br><br>&nbsp; &nbsp; &nbsp; dwRetorno := IcmpSendEcho( <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;HNDFile, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Endereco^, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;null, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Ip, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Icmp, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sizeof(Icmp), <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DWORD(5000)); <br>&nbsp; &nbsp; &nbsp; Destino.S_addr := icmp.source; <br>&nbsp; &nbsp; &nbsp; Memo1.Lines.Add('Pingou ' + Edit1.text); <br>&nbsp; &nbsp; &nbsp;end; <br><br><br>&nbsp; &nbsp;IcmpCLoseHandle(HNDFile); <br>&nbsp; &nbsp;FreeLibrary(HNDicmp); <br>&nbsp; &nbsp;WSACleanup(); <br>end; <br><br>end. <br>&nbsp;<br>
 
uses ...WinSock;<br>const<br>&nbsp; IcmpDLL = 'icmp.dll';<br>&nbsp; TimeOut = 5000;<br>......<br>&nbsp; PIcmpEchoReply = ^TIcmpEchoReply;<br>&nbsp; TIcmpEchoReply = packed record<br>&nbsp; &nbsp;Address: DWORD;<br>&nbsp; &nbsp;Status: DWORD;<br>&nbsp; &nbsp;RTT: DWORD;<br>&nbsp; &nbsp;DataSize: Word;<br>&nbsp; &nbsp;Reserved: Word;<br>&nbsp; &nbsp;Data: Pointer;<br>&nbsp; &nbsp;Options: TIPOptionInformation;<br>&nbsp; end;<br>&nbsp; TIcmpCreateFile = function: THandle; stdcall;<br>&nbsp; TIcmpCloseHandle = function(IcmpHandle: THandle): Boolean; stdcall;<br>&nbsp; TIcmpSendEcho = function(<br>&nbsp; &nbsp; IcmpHandle:THandle;<br>&nbsp; &nbsp; DestinationAddress:DWORD;<br>&nbsp; &nbsp; RequestData:Pointer;<br>&nbsp; &nbsp; RequestSize:Word;<br>&nbsp; &nbsp; RequestOptions:PIPOptionInformation;<br>&nbsp; &nbsp; ReplyBuffer: Pointer;<br>&nbsp; &nbsp; ReplySize: DWord;<br>&nbsp; &nbsp; Timeout: DWord<br>&nbsp; &nbsp;): DWord; stdcall;<br>......<br>var<br>&nbsp; hICMPlib: HModule;<br>&nbsp; IcmpCreateFile: TIcmpCreateFile;<br>&nbsp; IcmpCloseHandle: TIcmpCloseHandle;<br>&nbsp; IcmpSendEcho: TIcmpSendEcho;<br>&nbsp; hICMP: THandle;// Handle for the ICMP Calls<br>&nbsp; Size: integer;<br>&nbsp; Address: DWord; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Address of host to contact<br>&nbsp; HostName, HostIP: String; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Name and dotted IP of host to contact<br>&nbsp; Phe: PHostEnt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// HostEntry buffer for name lookup<br>&nbsp; BufferSize, nPkts: Integer;<br>&nbsp; pReqData, pData: Pointer;<br>&nbsp; pIPE: PIcmpEchoReply; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // ICMP Echo reply buffer<br>&nbsp; IPOpt: TIPOptionInformation; &nbsp; &nbsp; &nbsp; &nbsp;// IP Options for packet to send<br>......<br>procedure TForm1.FormCreate(Sender: TObject);<br>var<br>&nbsp; wsadata: TWSAData;<br>begin<br>&nbsp; // initialise winsock<br>&nbsp; if WSAStartup($101, wsadata) &lt;&gt; 0 then<br>&nbsp; begin<br>&nbsp; &nbsp;ShowMessage('初始化Winsock错误');<br>&nbsp; &nbsp;halt;<br>&nbsp; end;<br>&nbsp; // register the icmp.dll stuff<br>&nbsp; hICMPlib := loadlibrary(icmpDLL);<br>&nbsp; if hICMPlib &lt;&gt; null then<br>&nbsp; begin<br>&nbsp; &nbsp;@ICMPCreateFile := GetProcAddress(hICMPlib, 'IcmpCreateFile');<br>&nbsp; &nbsp;@IcmpCloseHandle:= GetProcAddress(hICMPlib, 'IcmpCloseHandle');<br>&nbsp; &nbsp;@IcmpSendEcho:= GetProcAddress(hICMPlib, 'IcmpSendEcho');<br>&nbsp; &nbsp;if (@ICMPCreateFile = Nil) or (@IcmpCloseHandle = Nil) or (@IcmpSendEcho = Nil) then<br>&nbsp; &nbsp;begin<br>&nbsp; &nbsp; ShowMessage('读入函数出错');<br>&nbsp; &nbsp; halt;<br>&nbsp; &nbsp;end;<br>&nbsp; &nbsp;hICMP := IcmpCreateFile;<br>&nbsp; &nbsp;if hICMP = INVALID_HANDLE_VALUE then<br>&nbsp; &nbsp;begin<br>&nbsp; &nbsp; ShowMessage('无效句柄');<br>&nbsp; &nbsp; halt;<br>&nbsp; &nbsp;end;<br>&nbsp; end<br>&nbsp; else<br>&nbsp; begin<br>&nbsp; &nbsp;ShowMessage('库注册错误');<br>&nbsp; &nbsp;halt;<br>&nbsp; end;<br>end;<br><br>procedure TForm1.Ping;<br>begin<br>&nbsp; Memo1.Lines.Add('发出 ' + IntToStr(Size) + ' 字节给 ' +<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HostName + ' (' + HostIP + ')');<br><br>&nbsp; // Get some data buffer space and put something in the packet to send<br>&nbsp; BufferSize := SizeOf(TICMPEchoReply) + Size;<br>&nbsp; GetMem(pReqData, Size);<br>&nbsp; GetMem(pData, Size);<br>&nbsp; GetMem(pIPE, BufferSize);<br>&nbsp; FillChar(pReqData^, Size, $AA);<br>&nbsp; pIPE^.Data := pData;<br>&nbsp; // Finally Send the packet<br>&nbsp; FillChar(IPOpt, SizeOf(IPOpt), 0);<br>&nbsp; IPOpt.TTL := 64;<br>&nbsp; NPkts := IcmpSendEcho(hICMP, Address, pReqData, Size,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @IPOpt, pIPE, BufferSize, TimeOut);<br>&nbsp; if NPkts = 0 then<br>&nbsp; &nbsp;ShowError(GetLastError)<br>&nbsp; else<br>&nbsp; begin<br>&nbsp; &nbsp;HostIP := StrPas(inet_ntoa(TInAddr(pIPE^.Address)));<br>&nbsp; &nbsp;Memo1.Lines.Add('收到 ' + IntToStr(pIPE^.DataSize) +<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;' 字节,来自: ' + HostIP + #13#10 +<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'用时: ' + IntToStr(pIPE^.RTT) + ' 毫秒')<br>&nbsp; end;<br>&nbsp; // Free those buffers<br>&nbsp; FreeMem(pIPE);<br>&nbsp; FreeMem(pData);<br>&nbsp; FreeMem(pReqData);<br>&nbsp; Memo1.Lines.Add('');<br>end;<br>
 
多人接受答案了。
 
后退
顶部