Delphi XE5 で PING を使ってみる
Indy の IdIcmpClient.Ping() を使う場合は、exe を管理者権限で実行する必要があるようです。
ネット上に、Winsock を使ったサンプルがあったので、試してみました。
unit xpingUnit; interface uses Winapi . Windows, Winapi . Messages, System . SysUtils, System . Variants, System . Classes, Vcl . Graphics, Vcl . Controls, Vcl . Forms, Vcl . Dialogs, Winsock, Vcl . StdCtrls; type TForm1 = class (TForm) Memo1: TMemo; Button1: TButton; Edit1: TEdit; Edit2: TEdit; Button2: TButton; Label1: TLabel; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private 宣言 } public { Public 宣言 } runFlag : boolean ; end ; var Form1: TForm1; // icmp.dll function IcmpCreateFile : THandle; stdcall; external 'icmp.dll' ; function IcmpCloseHandle (icmpHandle : THandle) : boolean ; stdcall; external 'icmp.dll' ; function IcmpSendEcho ( IcmpHandle : THandle; DestinationAddress : TInAddr; RequestData : Pointer ; RequestSize : Smallint ; RequestOptions : Pointer ; ReplyBuffer : Pointer ; ReplySize : DWORD; Timeout : DWORD) : DWORD; stdcall; external 'icmp.dll' ; implementation {$R *.dfm} // ----------------------------------------------- // uses Winsock // 「同一LAN内のIPAdressやMacAdressを取得するには?」 // ほぼ、そのままのコードです。 // ----------------------------------------------- // IP アドレスからホスト名を得る function GetHostName(Ip : AnsiString ) : AnsiString ; var PH : PHostEnt; InAddr: TInAddr; WSADATA : TWSADATA; begin Result := '' ; if Ip = '' then Exit; InAddr . S_addr := inet_addr( PAnsiChar (Ip)); WSAStartup(MakeWord( 1 , 1 ) , WSADATA); //MakeWord(1,1)=$0101 PH := GetHostByAddr(@InAddr, 4 , PF_INET); if PH = nil then Exit; Result := AnsiString (PH^.h_name); WSACleanup; end ; // ホスト名から IP アドレスを得る function GetIpAddress(HostName : AnsiString ) : AnsiString ; var PH : PHostEnt; InAddr: TInAddr; WSADATA : TWSADATA; begin Result := '' ; if HostName = '' then Exit; WSAStartup(MakeWord( 1 , 1 ), WSADATA); PH := GetHostByName( PAnsiChar (HostName)); if PH = nil then Exit; InAddr := PInAddr(PH^.h_addr_list^)^; Result := inet_ntoa(InAddr); WSACleanup; end ; // PING function PingIP(Ip : Ansistring ) : boolean ; var Hnd : THandle; InAddr : TInAddr; DW : DWORD; rep : array [ 1..128 ] of byte ; begin result := false ; Hnd := IcmpCreateFile; if Hnd = INVALID_HANDLE_VALUE then Exit; InAddr . S_addr := inet_addr( PAnsiChar (Ip)); DW := IcmpSendEcho(Hnd, InAddr, nil , 0 , nil , @rep, 128 , 500 {Timeout} ); Result := DW <> 0 ; IcmpCloseHandle(Hnd); end ; // 自PCのIPアドレスとPC名を取得 function LocalIP( var PcName: AnsiString ): Ansistring ; type TaPInAddr = array [ 0..10 ] of PInAddr; PaPInAddr = ^TaPInAddr; var PH : PHostEnt; pPtr: PaPInAddr; buffer: array [ 0..127 ] of AnsiChar ; i: Integer ; GInitData: TWSAData; begin WSAStartup(MakeWord( 1 , 1 ), GInitData); Result := '' ; PcName := '' ; GetHostName(buffer); PH := GetHostByName(buffer); if PH = nil then Exit; PcName := AnsiString (PH^.h_name); pPtr := PaPInAddr(PH^.h_addr_list); i := 0 ; while pPtr^[i] <> nil do begin Result := inet_ntoa(pPtr^[i]^); Inc(i); end ; WSACleanup; end ; // 自PCのIPアドレスとPC名を得る procedure TForm1 . Button1Click(Sender: TObject); var Ip : AnsiString ; PcName : AnsiString ; begin Edit1 . Text := '' ; Edit2 . Text := '' ; Ip := LocalIP(PcName); if Ip <> '' then begin Edit1 . Text := string (Ip); Edit2 . Text := string (PcName); end ; end ; procedure TForm1 . Button2Click(Sender: TObject); var i : integer ; n : integer ; IpHead : Ansistring ; Ip : Ansistring ; begin if Button2 . Caption = 'PING' then begin runFlag := True ; Button2 . Caption := 'Break' ; Memo1 . Lines . Clear; IpHead := '192.168.0.' ; n := LastDelimiter( '.' , Edit1 . Text); if n > 0 then IpHead := AnsiString (Copy( String (Edit1 . Text), 1 , n)); for i := 0 to 255 do begin if runFlag then begin Application . ProcessMessages; IP := IpHead + AnsiString (IntToStr(i)); Label1 . Caption := String (IP); Label1 . Refresh; if PingIp(Ip) then Memo1 . Lines . Add( String (Ip + AnsiString (StringOfChar( ' ' , 16 - Length(ip))) + GetHostName(Ip))); end else Break; end ; if runFlag then Memo1 . Lines . Add( '---- term ----' ) else Memo1 . Lines . Add( '---- break ----' ); end else begin runFlag := False ; Button2 . Caption := 'PING' ; Application . ProcessMessages; end ; end ; procedure TForm1 . FormCreate(Sender: TObject); begin Button1 . Caption := 'LocalIP' ; Button2 . Caption := 'PING' ; Edit1 . Text := '' ; Edit2 . Text := '' ; Label1 . Caption := '' ; Memo1 . Lines . Clear; end ; end . |