Thema: Delphi Ping mit HostName

Einzelnen Beitrag anzeigen

Benutzerbild von Alucard
Alucard

Registriert seit: 9. Jan 2015
11 Beiträge
 
Delphi 12 Athens
 
#1

Ping mit HostName

  Alt Gestern, 13:10
Moins.

Ich benutze die unten zitierte Unit, um Geräte im lokalen Netzwerk anzupingen. Im Wesentlichen will ich eigentlich nur wissen, ob mein Programm in meiner heimischen Umgebung ausgeführt wird bzw. ob mein heimischer ChromecastAudio erreichbar ist.

Die zitierte Unit funktioniert super, so lange ich mit IP-Adressen arbeite. Die IP des Chromecast ist daheim statisch und bekannt. Über einen Ping auf diese IP könnte es in fremden Netzwerken allerdings zu einer falsch-positiven Antwort kommen, falls durch Zufall ein Gerät mit der gleichen IP vorhanden ist. Wenn ich einen Hostnamen nutze, der im gerade verbundenen Netzwerk vorhanden ist, funktioniert die Unit auch fehlerfrei (/Cpt. Obvious). Sobald ich aber irgendwo bin, wo mein Chromecast nicht vorhanden ist und der Hostname also nicht bekannt ist, wirft Delphi beim Aufrufen von "PingHost('HostName_meines_Chromecast')" folgenden Fehler:
Code:
Im Projekt Blablub.exe ist eine Exception der Klasse EOSError mit der Meldung 'Systemfehler. Code: 11002.
Dies ist normalerweise ein zeitweiliger Fehler bei der Auflösung von Hostnamen. Grund ist, dass der lokale Server keine Rückmeldung vom autorisierenden Server erhalten hat' aufgetreten.
Vermutlich lässt sich der Fehler leicht beheben, aber da ich doof bin und die Unit nur irgendwoher geklaut habe, verstehe ich sie nicht ganz

Alternativ würde für mich auch reichen, die SSID des gerade verbundenen WLANs abzugleichen, aber das scheint auch nicht so wirklich trivial zu sein...

Code:
unit Ping2;

interface

function PingHost(const HostName : AnsiString; TimeoutMS : cardinal = 500) : boolean;

implementation

uses Windows, SysUtils, WinSock;

function IcmpCreateFile: THandle;
  stdcall; external 'iphlpapi.dll';
function IcmpCloseHandle(icmpHandle: THandle): boolean;
  stdcall; external 'iphlpapi.dll';
function IcmpSendEcho(icmpHandle: THandle; DestinationAddress: In_Addr;
  RequestData: Pointer; RequestSize: Smallint; RequestOptions: Pointer;
  ReplyBuffer: Pointer; ReplySize: DWORD; Timeout: DWORD): DWORD; stdcall;
  external 'iphlpapi.dll';

type
  TEchoReply = packed record
    Addr: In_Addr;
    Status: DWORD;
    RoundTripTime: DWORD;
  end;

  PEchoReply = ^TEchoReply;

var
  WSAData: TWSAData;


procedure Startup;
begin
  if WSAStartup($0101, WSAData) <> 0 then
    raise Exception.Create('WSAStartup');
end;


procedure Cleanup;
begin
  if WSACleanup <> 0 then
    raise Exception.Create('WSACleanup');
end;


function PingHost(const HostName: AnsiString; TimeoutMS: cardinal = 500): boolean;
const
  rSize = $400;
var
  e: PHostEnt;
  a: PInAddr;
  h: THandle;
  d: string;
  r: array [0 .. rSize - 1] of byte;
  i: cardinal;
begin
  Startup;
  e := gethostbyname(PAnsiChar(HostName));
  if e = nil then
    RaiseLastOSError;
  if e.h_addrtype = AF_INET then
    Pointer(a) := e.h_addr^
  else
    raise Exception.Create('Name doesn''t resolve to an IPv4 address');

  d := FormatDateTime('yyyymmddhhnnsszzz', Now);

  h := IcmpCreateFile;
  if h = INVALID_HANDLE_VALUE then
    RaiseLastOSError;
  try
    i := IcmpSendEcho(h, a^, PChar(d), Length(d), nil, @r[0], rSize, TimeoutMS);
    Result := (i <> 0) and (PEchoReply(@r[0]).Status = 0);
  finally
    IcmpCloseHandle(h);
  end;
  Cleanup;
end;


end.
formerly known as Alcuard
(Man muss seinen eigenen Username schon richtig tippen können... )
  Mit Zitat antworten Zitat