package broadcast import ( "fmt" "github.com/gogf/greuse" "strconv" "strings" "sync" "time" ) var ( port = 31995 lport = 31996 lock sync.Mutex //同一时刻只能有一个线程在执行搜索 ) //广播收集其他节点信息 func BroadCast() ([]string, error) { lock.Lock() defer lock.Unlock() retCh := make(chan []string) go startRecv(retCh) conn, err := greuse.Dial("udp", "0.0.0.0:"+strconv.Itoa(lport), "255.255.255.255:"+strconv.Itoa(port)) if err != nil { fmt.Println("err:", err) } else { defer conn.Close() n,err := conn.Write([]byte("who are you?")) if err != nil || n == 0 { fmt.Println("conn.Write err:", err, " n:", n) } } nodes := <-retCh return nodes, nil } func startRecv(rCh chan []string) { conn, err := greuse.ListenPacket("udp", "0.0.0.0:"+strconv.Itoa(lport)) if err != nil { fmt.Println("startRecv ListenPacket err:", err) rCh <- []string{} return } //10秒钟之内收到的返回,即认为是在线的 conn.SetReadDeadline(time.Now().Add(time.Second * 1)) ch := time.After(time.Second * 4) var nodes []string Loop: for { select { case <-ch: fmt.Println("<-ch") break Loop default: ret := make([]byte, 1024) n, from, e := conn.ReadFrom(ret) if e == nil && n >0 { arr := strings.Split(from.String(), ":") if len(arr) == 2 { nodes = append(nodes, arr[0]) } fmt.Println("read message from udp:", string(ret), " from:", from) } else { time.Sleep(time.Millisecond * 100) } } } rCh <- nodes }