zhangzengfei
2023-09-05 1b34d7bacad94933ad63fc0e199bd32ac49d9fa5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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
}