Motivation
感謝學校的擴招,本來的兩人間硬是魔改爲三人間,致使我的書桌面積小到兩臺筆記本都放不下。無奈之下,淘了一個小桌板,正好能放一臺筆記本。但隨着考試周的臨近,購入若干盒泡麪準備進行修仙時才發現 沒!地!方!放!泡!面!python
無奈之下,只能把Windows本本合上。git
反正平時基本上都是遠程桌面連上去下迅雷或者推Gal。所以,須要一種機制可以在機器關機的狀態下進行遠程喚醒,從而進行遠程桌面。Google後搜到Wake-on-LAN,是一種在機器處於休眠或關機狀態下經過網絡進行喚醒的技術。但筆記本沒有LAN口,是否可以經過WLAN喚醒呢?繼續搜索,發現也是支持的!github
Requirement
Wake-on-LAN / Wake-on-WLAN 須要主板和BIOS的支持。windows
根據Wiki,大概就是機器在休眠或關機時主板和網卡還保持微弱的供電,網卡會監聽廣播包,並對其進行解析。若是發現符合協議,而且MAC地址就是該網卡的MAC地址,則通知主板進行喚醒。網絡
這種數據包被稱爲Magic Packet,格式爲:socket
FF FF FF FF FF FF MAC地址post
所以經過構造Magic Packet,而後經過UDP進行廣播,便可實現喚醒的目的。測試
通過測試,在個人機器(XPS 9550)上,只能實現從睡眠(S3)和休眠(S4)狀態下喚醒,沒法從關機(S5)狀態喚醒。ui
這符合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 的說明:url
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
-
進入BIOS中,開啓 Wake on WLAN
-
進入Windows中,打開設備管理器,打開無線網卡的屬性,在電源管理的tab鉤上
容許此設備喚醒計算機
和只容許幻數據包喚醒計算機
後肯定。 -
若是須要進入休眠(S4),須要在控制面板的電源選項下點擊
更改當前不可用的設置
,而後把休眠
鉤上。 -
在網絡鏈接屬性處查詢無線網卡的MAC地址和局域網的廣播地址
- 睡眠/休眠,記得把電源插上
而後在另一臺電腦執行如下腳本,注意把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
發現喚醒設備除了無線網卡意外還有一個遠程桌面鼠標設備,不知道是幹啥的,把鼠標拔掉後解決。