精华内容
下载资源
问答
  • WOL远程开机

    2014-06-11 14:14:25
    远程开机,适用方法 创建AndroidSystemService对象 AndroidSystemService obj = new AndroidSystemService(); // 调用开机方法 // 参数1:开机的机器的LAN MAC地址 ,也可以是一个LIST.那么第二个参数就应该是一个...
  • WOL远程开机——通过ESP8266+Binker平台实现 之前疫情现在家里,无聊时改装家里的吸顶灯入网时,寻找了各种物联网平台,最终找到了blinker(点灯)这个物联网平台,APP很简洁,同时提供方便的API接口,非常适于DIY。...

    WOL远程开机——通过ESP8266+blinker(点灯)平台实现

    之前疫情现在家里,无聊时改装家里的吸顶灯入网时,寻找了各种物联网平台,最终找到了blinker(点灯)这个物联网平台,APP很简洁,同时提供方便的API接口,非常适于DIY。
    然后就是这次的想法,开学后已经搞好了Teamview远程连接自己的实验室电脑,使自己在宿舍也能科(hua)研(shui),但又因为实验室电脑总是开着,感觉不舒服(毕竟是自己配的机子,不舍得一直烧着)。于是想着怎么远程开关机,淘宝上的向日葵开机棒一个108,看了看原理,发现身为一个电子专业的科研狗,买了就是交智商税,刚好想到了用前面提到的平台,就可以实现远程开机,最后成本就8块钱(或者不要钱,我的ESP8266是本科玩剩下的,用不完就送学弟了)。

    说明

    本方法适合没公网IP的、没自己服务器的、没高级路由器的三无玩家,有以上几个的也可以这么搞,但没必要,毕竟(教程一堆):

    1. 宽带是公网IP的直接走内网映射
    2. 有腾讯云、阿里云服务器的直接走转发
    3. 有高级路由器的(带WOL功能)直接设置
      但是如果图方便也可以

    预备知识

    1. 计算机网络基本知识
    2. C语言基本知识
    3. Arduino编程经验(没有也行)
      (如果是电子专业的,肯定没啥障碍)

    所需材料和前提

    前提

    1. 自己的电脑支持WOL
    2. 连着网的路由器
      (没有上面两个前提的可以直接放弃)

    材料

    1. 手机APP(blinker,Android & IOS 平台都有)
    2. ESP8266模块一个

    调试下载工具

    1. Arduino IDE平台(编译用)
    2. USB转TTL模块(下载用)

    原理

    如果有上述提到的预备知识,则整体原理会非常简单,一句话概括就是手机APP端发送MQTT包到ESP8266,ESP8266转发WOL的UDP包到本地子网。

    WOL

    WOL(Wake On LAN) 局域网唤醒,顾名思义,是一种在局域网内唤醒PC的一种技术。其主要原理是向本地子网内的机器广播一个包含有目标机器网卡MAC地址的一个UDP包(WOL魔术包),所有接收到的机器解析包中的MAC地址,匹配成功的网卡发送对应命令,开启电脑。

    Blinker平台

    Blinker平台简介其官网有具体的介绍(链接在这),在此就大致说明一下本方法所用到的原理即可。
    原理

    大致原理即如图所示,在局域网内网中,手机客户端直接通过局域网与ESP8266通讯,ESP8266接收到指令后进行WOL包的广播发送,在非局域网的远程连接中,ESP8266与Blinker服务器连接,同时手机客户端向Blinker服务器发送相关指令后,服务器转发给远端的ESP8266后,ESP8266发送WOL包唤醒电脑。

    步骤

    STEP1:设置WOL(实现内网唤醒)

    WOL在BIOS中设置,具体的机器需要具体设置,就是在BIOS中打开一个选项开关,具体步骤自己在BIOS中找,我的电脑的设置如下:
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    其次就是在Windows中设置网卡的步骤,设置步骤如下:
    首先在设备管理器中找到自己的以太网卡,找到连网线的那个网卡,进行如下操作:
    在这里插入图片描述

    然后继续在此页面下进行已下操作:
    在这里插入图片描述

    最后在网络和共享中心中查看自己网卡的MAC地址和IP地址:
    在这里插入图片描述

    全部设置正确后,便可以在本地局域网下进行设备唤醒了。
    iOS下的Wolow软件可以进行测试,在手机连接路由器后(手机,电脑在同一个子网下,同时路由器没有开启AP隔离功能(一般都不开启)),进入对应设置,点击唤醒电脑就可以唤醒了。

    注:最好在路由器中设置PC的IP与MAC绑定,方便后续的开机状态检查功能拓展,若不设置此项,开机功能可以用,但是可能无法进行设备开启状态检查!!!

    Wolow软件设置如下:

    首先添加新设备,界面如下:

    在这里插入图片描述

    接下来按照提示进行相关设置的填写,界面如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A03j8cz4-1598239993341)(\app2.jpg)]

    设置完成后进行测试,若PC没能启动检查是否有设置错误的地方,直到测试成功唤醒。

    STEP2:ESP8266程序编写 + Blinker设置(实现外网唤醒)

    先贴程序,对着程序进行解释:

    /**
     * 本项目简单的利用了blinker的Button例程,在客户端按下按键后,
     * 通过MQTT通知ESP8266触发按键处理函数,按键处理函数主要负责
     * 发送WOL的UDP魔术包,WOL魔术包格式如下
     * FF FF FF FF FF FF ( XX XX XX XX XX XX (网卡的MAC地址)) x 16
     * 包的总大小为 6+6*16 = 102 Byte 
    */
    
    #define BLINKER_WIFI
    
    #include <Blinker.h>
    
    //对应客户端的秘钥
    char auth[] = "************";
    //WIFI SSID
    char ssid[] = "XXXX";
    //WIFI Password
    char pswd[] = "XXXX";
    
    #define BUTTON_1 "OPEN"
    
    
    WiFiUDP Udp;
    //网卡的IP地址
    const IPAddress remote_ip(192, 168, 0, 1);
    //根据自己的路由器选择子网段的广播地址
    #define BROADCAST_ADD "192.168.1.255"
    //网卡唤醒端口(一般为9或7,可以在BIOS中查看)
    #define REMOTEPORT 9
    //ESP8266端口,随便填一个,也填成9
    #define LOCALPORT 9
    //网卡的MAC地址 6个字节    
    char NETCARD_MAC[6] = {0xAA,0xAA,0xAA,0xAA,0xAA,0xAA};
    //WOL包
    char WOL_Buffer[102];
    
    //调试开关
    //#define WOL_DEBUG
    
    //WOL魔术包初始化
    void WOL_packet_init()
    {
    	int i,j;
    	for(i=0;i<6;i++)
    	{
    	WOL_Buffer[i] = 0xFF;
    	}
    	for(i=1;i<17;i++)
    	{
    		for(j=0;j<6;j++)
    		{
    		WOL_Buffer[i*6 + j] = NETCARD_MAC[j];
    		}
    	}
    #ifdef WOL_DEBUG	
    	Serial.printf("The WOL packet is :\n");
    	for(i=0;i<102;i++){
    		Serial.printf("%x ",WOL_Buffer[i]);
    	}
    #endif
    }
    
    void WOL_packet_transfer()
    {
    #ifdef WOL_DEBUG	
    	Serial.printf("NOW is send WOL packet!\n");
    #endif
    	Udp.beginPacket(BROADCAST_ADD, REMOTEPORT);
    	Udp.write(WOL_Buffer);
    	Udp.endPacket();
    }
    
    BlinkerButton Button1(BUTTON_1);
    
    void button1_callback(const String & state)
    {
    	BLINKER_LOG("get button state: ", state);
    
    	if (state == BLINKER_CMD_BUTTON_TAP) {
    		BLINKER_LOG("Button tap!");
    		WOL_packet_transfer();
    		BLINKER_LOG("WOL Packet Transfer Completed!");
    	}
    	else {
    		BLINKER_LOG("Get user setting: ", state);
    	}
    }
    
    void dataRead(const String & data)
    {
    	BLINKER_LOG("Blinker readString: ", data);
    	Blinker.vibrate();
    	uint32_t BlinkerTime = millis();
    	Blinker.print("millis", BlinkerTime);
    }
    
    void setup()
    {
    	Serial.begin(115200);
    	BLINKER_DEBUG.stream(Serial);
    	Blinker.begin(auth, ssid, pswd);
    	Blinker.attachData(dataRead);
    	Button1.attach(button1_callback);
    	Udp.begin(LOCALPORT);
    	WOL_packet_init();
    }
    
    void loop()
    {
    	Blinker.run();
    #ifdef WOL_DEBUG
    	if((Serial.read() == 0x96) || digitalRead(0) == LOW){
    		WOL_packet_transfer();
    		while(digitalRead(0) == LOW){}
    	}
    #endif
    }
    

    (1)程序设置

    上述程序中,基本功能已经编写好,不想加新东西的话只需要设置以下几项:

    • 客户端相关设置(两项):

    设备注册使用:

    //对应客户端的秘钥
    char auth[] = "************";
    

    客户端里的按键的名字,注册按键处理回调函数使用。

    #define BUTTON_1 "OPEN"
    
    • 路由器相关设置(两项):

    路由器SSID:

    //WIFI SSID
    char ssid[] = "XXXX";
    

    路由器密码:

    //WIFI Password
    char pswd[] = "XXXX";
    

    路由器子网广播地址,将路由器网关地址最后换成255即就是广播地址

    //根据自己的路由器选择子网段的广播地址
    #define BROADCAST_ADD "192.168.1.255"
    
    • PC端相关设置(两项):

    网卡端口号,一般为7或者9,之前Wolow软件测试用到过。

    //网卡唤醒端口(一般为9或7,可以在BIOS中查看)
    #define REMOTEPORT 9
    

    PC网卡的MAC地址,之前测试用到过。

    //网卡的MAC地址 6个字节    
    char NETCARD_MAC[6] = {0xAA,0xAA,0xAA,0xAA,0xAA,0xAA};
    

    除了 客户端 相关的两项设置目前无法填写之外,其余的内容在之前的步骤中已经出现过,可以直接填写。

    (2)客户端APP设置

    首先打开Blinker的APP,没注册的先注册,然后开始设备申请流程:

    Step1:添加设备,选择Arduino设备

    在这里插入图片描述

    Step2:选择WIFI接入

    在这里插入图片描述

    Step3:得到设备秘钥,此秘钥对应着程序中的秘钥,直接复制进程序中即可。
    在这里插入图片描述

    Step4:返回主界面,点击进入申请号的设备中

    在这里插入图片描述

    Step5:点击右上角的编辑按键,进入编辑界面,然后添加一个按键,点击出现的按键进入按键设置中

    在这里插入图片描述

    Step6:在按键的基础设置中,首先设置数据键名,此键名为程序中客户端设置的第二个需要填写的项,将此项填入程序中,接着选择按键类型为普通按键即可,其余项目可以不用在意。设置完后保存,退出编辑界面。

    在这里插入图片描述

    Step7:完成APP设置后回到设备主界面,如下:

    至此,已经完成相关客户端的相关项设置。

    STEP3:程序烧写

    将前两步的相关设置填写入程序中,打开Arduino IDE进行程序烧写,需要提前设置IDE的环境,这里就不多讲了,Blinker的开发说明中有非常详细的安装操作步骤(连接在这),完成后点击编译下载进ESP8266模块中(使用IDE下载或使用官方的下载都行,都是通过串口下载,这个也就不多说了,毕竟网上关于ESP8266的资料漫天飞)。

    下载完成后,重新启动模块,等待模块连接WIFI成功,同时,在手机客户端可以看见之前的设备从离线状态变为在线状态,点击进入设备,点击按键(此时手机在内外网均可),不出意外,则PC成功启动。

    后续拓展功能

    Ping功能添加

    利用ESP8266去Ping电脑,在开机后,若可以Ping通,则证明已经开机成功。Ping时需要注意的是需要在开机后等待一段时间在去Ping,可以在APP中再定义一组按键来实现状态查询功能, 在状态检测按键按下后,ESP8266开始Ping主机IP,Ping通则利用Blinker的消息组件进行状态返回。
    已经测试成功,下面贴出完整的代码:

    #define BLINKER_WIFI
    
    #include <Blinker.h>
    #include <ESP8266Ping.h>
    
    //对应客户端的秘钥
    char auth[] = "XXXXXX";
    //WIFI SSID
    char ssid[] = "XXXXXX";
    //WIFI Password
    char pswd[] = "XXXXXX";
    
    #define BUTTON_1 "OPEN"
    
    #define BUTTON_2 "PC-Status"
    
    WiFiUDP Udp;
    //根据自己的路由器选择子网段的广播地址
    #define BROADCAST_ADD "192.168.XXX.255"
    //网卡唤醒端口(一般为9,可以在BIOS中查看)
    #define REMOTEPORT 9
    //PC端的IP地址(需要在路由器端进行MAC和IP绑定)
    const IPAddress remote_ip(192, 168, XXX, XXX);
    //本地UDP端口
    #define LOCALPORT 9
    //网卡的MAC地址 6个字节    
    char NETCARD_MAC[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
    //WOL包
    char WOL_Buffer[102];
    
    //WOL包发送完成标志
    int complete_flag = 0;
    //ping计数
    int ping_num = 0;
    
    //WOL魔术包初始化
    void WOL_packet_init()
    {
    	int i,j;
    	for(i=0;i<6;i++)
    	{
    	WOL_Buffer[i] = 0xFF;
    	}
    	for(i=1;i<17;i++)
    	{
    		for(j=0;j<6;j++)
    		{
    		WOL_Buffer[i*6 + j] = NETCARD_MAC[j];
    		}
    	}
    #ifdef WOL_DEBUG	
    	Serial.printf("The WOL packet is :\n");
    	for(i=0;i<102;i++){
    		Serial.printf("%x ",WOL_Buffer[i]);
    	}
    #endif
    }
    
    void WOL_packet_transfer()
    {
    #ifdef WOL_DEBUG	
    	Serial.printf("NOW is send WOL packet!\n");
    #endif
    	Udp.beginPacket(BROADCAST_ADD, REMOTEPORT);
    	Udp.write(WOL_Buffer);
    	Udp.endPacket();
    }
    
    BlinkerButton Button1(BUTTON_1);
    
    void button1_callback(const String & state)
    {
    	  BLINKER_LOG("get button1 state: ", state);
    
    	  if (state == BLINKER_CMD_BUTTON_TAP) {
    		BLINKER_LOG("Button1 tap!");
    		WOL_packet_transfer();
    		BLINKER_LOG("WOL Packet Transfer Completed!");
        complete_flag = 1;
        Blinker.notify("!Opening... Plase wait a moment");
    	}
    	else {
    		BLINKER_LOG("Get user setting: ", state);
    	}
    }
    
    
    BlinkerButton Button2(BUTTON_2);
    void button2_callback(const String & state)
    {
        BLINKER_LOG("get button2 state: ", state);
    
        if (state == BLINKER_CMD_BUTTON_TAP) {
        BLINKER_LOG("Button2 tap!");
        if(complete_flag){
          if(Ping.ping(remote_ip)){
            Blinker.notify("!PC Open Successful!");
            ping_num = 0;
            complete_flag = 0;
          }
          else{
            Blinker.notify("!Opening... Plase wait a moment");
            ping_num++;
            if(ping_num > 4){
              ping_num = 0;
              complete_flag = 0;
              Blinker.print("Open Failed,Plase tap button again!");
              Blinker.notify("!Open Failed,Plase tap button again");
            }
          }
        }
        else{
          Blinker.notify("!Plase tap button again!");
        }
      }
      else {
        BLINKER_LOG("Get user setting: ", state);
      }
    }
    
    void dataRead(const String & data)
    {
    	BLINKER_LOG("Blinker readString: ", data);
    	Blinker.vibrate();
    	uint32_t BlinkerTime = millis();
    	Blinker.print("millis", BlinkerTime);
    }
    
    void setup()
    {
    	Serial.begin(115200);
    	BLINKER_DEBUG.stream(Serial);
    	Blinker.begin(auth, ssid, pswd);
    	Blinker.attachData(dataRead);
    	Button1.attach(button1_callback);
      	Button2.attach(button2_callback);
    	Udp.begin(LOCALPORT);
    	WOL_packet_init();
    }
    
    void loop()
    {
    	Blinker.run();
    }
    

    APP界面如下:
    在这里插入图片描述

    补充说明

    这只是个简单的开机模块,至于远程开机有什么用,对于我来说就是配合Teamview实现在宿舍科研,远程跑个仿真啥的非常方便,不用的话可以在 power shell 中利用 shutdown -s 指令进行关机,减少机子的空耗时间,增加寿命。这只是个基础的版本,后面可以添加各种功能进行DIY,看各位发挥了!

    展开全文
  • java使用wol远程开机

    2021-04-16 06:50:46
    package com.meeno.framework.wol.params; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @Setter @Getter @NoArgsConstructor public class WolParam { /** ...

    param类

    package com.meeno.framework.wol.params;
    
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    
    @Setter
    @Getter
    @NoArgsConstructor
    public class WolParam {
    
        /**
         * ip
         */
        private String ip;
    
        /**
         * mac
         */
        private String mac;
    
        public WolParam(String ip, String mac) {
            this.ip = ip;
            this.mac = mac;
        }
    }

    WolUtils

    package com.meeno.framework.wol;
    
    import com.meeno.framework.wol.params.WolParam;
    import org.springframework.util.CollectionUtils;
    
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;
    
    public class WolUtils {
    
    
        /**
         * 批量唤醒
         * @param params
         */
        public static void batchWake(WolParam... params){
            if(params != null && params.length != 0){
                List<WolParam> list = Arrays.stream(params).collect(Collectors.toList());
                batchWake(list);
            }
        }
    
        /**
         * 批量唤醒
         * @param list
         */
        public static void batchWake(List<WolParam> list){
            if(!CollectionUtils.isEmpty(list)){
                for (WolParam wolParam : list) {
                    wake(wolParam.getIp(), wolParam.getMac(), 4343);
                }
            }
        }
    
        /**
         * 唤醒
         * @param ip
         * @param macAddr
         * @param port
         */
        // 魔术包的组成
        // 魔术包的组成非常固定,由6对“FF”组成前缀,其余为重复16次的MAC地址组成。例如:试验机的MAC为:“28-D2-44-35-68-A7”,那么魔术包为:
        // “0xFFFFFFFFFFFF28D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A728D2443568A7”
        public static void wake(String ip, String macAddr, int port){
            try {
                //String ip = "192.168.0.72";
                //mac地址
                //String macAddr = "70-85-C2-8E-36-0B";
                //端口
                //int port = 4343;
                byte[] macByte = new byte[6];
                String[] ips = macAddr.split("\\:|\\-");
                for (int i = 0; i < 6; i++) {
                    macByte[i] = (byte) Integer.parseInt(ips[i], 16);
                }
                // 用来存储网络唤醒数据包
                byte[] bys = new byte[6 + 16 * macByte.length];
                for (int i = 0; i < 6; i++) {
                    bys[i] = (byte) 0xff;
                }
                for (int i = 6; i < bys.length; i += macByte.length) {
                    System.arraycopy(macByte, 0, bys, i, macByte.length);
                }
                // 将字符形式的IP地址转换成标准的IP地址
                InetAddress address = InetAddress.getByName(ip);
                // 生成标准的数据报
                DatagramPacket pack = new DatagramPacket(bys, bys.length, address, port);
                // 创建标准套接字,用来发送数据报
                DatagramSocket socket = new DatagramSocket();
                // 发送魔法包
                socket.send(pack);
                socket.close();
                System.out.println("发送结束");
            } catch (Exception e) {
                e.printStackTrace();
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
    
       public static void main(String[] args) {
            batchWake(new WolParam("192.168.0.72","70-85-C2-8E-36-0B"));
        }
    
    }
    展开全文
  • wol 远程开机编译源码

    千次阅读 2016-06-15 12:30:35
    gcc -g -p -o wol wol.c 生成wol可执行文件 ./wol MAC 地址即可远程开机 下面是源码:   /* ether-wake.c: Send a magic packet to wake up sleeping machines. */ static char version_msg[] = "ether-wak

    直接gcc 编译源码生成可执行文件,免安装
    gcc -g -p -o wol wol.c 生成wol可执行文件 ./wol MAC 地址即可远程开机

    下面是源码:

     

    /* ether-wake.c: Send a magic packet to wake up sleeping machines. */

    static char version_msg[] =
    "ether-wake.c: v1.09 11/12/2003 Donald Becker, http://www.scyld.com/";
    static char brief_usage_msg[] =
    "usage: ether-wake [-i <ifname>] [-p aa:bb:cc:dd[:ee:ff]] 00:11:22:33:44:55\n"
    "   Use '-u' to see the complete set of options.\n";
    static char usage_msg[] =
    "usage: ether-wake [-i <ifname>] [-p aa:bb:cc:dd[:ee:ff]] 00:11:22:33:44:55\n"
    "\n"
    "        This program generates and transmits a Wake-On-LAN (WOL)\n"
    "        \"Magic Packet\", used for restarting machines that have been\n"
    "        soft-powered-down (ACPI D3-warm state).\n"
    "        It currently generates the standard AMD Magic Packet format, with\n"
    "        an optional password appended.\n"
    "\n"
    "        The single required parameter is the Ethernet MAC (station) address\n"
    "        of the machine to wake or a host ID with known NSS 'ethers' entry.\n"
    "        The MAC address may be found with the 'arp' program while the target\n"
    "        machine is awake.\n"
    "\n"
    "        Options:\n"
    "                -b        Send wake-up packet to the broadcast address.\n"
    "                -D        Increase the debug level.\n"
    "                -i ifname        Use interface IFNAME instead of the default 'eth0'.\n"
    "                -p <pw>                Append the four or six byte password PW to the packet.\n"
    "                                        A password is only required for a few adapter types.\n"
    "                                        The password may be specified in ethernet hex format\n"
    "                                        or dotted decimal (Internet address)\n"
    "                -p 00:22:44:66:88:aa\n"
    "                -p 192.168.1.1\n";

    /*
            This program generates and transmits a Wake-On-LAN (WOL) "Magic Packet",
            used for restarting machines that have been soft-powered-down
            (ACPI D3-warm state).  It currently generates the standard AMD Magic Packet
            format, with an optional password appended.

            This software may be used and distributed according to the terms
            of the GNU Public License, incorporated herein by reference.
            Contact the author for use under other terms.

            This source file was originally part of the network tricks package, and
            is now distributed to support the Scyld Beowulf system.
            Copyright 1999-2003 Donald Becker and Scyld Computing Corporation.

            The author may be reached as becker@scyld, or C/O
             Scyld Computing Corporation
             914 Bay Ridge Road, Suite 220
             Annapolis MD 21403

      Notes:
      On some systems dropping root capability allows the process to be
      dumped, traced or debugged.
      If someone traces this program, they get control of a raw socket.
      Linux handles this safely, but beware when porting this program.

      An alternative to needing 'root' is using a UDP broadcast socket, however
      doing so only works with adapters configured for unicast+broadcast Rx
      filter.  That configuration consumes more power.
    */

    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <ctype.h>
    #include <string.h>

    #if 0                                                        /* Only exists on some versions. */
    #include <ioctls.h>
    #endif

    #include <sys/socket.h>

    #include <sys/types.h>
    #include <sys/ioctl.h>
    #include <linux/if.h>

    #include <features.h>
    #if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
    #include <netpacket/packet.h>
    #include <net/ethernet.h>
    #else
    #include <asm/types.h>
    #include <linux/if_packet.h>
    #include <linux/if_ether.h>
    #endif
    #include <netdb.h>
    #include <netinet/ether.h>

    /* Grrr, no consistency between include versions.
       Enable this if setsockopt() isn't declared with your library. */
    #if 0
    extern int setsockopt __P ((int __fd, int __level, int __optname,
                                                            __ptr_t __optval, int __optlen));
    #else                                /* New, correct head files.  */
    #include <sys/socket.h>
    #endif

    u_char outpack[1000];
    int outpack_sz = 0;
    int debug = 0;
    u_char wol_passwd[6];
    int wol_passwd_sz = 0;

    static int opt_no_src_addr = 0, opt_broadcast = 0;

    static int get_dest_addr(const char *arg, struct ether_addr *eaddr);
    static int get_fill(unsigned char *pkt, struct ether_addr *eaddr);
    static int get_wol_pw(const char *optarg);

    int main(int argc, char *argv[])
    {
            char *ifname = "eth0";
            int one = 1;                                /* True, for socket options. */
            int s;                                                /* Raw socket */
            int errflag = 0, verbose = 0, do_version = 0;
            int perm_failure = 0;
            int i, c, pktsize;
    #if defined(PF_PACKET)
            struct sockaddr_ll whereto;
    #else
            struct sockaddr whereto;        /* who to wake up */
    #endif
            struct ether_addr eaddr;

            while ((c = getopt(argc, argv, "bDi:p:uvV")) != -1)
                    switch (c) {
                    case 'b': opt_broadcast++;        break;
                    case 'D': debug++;                        break;
                    case 'i': ifname = optarg;        break;
                    case 'p': get_wol_pw(optarg); break;
                    case 'u': printf(usage_msg); return 0;
                    case 'v': verbose++;                break;
                    case 'V': do_version++;                break;
                    case '?':
                            errflag++;
                    }
            if (verbose || do_version)
                    printf("%s\n", version_msg);
            if (errflag) {
                    fprintf(stderr, brief_usage_msg);
                    return 3;
            }

            if (optind == argc) {
                    fprintf(stderr, "Specify the Ethernet address as 00:11:22:33:44:55.\n");
                    return 3;
            }

            /* Note: PF_INET, SOCK_DGRAM, IPPROTO_UDP would allow SIOCGIFHWADDR to
               work as non-root, but we need SOCK_PACKET to specify the Ethernet
               destination address. */
    #if defined(PF_PACKET)
            s = socket(PF_PACKET, SOCK_RAW, 0);
    #else
            s = socket(AF_INET, SOCK_PACKET, SOCK_PACKET);
    #endif
            if (s < 0) {
                    if (errno == EPERM)
                            fprintf(stderr, "ether-wake: This program must be run as root.\n");
                    else
                            perror("ether-wake: socket");
                    perm_failure++;
            }
            /* Don't revert if debugging allows a normal user to get the raw socket. */
            setuid(getuid());

            /* We look up the station address before reporting failure so that
               errors may be reported even when run as a normal user.
            */
            if (get_dest_addr(argv[optind], &eaddr) != 0)
                    return 3;
            if (perm_failure && ! debug)
                    return 2;

            pktsize = get_fill(outpack, &eaddr);

            /* Fill in the source address, if possible.
               The code to retrieve the local station address is Linux specific. */
            if (! opt_no_src_addr) {
                    struct ifreq if_hwaddr;
                    unsigned char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data;

                    strcpy(if_hwaddr.ifr_name, ifname);
                    if (ioctl(s, SIOCGIFHWADDR, &if_hwaddr) < 0) {
                            fprintf(stderr, "SIOCGIFHWADDR on %s failed: %s\n", ifname,
                                            strerror(errno));
                            /* Magic packets still work if our source address is bogus, but
                               we fail just to be anal. */
                            return 1;
                    }
                    memcpy(outpack+6, if_hwaddr.ifr_hwaddr.sa_data, 6);

                    if (verbose) {
                            printf("The hardware address (SIOCGIFHWADDR) of %s is type %d  "
                                       "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n", ifname,
                                       if_hwaddr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1],
                                       hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
                    }
            }

            if (wol_passwd_sz > 0) {
                    memcpy(outpack+pktsize, wol_passwd, wol_passwd_sz);
                    pktsize += wol_passwd_sz;
            }

            if (verbose > 1) {
                    printf("The final packet is: ");
                    for (i = 0; i < pktsize; i++)
                            printf(" %2.2x", outpack[i]);
                    printf(".\n");
            }

            /* This is necessary for broadcasts to work */
            if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&one, sizeof(one)) < 0)
                    perror("setsockopt: SO_BROADCAST");

    #if defined(PF_PACKET)
            {
                    struct ifreq ifr;
                    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
                    if (ioctl(s, SIOCGIFINDEX, &ifr) == -1) {
                            fprintf(stderr, "SIOCGIFINDEX on %s failed: %s\n", ifname,
                                            strerror(errno));
                            return 1;
                    }
                    memset(&whereto, 0, sizeof(whereto));
                    whereto.sll_family = AF_PACKET;
                    whereto.sll_ifindex = ifr.ifr_ifindex;
                    /* The manual page incorrectly claims the address must be filled.
                       We do so because the code may change to match the docs. */
                    whereto.sll_halen = ETH_ALEN;
                    memcpy(whereto.sll_addr, outpack, ETH_ALEN);

            }
    #else
            whereto.sa_family = 0;
            strcpy(whereto.sa_data, ifname);
    #endif

            if ((i = sendto(s, outpack, pktsize, 0, (struct sockaddr *)&whereto,
                                            sizeof(whereto))) < 0)
                    perror("sendto");
            else if (debug)
                    printf("Sendto worked ! %d.\n", i);

    #ifdef USE_SEND
            if (bind(s, (struct sockaddr *)&whereto, sizeof(whereto)) < 0)
                    perror("bind");
            else if (send(s, outpack, 100, 0) < 0)
                    perror("send");
    #endif
    #ifdef USE_SENDMSG
            {
                    struct msghdr msghdr = { 0,};
                    struct iovec iovector[1];
                    msghdr.msg_name = &whereto;
                    msghdr.msg_namelen = sizeof(whereto);
                    msghdr.msg_iov = iovector;
                    msghdr.msg_iovlen = 1;
                    iovector[0].iov_base = outpack;
                    iovector[0].iov_len = pktsize;
                    if ((i = sendmsg(s, &msghdr, 0)) < 0)
                            perror("sendmsg");
                    else if (debug)
                            printf("sendmsg worked, %d (%d).\n", i, errno);
            }
    #endif

            return 0;
    }

    /* Convert the host ID string to a MAC address.
       The string may be a
            Host name
        IP address string
            MAC address string
    */

    static int get_dest_addr(const char *hostid, struct ether_addr *eaddr)
    {
            struct ether_addr *eap;

            eap = ether_aton(hostid);
            if (eap) {
                    *eaddr = *eap;
                    if (debug)
                            fprintf(stderr, "The target station address is %s.\n",
                                            ether_ntoa(eaddr));
            } else if (ether_hostton(hostid, eaddr) == 0) {
                    if (debug)
                            fprintf(stderr, "Station address for hostname %s is %s.\n",
                                            hostid, ether_ntoa(eaddr));
            } else {
                    (void)fprintf(stderr,
                                              "ether-wake: The Magic Packet host address must be "
                                              "specified as\n"
                                              "  - a station address, 00:11:22:33:44:55, or\n"
                                              "  - a hostname with a known 'ethers' entry.\n");
                    return -1;
            }
            return 0;
    }


    static int get_fill(unsigned char *pkt, struct ether_addr *eaddr)
    {
            int offset, i;
            unsigned char *station_addr = eaddr->ether_addr_octet;

            if (opt_broadcast)
                    memset(pkt+0, 0xff, 6);
            else
                    memcpy(pkt, station_addr, 6);
            memcpy(pkt+6, station_addr, 6);
            pkt[12] = 0x08;                                /* Or 0x0806 for ARP, 0x8035 for RARP */
            pkt[13] = 0x42;
            offset = 14;

            memset(pkt+offset, 0xff, 6);
            offset += 6;

            for (i = 0; i < 16; i++) {
                    memcpy(pkt+offset, station_addr, 6);
                    offset += 6;
            }
            if (debug) {
                    fprintf(stderr, "Packet is ");
                    for (i = 0; i < offset; i++)
                            fprintf(stderr, " %2.2x", pkt[i]);
                    fprintf(stderr, ".\n");
            }
            return offset;
    }

    static int get_wol_pw(const char *optarg)
    {
            int passwd[6];
            int byte_cnt;
            int i;

            byte_cnt = sscanf(optarg, "%2x:%2x:%2x:%2x:%2x:%2x",
                                              &passwd[0], &passwd[1], &passwd[2],
                                              &passwd[3], &passwd[4], &passwd[5]);
            if (byte_cnt < 4)
                    byte_cnt = sscanf(optarg, "%d.%d.%d.%d",
                                                      &passwd[0], &passwd[1], &passwd[2], &passwd[3]);
            if (byte_cnt < 4) {
                    fprintf(stderr, "Unable to read the Wake-On-LAN password.\n");
                    return 0;
            }
            printf(" The Magic packet password is %2.2x %2.2x %2.2x %2.2x (%d).\n",
                       passwd[0], passwd[1], passwd[2], passwd[3], byte_cnt);
            for (i = 0; i < byte_cnt; i++)
                    wol_passwd[i] = passwd[i];
            return wol_passwd_sz = byte_cnt;
    }

    #if 0
    {
            to = (struct sockaddr_in *)&whereto;
            to->sin_family = AF_INET;
            if (inet_aton(target, &to->sin_addr)) {
                    hostname = target;
            }
            memset (&sa, 0, sizeof sa);
            sa.sa_family = AF_INET;
            strncpy (sa.sa_data, interface, sizeof sa.sa_data);
            sendto (sock, buf, bufix + len, 0, &sa, sizeof sa);
            strncpy (sa.sa_data, interface, sizeof sa.sa_data);
    #if 1
            sendto (sock, buf, bufix + len, 0, &sa, sizeof sa);
    #else
            bind (sock, &sa, sizeof sa);
            connect();
            send (sock, buf, bufix + len, 0);
    #endif
    }
    #endif


    /*
    * Local variables:
    *  compile-command: "gcc -O -Wall -o ether-wake ether-wake.c"
    *  c-indent-level: 4
    *  c-basic-offset: 4
    *  c-indent-level: 4
    *  tab-width: 4
    * End:
    */

     

     

    展开全文
  • 终于鼓捣出来了,完美通过4g网络和手机app实现远程开机,现在这里记录一下教程。需要:路由器网线接电脑,公网ip或者ipv61.电脑设置主板(华硕)bios—高级—电源设置—wake on PCIE 开启系统网卡驱动升级到最新,...

    终于鼓捣出来了,完美通过4g网络和手机app实现远程开机,现在这里记录一下教程。

    需要:路由器网线接电脑,公网ip或者ipv6

    1.电脑设置

    主板(华硕)bios—高级—电源设置—wake on PCIE 开启

    系统网卡驱动升级到最新,否则设备管理器内可能没有“电源管理”

    我的电脑—右键属性—设备管理器—网络适配器—有线网卡(Rea开头的)—电源管理—三个全打勾

    系统防火墙—网络—高级设置—入站规则—添加入站规则—端口填9,选udp、公用、所有ip可访问,自动连接等等……

    下载wake on lan软件,里面有一个检测封包的功能,以便你可以用电脑在开机时测试能不能接受到外网发来的幻数据包,软件图标如下图

    99c46e161e010410514f51ee0e9571d2.png

    软件内界面大概是这样

    3d349cf12ab90e522e3813fc157ef72f.png

    2.路由器设置(tp link)

    查询路由器内拨号自动获取的ipv4地址,百度搜ip看自己的外网地址,如果两个一样说明你有公网ip

    我是校园网,支持ipv6,前期一直获取不到地址,后来解决了原因是:我们学校只支持一个网口分配一个ipv6地址,但是路由器却等着网口给一个地址前缀然后自己再分后面的地址来给局域网用,两个矛盾了当然分不成地址了。解决方法:高级设置里选“无状态分配”(s开头的一个),非dhcp,就是说路由器只获取一个固定ipv6,不要PD前缀

    路由器—内置ddns应用—注册花生壳/tplink账号送域名(我觉得花生壳的好用一点)设置好域名就可以了

    路由器—arp绑定应用—给需要开机的电脑mac和任意内网的ip地址绑定在一起

    路由器—虚拟服务器应用—设置端口转发—服务器空着,内外端口均填9,协议选all(或者udp),ip设置为上面绑定mac的ip

    路由器—dmz主机应用—设置为上面的ip(这条可能非必须)

    3.手机app设置

    试了好几个app,有的不支持输入域名(只能app),有的广域网总是发不出信号,所以推荐我最后成功的一款,无论是我用内网穿透还是上面说的ddns解析域名都可以成功接受到信号

    b1003d86cd154c45ba76d34b81b29a5d.png

    其他:

    1.我的ddns应该用的是公网ipv4而非ipv6,在某些wol 的app看到域名被解析成了我的ipv4地址,虽然我也有ipv6但是还没用上,如果配合阿里云去注册一个域名应该可以派上用场

    2.最后测试一定不要接wifi,要用4g,否则你看到的成功都是其实都是骗你的

    3.如果局域网内wol也出现问题先关闭下快速启动试试,控制面板—电源—电源按钮功能—更改不可用设置—关闭快速启动

    4.有些人想用无线网卡wol,即使在设备管理器里看到有电源管理可以设置为“幻数据包唤醒”,也很有可能不会成功(蒲公英路由器在淘宝详情页也强调了,远程开机仅支持有线连接,这是一个道理)

    5.免费的内网穿透

    强烈推荐sakurafrp,每天签到送几个g流量,就算一天挂12个小时我估计都用不完,就是相当于免费了。这个软件360会报毒,不用当回事。

    为什么用这个软件呢,因为你在测试电脑能不能检测到udp包的时候,一开始失败肯定很难找到问题,尤其是不知道问题出在网络上还是路由器上还是下载的手机app上还是电脑的系统设置上。这个软件的作用就相当于保证你的网络肯定是没问题的,如果再失败那就是你手机app或者路由器端口转发或者电脑系统设置的问题(毕竟网络的问题总是最难解决的,也是最怕出问题的)。

    6.其他的远程开机方法

    1)开机棒

    淘宝搜索可买,使用方法接到主板上对应引脚,通过内置wifi芯片和天线连接到他们的服务器帮你送达开机命令(笔记本安装比较麻烦)

    2)智能插座

    淘宝可买,推荐小米的,使用方法:主板开始来电自启,米家里给插座设置wifi就可以远程控制其开关。不过不适用与笔记本(一般笔记本不支持来电自启)

    3)usb唤醒

    淘宝搜索,只有一家有卖,原理同1)不过是退而求其次的方法,只能做到睡眠中唤醒而不能开机唤醒,唤醒电脑后再配合远程软件。

    (有的人可能会说我睡眠时也可以用远程直接连电脑,那是因为你的电脑是假睡眠,需要在注册表里改个设置,真睡眠只有内存供着电,你的电脑内任何软件都相当于断网状态)

    展开全文
  • 转自:... 今天发现个可以对linux服务器进行远程开机的软件-wakeonlan,软件可在 http://sourceforge.net/projects/wake-on-lan/下载。通过wakeonlan,可以启动已关闭的linux服务器,这对一些没有I...
  • WOL远程开机启动

    千次阅读 2011-04-05 14:53:00
    前些天,听wanglin说可以通过设置网卡来远程开机,今天上网特意搜了搜,发现确实有方法可以,具体步骤如下: 一,重启电脑,进入BIOS设置,找到相关的主板启动项,叫做power up by ring,设置为enable...
  • 今天发现个可以对linux服务器进行远程开机的软件-wakeonlan,软件可在http://sourceforge.net/projects/wake-on-lan/下载。通过wakeonlan,可以启动已关闭的linux服务器,这对一些没有ILO口等远程管理的服务器非常...
  • 远程开机(外网WOL远程唤醒)

    万次阅读 2019-11-22 20:53:57
    PS:远程唤醒的要求 1.首先,我们要在主板 BIOS 里面设置 WOL 唤醒功能的开关,大部分主板都会支持唤醒 2.电脑的主板和网卡需要支持网络唤醒。一般无线网卡是不支持的,板载的有线网卡一般是可以的。 3.所在网络...
  • wol远程开机

    2018-08-08 01:54:44
    什么是远程开机以及它的使用场景 远程开机就是利用网卡特性唤醒关机或睡眠状态下的电脑,意义就是不用手动开机了,甚至可以外网远程唤醒计算机,大多数人并没有这种使用场景,但是对于需要控制的服务器来说是很有...
  • wol-0.7.1远程开机

    2016-10-15 11:30:34
    linux WOL远程唤醒 1、运行ethtool命令查看网卡是否支持Wake On Lan Supports Wake-on: pumbg Wake-on: d 若Wake-on为d,表示禁用Wake On LAN,需要启用它。 如果已经是g就说明目标机器的网卡已经支持Wake On...
  • 远程开机WOL

    千次阅读 2011-01-18 15:35:00
    远程唤醒技术,英文简称WOL,即Wake-on-LAN,是指可以通过局域网实现远程开机,无论被访问的计算机离用户有多远、处于什么位置,只要处于同一局域网内,就都能够被随时启动。 人们通常也把这种开机...
  • WOL远程唤醒

    2020-11-18 21:37:39
    WOL远程唤醒 1.什么是WOL? Wake-on-LAN简称WOL,中文译为“网络唤醒”、“远端唤醒”技术。 WOL是一种技术,同时也是该技术的规范标准,它的功能在于让已经进入休眠状态或关机状态的设备(如电脑、NAS等),透过...
  • WOL实现远程开机分为3大步。 魔术包Magic Packet 第一步:设置主机的有线网卡Wake on Magic Package属性为Enable。 1.首先进入cmd命令窗口,查看自己的有线网卡的ip地址和mac地址,写java程序时需要使用。 2....
  • 很多使用WOL远程唤醒软件的用户们都不知道怎么开启WOL网络唤醒远程开机功能,有这软件也用不了啊!今天小编就给大家介绍怎样才能设置电脑远程唤醒,不同牌子的主板、网卡、路由器在选项设置的名称和位置上都基本都不...
  • 命令行远程开机程序wol.exe

    热门讨论 2008-10-17 21:14:05
    命令行远程开机程序,输入wol /?查看帮助
  • 现在主板都支持网卡远程唤醒功能,要是用远程唤醒功能。具体如下操作: ...4.静态绑定IP,这样就可以通过wake on lan 局域网远程唤醒开机了。但外网远程唤醒还需要有公网IP和路由器端口映射下。 如果要外.
  • Win10怎么开启WOL网络唤醒远程开机功能?网络唤醒是一种利用网络远程唤醒计算机的技术,不过需要ATX电源及主板的软硬件支持。相信还有很多伙伴都不懂要如何开启WOL网络唤醒开机功能吧?其实方法有很多,比如我们可以...

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 204
精华内容 81
关键字:

wol远程开机