package wol import ( "bytes" "encoding/hex" "errors" "fmt" "net" "regexp" "strings" ) var ( MacFormatError = errors.New("mac 地址格式错误") ) type Service struct { } var Services *Service func init() { Services = &Service{} } func (s *Service) validateMac(mac string) bool { exp, _ := regexp.Compile("([0-9a-fA-F]{2}(-|:)?){5}([a-fA-F0-9]{2})") macLen := len(mac) return exp.MatchString(mac) && (macLen == 12 || macLen == 17) } func (s *Service) WakeUp(mac string, port int) error { mac = strings.Replace(strings.Replace(mac, ":", "", -1), "-", "", -1) if !s.validateMac(mac) { return MacFormatError } return s.wake(mac, port) } func (s *Service) wake(mac string, port int) error { udpAddr, _ := net.ResolveUDPAddr("udp", fmt.Sprintf("255.255.255.255:%d", port)) interfaces, err := net.Interfaces() if err != nil { return err } macHex, _ := hex.DecodeString(mac) // 广播MAC地址 FF:FF:FF:FF:FF:FF var broadcast = []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} var buffer bytes.Buffer buffer.Write(broadcast) for i := 0; i < 16; i++ { buffer.Write(macHex) } wolPackage := buffer.Bytes() for _, i := range interfaces { if i.Flags&net.FlagUp == 0 { continue } addrs, err := i.Addrs() if err != nil { return err } for _, addr := range addrs { if ip, ok := addr.(*net.IPNet); ok { if ipv4 := ip.IP.To4(); ipv4 != nil { conn, err := net.DialUDP("udp", &net.UDPAddr{IP: ipv4}, udpAddr) if err != nil { return err } _, _ = conn.Write(wolPackage) _ = conn.Close() } } } } return err }