网络唤醒 php,go实现网络唤醒远程开机(Wake on Lan)

源码位置: https://github.com/zzustu/wol

编译后的文件位置: https://github.com/zzustu/wol/releases

初学go语言,想着做一个远程开机的小程序放在路由器上面,能给电脑远程开机的小程序,

刚开始在电脑上可以唤醒成功,但是放在路由器上怎么也唤醒不成功,也抓不到唤醒魔包,

研究了一下发现是因为路由器是多网卡,魔包并没有走内网网卡,现在可以通过指定网卡

发送唤醒魔包了,

命令:`wol -nic br-lan -mac XX:XX:XX:XX:XX:XX` ,

`br-lan` 为替换成你实际网卡的名称,一般单网卡设备可以忽略该参数

现在贴出来,如果代码有哪里不合适的地方也请各位大佬指点。

```go

package main

import (

"bytes"

"encoding/hex"

"errors"

"flag"

"fmt"

"net"

"strings"

)

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

源码地址:

https://github.com/zzustu/wol

`

// 网络唤醒魔包技术白皮书地址: https://www.amd.com/system/files/TechDocs/20213.pdf

func main() {

mac := flag.String("mac", "", help)

nic := flag.String("nic", "", help)

flag.Parse()

if len(*mac) == 0 {

fmt.Printf("%s\n", help)

return

}

hw := strings.Replace(strings.Replace(*mac, ":", "", -1), "-", "", -1)

if len(hw) != 12 {

fmt.Printf("MAC: [%s] 输入不正确.\n", *mac)

return

}

macHex, err := hex.DecodeString(hw)

if err != nil {

fmt.Printf("MAC: [%s] 输入不正确.\n", *mac)

return

}

// 广播MAC地址 FF:FF:FF:FF:FF:FF

var bcast = []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}

var buff bytes.Buffer

buff.Write(bcast)

for i := 0; i < 16; i++ {

buff.Write(macHex)

}

// 获得唤醒魔包

mp := buff.Bytes()

if len(mp) != 102 {

fmt.Printf("MAC: [%s] 输入不正确.\n", *mac)

return

}

sendMagicPacket(mp, *nic)

}

// 向指定网卡发送唤醒魔包

func sendMagicPacket(mp []byte, nic string) {

sender := net.UDPAddr{}

if len(nic) != 0 {

ip, err := interfaceIPv4ByName(nic)

if err != nil {

fmt.Printf("网卡[%s]错误: %s", nic, err)

return

}

sender.IP = ip

}

target := net.UDPAddr{

IP: net.IPv4bcast,

}

conn, err := net.DialUDP("udp", &sender, &target)

if err != nil {

fmt.Printf("创建UDP错误:%v", err)

return

}

defer func() {

_ = conn.Close()

}()

_, err = conn.Write(mp)

if err != nil {

fmt.Printf("魔包发送失败[%s]", err)

} else {

fmt.Printf("魔包发送成功")

}

}

// 通过网卡名称获取该网卡绑定的IPv4

func interfaceIPv4ByName(nic string) (net.IP, error) {

inter, err := net.InterfaceByName(nic)

if err != nil {

return nil, err

}

// 检查网卡是否正在工作

if (inter.Flags & net.FlagUp) == 0 {

return nil, errors.New("网卡未工作")

}

addrs, err := inter.Addrs()

if err != nil {

return nil, err

}

for _, addr := range addrs {

if ip, ok := addr.(*net.IPNet); ok {

if ipv4 := ip.IP.To4(); ipv4 != nil {

return ipv4, nil

}

}

}

return nil, errors.New("找不到网卡绑定的IP")

}

```

有疑问加站长微信联系(非本文作者)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值