通過WIFI遠程喚醒(Wake-on-WLAN) Windows


Motivation

感謝學校的擴招,原本的兩人間硬是魔改成三人間,導致個人書桌面積小到兩台筆記本都放不下。無奈之下,淘了一個小桌板,正好能放一台筆記本。但隨着考試周的臨近,購入若干盒泡面准備進行修仙時才發現 沒!地!方!放!泡!面!

無奈之下,只能把Windows本本合上。

反正平時基本上都是遠程桌面連上去下迅雷或者推Gal。因此,需要一種機制能夠在機器關機的狀態下進行遠程喚醒,從而進行遠程桌面。Google后搜到Wake-on-LAN,是一種在機器處於休眠或關機狀態下通過網絡進行喚醒的技術。但筆記本沒有LAN口,是否能夠通過WLAN喚醒呢?繼續搜索,發現也是支持的!

Requirement

Wake-on-LAN / Wake-on-WLAN 需要主板和BIOS的支持。

根據Wiki,大概就是機器在休眠或關機時主板和網卡還保持微弱的供電,網卡會監聽廣播包,並對其進行解析。如果發現符合協議,並且MAC地址就是該網卡的MAC地址,則通知主板進行喚醒。

這種數據包被稱為Magic Packet,格式為:

FF FF FF FF FF FF MAC地址

因此通過構造Magic Packet,然后通過UDP進行廣播,即可實現喚醒的目的。

經過測試,在我的機器(XPS 9550)上,只能實現從睡眠(S3)和休眠(S4)狀態下喚醒,無法從關機(S5)狀態喚醒。

這符合Dell在 https://www.dell.com/support/article/us/en/19/SLN216918/newer-dell-system-models-will-not-wake-on-lan-with-deep-sleep-control-set-to-s5?lang=EN 的說明:

Newer Dell system models will not Wake-On-LAN with Deep Sleep Control set to S5

也符合Windows在 https://msdn.microsoft.com/en-us/library/windows/desktop/aa373229(v=vs.85).aspx#wake-on-lan_behavior 的說明:

WOL is supported from sleep (S3) or hibernate (S4). It is not supported from fast startup or soft off (S5) shutdown states. NICs are not armed for wake in these states because users do not expect their systems to wake up on their own.

Implementation

  1. 進入BIOS中,開啟 Wake on WLAN

  2. 進入Windows中,打開設備管理器,打開無線網卡的屬性,在電源管理的tab鈎上允許此設備喚醒計算機只允許幻數據包喚醒計算機后確定。

  3. 如果需要進入休眠(S4),需要在控制面板的電源選項下點擊更改當前不可用的設置,然后把休眠鈎上。

  4. 在網絡連接屬性處查詢無線網卡的MAC地址和局域網的廣播地址

  5. 睡眠/休眠,記得把電源插上

然后在另外一台電腦執行以下腳本,注意把MAC和BROADCAST改成你自己的:

# !/usr/bin/env python
# -*- coding: utf-8 -*-
#
# FileName:      wol.py
# Author:        binss
# Create:        2017-06-04 22:32:48
# Description:   Ref: https://github.com/bentasker/Wake-On-Lan-Python
#

import socket
import struct
import time


MAC = "60-6D-C4-C6-30-48"
BROADCAST = "192.168.1.255"


def main():
    if len(MAC) != 17:
        raise ValueError("MAC address should be set as form 'XX-XX-XX-XX-XX-XX'")
    mac_address = MAC.replace("-", '')
    data = ''.join(['FFFFFFFFFFFF', mac_address * 20])
    send_data = b''

    # Split up the hex values and pack.
    for i in range(0, len(data), 2):
        send_data = b''.join([send_data, struct.pack('B', int(data[i: i + 2], 16))])

    # Broadcast
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        sock.sendto(send_data, (BROADCAST, 7))
        time.sleep(1)
        sock.sendto(send_data, (BROADCAST, 7))
        time.sleep(1)
        sock.sendto(send_data, (BROADCAST, 7))
        print("Done")
    except Exception as e:
        print(e)


if __name__ == '__main__':
    main()

Troubleshoot執行后就可以發現機器被喚醒了。

為什么休眠后發現機器立刻被喚醒了?

通過powercfg -devicequery wake_armed發現喚醒設備除了無線網卡意外還有一個遠程桌面鼠標設備,不知道是干啥的,把鼠標拔掉后解決。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM