以下是我从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&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. 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> IPINFO = record <br> Ttl :char; <br> Tos :char; <br> IPFlags :char; <br> OptSize :char; <br> Options :^char; <br>end; <br>5. Declare a record constant to put the ICMP package: <br>type <br>ICMPECHO = record <br>Source :longint; <br>Status :longint; <br>RTTime :longint; <br>DataSize:Shortint; <br>Reserved:Shortint; <br>pData :^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
WORD; buffer:variant; tam:WORD; IP:IPINFO; ICMP:ICMPECHO; tamicmp
WORD; tempo
WORD)
WORD;{$IFDEF WIN32} stdcall; {$ENDIF} <br><br>7. In the Tbutton&acute;s Onclick event insert this code:: <br><br>procedure TForm1.Button1Click(Sender: TObject); <br>var <br>wsadt : wsadata; <br>icmp :icmpecho; <br>HNDicmp : integer; <br>hndFile :integer; <br>Host
HostEnt; <br>Destino :in_addr; <br>Endereco :^DWORD; <br>IP : ipinfo; <br>Retorno :integer; <br>dwRetorno
WORD; <br>x :integer; <br><br>IcmpCreateFile : TIcmpCreateFile; <br>IcmpCloseHandle : TIcmpCloseHandle; <br>IcmpSendEcho : TIcmpSendEcho; <br><br>begin <br> if (edit1.Text = '') then begin <br> Application.MessageBox('Enter a HostName ro a IP Adress', <br> 'Error', MB_OK); <br> exit; <br> end; <br> HNDicmp := LoadLibrary('ICMP.DLL'); <br> if (HNDicmp <> 0) then begin <br> @IcmpCreateFile := GetProcAddress(HNDicmp,'IcmpCreateFile'); <br> @IcmpCloseHandle := GetProcAddress(HNDicmp,'IcmpCloseHandle'); <br> @IcmpSendEcho := GetProcAddress(HNDicmp,'IcmpSendEcho'); <br> if (@IcmpCreateFile=nil) or (@IcmpCloseHandle=nil) or (@IcmpSendEcho=nil) then begin <br> Application.MessageBox('Error getting ICMP Adress’,'Error', MB_OK); <br> FreeLibrary(HNDicmp); <br> end; <br> end; <br> Retorno := WSAStartup($0101,wsadt); <br><br> if (Retorno <> 0) then begin <br> Application.MessageBox('Can&acute;t Load WinSockets','WSAStartup', MB_OK); <br> WSACleanup(); <br> FreeLibrary(HNDicmp); <br> end; <br><br> Destino.S_addr := inet_addr(Pchar(Edit1.text)); <br> if (Destino.S_addr = 0) then begin <br> Host := GetHostbyName(PChar(Edit1.text)); <br> end <br> else begin <br> Host := GetHostbyAddr(@Destino,sizeof(in_addr), AF_INET); <br> end; <br><br> if (host = nil) then begin <br> Application.MessageBox('Host not found','Error', MB_OK); <br> WSACleanup(); <br> FreeLibrary(HNDicmp); <br> exit; <br> end; <br> memo1.Lines.Add('Pinging ' + Edit1.text); <br><br> Endereco := @Host.h_addr_list; <br><br> HNDFile := IcmpCreateFile(); <br> for x:= 0 to 4 do begin <br> Ip.Ttl := char(255); <br> Ip.Tos := char(0); <br> Ip.IPFlags := char(0); <br> Ip.OptSize := char(0); <br> Ip.Options := nil; <br><br> dwRetorno := IcmpSendEcho( <br> HNDFile, <br> Endereco^, <br> null, <br> 0, <br> Ip, <br> Icmp, <br> sizeof(Icmp), <br> DWORD(5000)); <br> Destino.S_addr := icmp.source; <br> Memo1.Lines.Add('Ping ' + Edit1.text); <br> end; <br><br><br> IcmpCLoseHandle(HNDFile); <br> FreeLibrary(HNDicmp); <br> WSACleanup(); <br>end; <br><br>This code is not complete functional, sometimes it&acute;s doesn&acute;t work with Hostnames, only with IP adresses. For NT users don&acute;t use the IcmpCloseHandle function. If you have some idea to make this code work better, mail me. <br><br>That&acute;s All….. <br><br>Now, the complete unit &acute;s code: <br><br>---------------------------------- <br>unit Unit1; <br><br>interface <br><br>uses <br> Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, <br> winsock, StdCtrls; <br><br>type <br> IPINFO = record <br> Ttl :char; <br> Tos :char; <br> IPFlags :char; <br> OptSize :char; <br> Options :^char; <br>end; <br><br>type <br>ICMPECHO = record <br>Source :longint; <br>Status :longint; <br>RTTime :longint; <br>DataSize:Shortint; <br>Reserved:Shortint; <br>pData :^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
WORD; buffer:variant; tam:WORD; IP:IPINFO; ICMP:ICMPECHO; tamicmp
WORD; tempo
WORD)
WORD;{$IFDEF WIN32} stdcall; {$ENDIF} <br><br><br>type <br> TForm1 = class(TForm) <br> Button1: TButton; <br> Button2: TButton; <br> Edit1: TEdit; <br> Memo1: TMemo; <br> procedure Button1Click(Sender: TObject); <br> procedure Button2Click(Sender: TObject); <br> private <br> { Private declarations } <br> public <br><br> end; <br><br>var <br> Form1: TForm1; <br><br>implementation <br><br>{$R *.DFM} <br><br>procedure TForm1.Button1Click(Sender: TObject); <br>var <br>wsadt : wsadata; <br>icmp :icmpecho; <br>HNDicmp : integer; <br>hndFile :integer; <br>Host
HostEnt; <br>Destino :in_addr; <br>Endereco :^DWORD; <br>IP : ipinfo; <br>Retorno :integer; <br>dwRetorno
WORD; <br>x :integer; <br><br>IcmpCreateFile : TIcmpCreateFile; <br>IcmpCloseHandle : TIcmpCloseHandle; <br>IcmpSendEcho : TIcmpSendEcho; <br><br>begin <br> if (edit1.Text = '') then begin <br> Application.MessageBox('Digite um HostName ou um End. IP', <br> 'Error', MB_OK); <br> exit; <br> end; <br> HNDicmp := LoadLibrary('ICMP.DLL'); <br> if (HNDicmp <> 0) then begin <br> @IcmpCreateFile := GetProcAddress(HNDicmp,'IcmpCreateFile'); <br> @IcmpCloseHandle := GetProcAddress(HNDicmp,'IcmpCloseHandle'); <br> @IcmpSendEcho := GetProcAddress(HNDicmp,'IcmpSendEcho'); <br> if (@IcmpCreateFile=nil) or (@IcmpCloseHandle=nil) or (@IcmpSendEcho=nil) then begin <br> Application.MessageBox('Erro pegando endere&ccedil;os ICMP','Error', MB_OK); <br> FreeLibrary(HNDicmp); <br> end; <br> end; <br> Retorno := WSAStartup($0101,wsadt); <br><br> if (Retorno <> 0) then begin <br> Application.MessageBox('N&atilde;o foi possível carregar WinSockets','WSAStartup', MB_OK); <br> WSACleanup(); <br> FreeLibrary(HNDicmp); <br> end; <br><br> Destino.S_addr := inet_addr(Pchar(Edit1.text)); <br> if (Destino.S_addr = 0) then begin <br> Host := GetHostbyName(PChar(Edit1.text)); <br> end <br> else begin <br> Host := GetHostbyAddr(@Destino,sizeof(in_addr), AF_INET); <br> end; <br><br> if (host = nil) then begin <br> Application.MessageBox('Host n&atilde;o encontrado','Error', MB_OK); <br> WSACleanup(); <br> FreeLibrary(HNDicmp); <br> exit; <br> end; <br> memo1.Lines.Add('Pinging ' + Edit1.text); <br><br> Endereco := @Host.h_addr_list; <br><br> HNDFile := IcmpCreateFile(); <br> for x:= 0 to 4 do begin <br> Ip.Ttl := char(255); <br> Ip.Tos := char(0); <br> Ip.IPFlags := char(0); <br> Ip.OptSize := char(0); <br> Ip.Options := nil; <br><br> dwRetorno := IcmpSendEcho( <br> HNDFile, <br> Endereco^, <br> null, <br> 0, <br> Ip, <br> Icmp, <br> sizeof(Icmp), <br> DWORD(5000)); <br> Destino.S_addr := icmp.source; <br> Memo1.Lines.Add('Pingou ' + Edit1.text); <br> end; <br><br><br> IcmpCLoseHandle(HNDFile); <br> FreeLibrary(HNDicmp); <br> WSACleanup(); <br>end; <br><br>end. <br> <br>