如何在Delphi XE6中使用Magic数据包和Indy创建局域网唤醒应用程序?

时间:2018-08-02 08:48:23

标签: delphi networking ethernet wake-on-lan

环境

操作系统:Windows 10 Pro 64位

IDE:Delphi XE6 + Update 1


目标

在Delphi XE6中创建一个通过Indy组件发送Magic packet的应用程序,以实现局域网唤醒本地服务器。服务器已经过测试,可以从Linux客户端唤醒。

请注意,我想创建自己的解决方案,请没有应用建议。谢谢。


魔术包

引用Wikipedia article的一部分:

  

魔术包是一个广播帧,在其有效载荷中的所有位置包含所有255个字节的6个字节(十六进制FF FF FF FF FF FF),然后是目标计算机的48位MAC地址的十六个重复,总共为102字节。


基本版本

我从this page获得了基本版本。

作者没有提到他使用的是哪个版本的Delphi,我们假设是一个较旧的版本。

如果页面不可用,未更改,我会引用它:

destroyed

但是Delphi XE6的编译器在网上抱怨:

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;

它说:

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

EDIT1

我根本不想使用任何IP地址,只应该使用纯MAC地址即可。

2 个答案:

答案 0 :(得分:2)

原始代码是为Indy 9编写的。与Indy 10等效的代码看起来像这样:

UDPClient := TIdUDPClient.Create(nil);
try
  UDP.Host := '255.255.255.255';
  UDP.Port := 32767;
  UDP.IPVersion := Id_IPv4;
  UDP.BroadcastEnabled := True;
  UDP.SendBuffer(RawToBytes(WR, SizeOf(WR)));
finally
  UDP.Free;
end;

或者:

UDPClient := TIdUDPClient.Create(nil);
try
  UDP.IPVersion := Id_IPv4;
  UDP.BroadCastEnabled := True;
  UDP.SendBuffer('255.255.255.255', 32767, RawToBytes(WR, SizeOf(WR)));
finally
  UDP.Free;
end;

或者:

UDP := TIdUDPClient.Create(nil);
try
  UDP.IPVersion := Id_IPv4;
  UDP.Broadcast(RawToBytes(WR, SizeOf(WR)), 32767);
finally
  UDP.Free;
end;

答案 1 :(得分:0)

此代码对我有用,请查看SendBuffer函数的参数(服务器,端口,缓冲区):

UDP.IPVersion := Id_IPv4;
UDP.BroadCastEnabled := True;
UDP.SendBuffer('192.168.1.255', 9, RawToBytes(WR, SizeOf(WR)));
UDP.BroadCastEnabled := False;

请注意,广播地址“ 255.255.255.255”可能无法正常工作,请以广播范围为例。