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.