golang---实现wake on lan

该文描述了一个实现通过UDP发送魔术包到广播地址255.255.255.255:9来唤醒具有Wake-on-LAN功能的主机的过程。主机需预先配置并保持有线连接。程序需指定正确的MAC地址和发送网卡,确保数据包能送达目标主机。
摘要由CSDN通过智能技术生成

实现逻辑

就是通过UDP向广播地址255.255.255.255:9发送一个称为“魔术包”的数据包。被唤醒主机关机之后需要和程序所在主机通过网线连接,才能收到这个数据包。被唤醒主机收到之后就会开机。

配置需要被唤醒的主机

我的台式主机试DELL的,dell官网有相关的配置方法,其他的可能有区别需要查询
我的主机配置方法

实施唤醒操作的程序

要注意的是:程序所在的主机,要确保一定有一次的数据包是通过那个有限网卡发出去的,可以在程序中指定从哪个网卡发出,或者控制主机的无线网络,或者每个网卡都发一次
指定网卡发送UDP数据包


var help = `
环境说明:
    1. 被唤醒主机要支持Wake on Lan功能且已开启该功能
    2. 被唤醒主机在关机时应该是有线连接
    3. 请确保该程序与被唤醒主机在同一局域网中
参数说明:
    -mac 被唤醒主机的MAC地址 (必须输入)
    -nic 指定网卡发送唤醒魔包
使用说明:
    wol -mac 11:22:33:44:55:66 -nic eno1
注意事项:
    1. 路由器设备或有些主机有多张网卡, 如果不指定网卡唤醒魔包可能到达不了被唤醒主机
    2. MAC地址的格式可以是以下几种形式
        11:22:33:44:55:66 或
        11-22-33-44-55-66 或
        11:22-33:44:55-66 或
        112233445566
`
func main() {
	err := wakeNew()
	fmt.Println("wakeNew  err = ", err)
}

func wakeNew() error {
	macAddr := flag.String("mac", "xx:xx:xx:xx:xx:xx", help)//被唤醒主机的MAC地址,这里通过一条网线连接的,可以在网络适配器看见整个以太网地址
	nic := flag.String("nic", "以太网 2", help)
	flag.Parse()
	if len(*macAddr) == 0 {
		return errors.New(fmt.Sprintf("%s\n", help))
	}
	hw := strings.Replace(strings.Replace(*macAddr, ":", "", -1), "-", "", -1)
	if len(hw) != 12 {
		return errors.New(fmt.Sprintf("MAC: [%s] 输入不正确.\n", *macAddr))
	}
	macBytes, err := hex.DecodeString(hw)
	if err != nil {
		fmt.Println("DecodeString  err = ", err)
		return err
	}

	// 构造 Magic Packet 数据包
	var magicPacket bytes.Buffer
	for i := 0; i < 6; i++ {
		err := magicPacket.WriteByte(0xff)
		if err != nil {
			fmt.Println("WriteByte  err = ", err)
		}
	}
	for i := 0; i < 16; i++ {
		_, err = magicPacket.Write(macBytes)
		if err != nil {
			fmt.Println("magicPacket Write  err = ", err)
		}
	}
	sender := net.UDPAddr{}
	if len(*nic) != 0 {
		ip, err := interfaceIPv4ByName(*nic)
		if err != nil {
			err = errors.New(fmt.Sprintf("网卡[%s]错误: %s", *nic, err))
			return err
		}
		sender.IP = ip
	}

	// 发送 Magic Packet
	target , err := net.ResolveUDPAddr("udp", "255.255.255.255:9")
	if err != nil {
		fmt.Println("ResolveUDPAddr err = ", err)
		return err
	}
	//也可以这样写
//	target := net.UDPAddr{
//		IP:   net.IPv4bcast,
//		Port: 9,
//	}
	conn, err := net.DialUDP("udp", &sender, &target)
	if err != nil {
		fmt.Println("DialUDP err = ", err)
		return err
	}
	_, err = conn.Write(magicPacket.Bytes())
	if err != nil {
		fmt.Println("conn.Write err = ", err)
		return err
	}
	fmt.Println("Wake-on-LAN packet sent!")
	return nil
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值