python局域网内唤醒设备

发布于:2025-02-10 ⋅ 阅读:(70) ⋅ 点赞:(0)
# !/usr/bin/env python
# -*- coding:utf-8 -*-
# @FileName  :restart_host.py
# @Time      :2025/1/17 11:48

import socket
import time
import struct
import traceback


def wake_up(mac='48-XX-0B-5E-AC-36'):
    MAC = mac
    BROADCAST = "192.168.25.255"
    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''

    # 把原始数据转换为16进制字节数组,
    for i in range(0, len(data), 2):
        send_data = b''.join([send_data, struct.pack('B', int(data[i: i + 2], 16))])
    # print(send_data)

    # 通过socket广播出去,为避免失败,间隔广播三次
    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(traceback.format_exc())


wake_up()

这段代码的功能是实现Wake-on-LAN(WOL,局域网内唤醒设备)功能,能够通过广播特定的Magic Packet来唤醒指定MAC地址的设备。

1. 引入模块

import socket
import time
import struct
import traceback
  • socket:用于创建网络连接、发送数据和接收数据。
  • time:用于实现延时(sleep),控制发送Magic Packet的间隔。
  • struct:用于将数据转换为二进制格式。这里用来将构造的十六进制数据转换为字节数组。
  • traceback:用于在出现异常时输出错误信息的详细堆栈。

2. wake_up 函数

def wake_up(mac='48-XX-0B-5E-AC-36'):
  • 该函数接受一个MAC地址参数(默认为 '48-XX-0B-5E-AC-36'),并将该MAC地址作为目标设备的标识来发送Magic Packet。

3. 检查MAC地址格式

if len(MAC) != 17:
    raise ValueError("MAC address should be set as form 'XX-XX-XX-XX-XX-XX'")
  • MAC地址验证:确保传入的MAC地址的长度为17个字符(6组2位十六进制字符,用连字符-分隔)。

4. 构造Magic Packet

mac_address = MAC.replace("-", '')
data = ''.join(['FFFFFFFFFFFF', mac_address * 20])
  • MAC地址格式化replace("-", '') 去除MAC地址中的连接符,转换为没有连接符的连续字符。
  • Magic Packet构造
    • FFFFFFFFFFFF 是固定的前导部分,表示Wake-on-LAN的开始标志。
    • mac_address * 20 将目标MAC地址重复20次,构成Magic Packet的后续部分。WOL的Magic Packet结构要求将MAC地址重复20次来确保正确识别。

5. 将Magic Packet转换为字节格式

send_data = b''

for i in range(0, len(data), 2):
    send_data = b''.join([send_data, struct.pack('B', int(data[i: i + 2], 16))])
  • 字节数组构造:遍历构建的十六进制字符串data,将每两个字符转换为一个字节并组合成字节数组send_datastruct.pack('B', ...) 是将每一对十六进制字符转换为字节的操作。

6. 通过Socket广播Magic Packet

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(traceback.format_exc())
  • 创建Socketsocket.socket(socket.AF_INET, socket.SOCK_DGRAM) 创建一个UDP协议的IPv4 socket。

  • 设置广播选项sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) 设置socket选项,允许发送广播消息。

  • 发送Magic Packet

    • sock.sendto(send_data, (BROADCAST, 7)) 通过UDP广播的方式将Magic Packet发送到广播地址 192.168.25.255,端口使用7(WOL通常使用该端口)。
    • 三次发送:为了增加唤醒设备的成功率,Magic Packet被发送三次,每次发送之间暂停1秒钟。

    time.sleep(1) 是让程序在发送每个Magic Packet之间等待1秒,避免发送过快。

  • 异常处理:如果发生任何异常,使用traceback.format_exc() 输出详细的错误堆栈信息。

7. 调用 wake_up 函数

wake_up()
  • 最后,调用 wake_up 函数来实际执行唤醒操作,默认使用给定的MAC地址。

总结

这段代码通过UDP广播的方式发送Magic Packet来实现Wake-on-LAN功能,能够在局域网中唤醒目标MAC地址的计算机。它首先构建一个符合WOL协议的Magic Packet,然后通过网络广播的方式三次发送该数据包,以提高唤醒成功的概率。

在使用这段代码时,通常需要确保目标机器支持Wake-on-LAN,并且已经在网络设置和BIOS中启用了相应的功能。


网站公告

今日签到

点亮在社区的每一天
去签到