热情软件屋

 

如何实现网络唤醒


编号:QA004784
建立日期: 2003年12月6日 最后修改日期:2003年12月6日
所属类别:

王伟:
    操作系统:windows xp
    编程工具:visual studio.net
    问题:有关网络唤醒的问题wake on LAN(WOL),也可称作“远程开机”。我曾尝试用c++,vb,c#等多种方法解决这一问题,基本思路来自网上一些介绍:
    前提:
    1、已知欲开启机的网卡物理地址(MAC)
    2、用一些第三方应用软件测试(如:国产LanHelper)可以开启LAN内的任一机器,证明硬件设置正确。
    我曾尝试用c++,vb,c#等多种编程手段解决这一问题,基本思路来自网上一些介绍:
    1、采用UDP 协议
    2、向LAN中的欲开启PC机发送16进制的“FFFFFF"和网卡物理地址的16次重复(12次也试过)。未能成功。
    如今,几乎所有PC都有WOL功能。难道都只能用第三方应用软件实现“远程开机”这一如此有用的功能?
    望高手老师不吝赐教,指点迷津。(最好能有上述编程手段的源码)
    水平: 中级

回答:

    提供一delphi单元代码,你可以翻译成所需要的。
    unit WakeUp;
    
    interface
    uses
     Windows, Messages, SysUtils, Dialogs, WinSock;
    
    function CheckWinSockResult(ResultCode: Integer; const FuncName: string): Integer;
    procedure OpenComputer(SAddr: string);
    
    const
     LEN_PHYSADDR = 6;
    
    implementation
    
    {$R *.DFM}
    function CheckWinSockResult(ResultCode: Integer; const FuncName: string): Integer;
    begin
     if ResultCode <> 0 then
     begin
     Result := WSAGetLastError;
     ShowMessage(Format(#13#10'Windows socket函数''%s''错误: %s (%d)',[FuncName,SysErrorMessage(Result), Result]));
     Abort;
     end else Result := 0;
    end;
    
    procedure OpenComputer(SAddr: string); //00-B0-D0-15-86-B4
    var
     WSAData: TWSAData;
     MSocket: TSocket;
     SockAddrIn: TSockAddrIn;
     RetVal, OptVal, i: Integer;
     MacAddr: array[0..5] of Byte;
     MagicData: array[0..101] of Byte;
     Position: Longint;
    begin
     try
     if Length(SAddr) <> 17 then Abort;
     for i := 1 to Length(SAddr) do
     if i in [3, 6, 9, 12, 15] then
     if SAddr[i] <> '-' then Abort;
     for i := 0 to High(MacAddr) do
     begin
     if Pos('-', SAddr) > 0 then
     MacAddr[i] := StrToInt(HexDisplayPrefix + Copy(SAddr, 1, Pos('-', SAddr) - 1))
     else
     MacAddr[i] := StrToInt(HexDisplayPrefix + SAddr);
     Delete(SAddr, 1, Pos('-', SAddr));
     end;
     except
     ShowMessage(#13#10'网卡地址错误.');
     exit;
     end;
     try
     CheckWinSockResult(WSAStartup($0101, WSAData), 'WSAStartup');
     MSocket := socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
     if MSocket = INVALID_SOCKET then CheckWinSockResult(MSocket, 'socket');
     OptVal := 1;
     CheckWinSockResult(setsockopt(MSocket, SOL_SOCKET, SO_BROADCAST,
     PChar(@OptVal), SizeOf(OptVal)), 'setsockopt');
     FillChar(MagicData, SizeOf(MagicData), $FF);
     Position := LEN_PHYSADDR;
     while Position < SizeOf(MagicData) do
     begin
     Move(MacAddr, Pointer(Longint(@MagicData) + Position)^, LEN_PHYSADDR);
     Inc(Position, LEN_PHYSADDR);
     end;
     SockAddrIn.sin_family := AF_INET;
     SockAddrIn.sin_addr.S_addr := Longint(INADDR_BROADCAST);
     RetVal := sendto(MSocket, MagicData, SizeOf(MagicData), 0, SockAddrIn, SizeOf(SockAddrIn));
     if RetVal = SOCKET_ERROR then CheckWinSockResult(RetVal, 'sendto');
     CheckWinSockResult(closesocket(MSocket), 'closesocket');
     CheckWinSockResult(WSACleanup, 'WSACleanup');
     except
     exit;
     end;
    end;
    
    end.
    

此问题由傻猫回答。

附加关键字:编程, 源程序, programming, source code, Delphi, VCL, Borland, 网络与通信, network, communicate, com, com1, com2

 
把这个问题推荐给朋友
   
   
您的意见类别
您的名字
您的电子邮件
您的建议(请尽可能详细)
 
 

版权所有 1997-2008 热情软件屋
如果您有任何建议和意见, 请给我发个电子邮件 askpro@china-askpro.com
Web Designed by ZebraStudio