環境
OS: Windows 10 プロ 64 ビット
IDE: Delphi XE6 + Update 1
ゴール
ローカル サーバーで Wake-on-LAN を実現するために、Indy コンポーネントを介してMagic パケットを送信する Delphi XE6 でアプリケーションを作成します。サーバーは、Linux クライアントから起動できることがテストされています。
独自のソリューションを作成したいので、アプリケーションの提案はありません。ありがとうございました。
マジックパケット
ウィキペディアの記事の一部を引用:
マジック パケットは、ペイロード内の任意の場所に 255 (16 進数で FF FF FF FF FF FF) の 6 バイトを含むブロードキャスト フレームであり、その後にターゲット コンピュータの 48 ビット MAC アドレスが 16 回繰り返され、合計 102 バイトになります。
ベースバージョン
このページから基本バージョンを取得しました。
著者は、使用した Delphi のバージョンについて言及していません。古いバージョンを想定してみましょう。
ページが利用できなくなった場合に備えて、変更せずに引用します。
procedure WakeOnLan(const AMacAddress : string);
type
TMacAddress = array [1..6] of byte;
TWakeRecord = packed record
Waker : TMACAddress;
MAC : array[0..15] of TMACAddress;
end;
var i : integer;
WR : TWakeRecord;
MacAddress : TMacAddress;
UDP : TIdUDPClient;
sData : string;
begin
// Convert MAC string into MAC array
fillchar(MacAddress,SizeOf(TMacAddress),0);
sData := trim(AMacAddress);
if length(sData) = 17 then begin
for i := 1 to 6 do begin
MacAddress[i] := StrToIntDef('$' + copy(sData,1,2),0);
sData := copy(sData,4,17);
end;
end;
for i := 1 To 6 do WR.Waker[i] := $FF;
for i := 0 to 15 do WR.MAC[i] := MacAddress;
// Create UDP and Broadcast data structure
UDP := TIdUDPClient.Create(nil);
UDP.Host := '255.255.255.255';
UDP.Port := 32767;
UDP.BroadCastEnabled := true;
UDP.SendBuffer(WR,SizeOf(TWakeRecord));
UDP.BroadcastEnabled := false;
UDP.Free;
end;
しかし、Delphi XE6 のコンパイラは次の行に文句を言います。
UDP.SendBuffer(WR,SizeOf(TWakeRecord));
それが言うところ:
[dcc64 Error] main.pas(73): E2250 There is no overloaded version of 'SendBuffer' that can be called with these arguments
私のバージョン
読みやすくするために上記のコードを書き直しました+コンパイルしないさまざまなアプローチを試しましたが、これはコンパイルされますが、明らかに機能しません(サーバーを起動しません)。
procedure WakeOnLan(const AMacAddress: string);
type
TMacAddress = array [1..6] of Byte;
TWakeRecord = packed record
Waker : TMACAddress;
MAC : array [0..15] of TMacAddress;
end;
var
I : Integer;
WR : TWakeRecord;
MacAddress : TMacAddress;
UDPClient : TIdUDPClient;
sData : string;
begin
FillChar(MacAddress, SizeOf(TMacAddress), 0);
sData := Trim(AMacAddress);
if Length(sData) = 17 then begin
for I := 1 to 6 do begin
MacAddress[I] := StrToIntDef('$' + Copy(sData, 1, 2), 0);
sData := Copy(sData, 4, 17);
end;
end;
for I := 1 to 6 do WR.Waker[I] := $FF;
for I := 0 to 15 do WR.MAC[I] := MacAddress;
UDPClient := TIdUDPClient.Create(nil);
try
// UDP.Host := '255.255.255.255';
// UDP.Port := 32767;
UDPClient.BroadCastEnabled := True;
UDPClient.Broadcast(RawToBytes(WR, SizeOf(TWakeRecord)), 7);
// UDP.SendBuffer(RawToBytes(WR, SizeOf(TWakeRecord)));
UDPClient.BroadcastEnabled := False;
finally
UDPClient.Free;
end;
end;
編集1
私は IP アドレスをまったく使用したくありません。純粋な MAC アドレスだけで十分です。