package localchat import ( "encoding/json" "fmt" "log" "net" "os" "time" ) func DiscoverServers() { broadcastTicker := time.NewTicker(broadcartTime) done := make(chan struct{}) // New channel to signal when to stop go func() { for { select { case <-broadcastTicker.C: conn, err := net.Dial("udp", broadcastAddr) if err != nil { fmt.Println(err) continue } myIP, myHostname, err := getMyIPAndHostname() if err != nil { log.Printf("Failed to get my IP and hostname: %v", err) conn.Close() continue } msg := UdpMessage{ Type: "online", Hostname: myHostname, IP: myIP, Message: time.Now().Format("2006-01-02 15:04:05"), } jsonData, err := json.Marshal(msg) if err != nil { log.Printf("Failed to marshal message to JSON: %v", err) conn.Close() continue } //log.Printf("Sending message: %+v", msg) _, err = conn.Write(jsonData) if err != nil { fmt.Println(err) } conn.Close() // Close the connection after use case <-done: // Signal to stop broadcastTicker.Stop() return } } }() } // 获取自己的IP地址和主机名 func getMyIPAndHostname() (string, string, error) { hostname, err := os.Hostname() if err != nil { return "", "", fmt.Errorf("failed to get hostname: %w", err) } addrs, err := net.Interfaces() if err != nil { return "", "", fmt.Errorf("failed to get network interfaces: %w", err) } var preferredIP net.IP for _, iface := range addrs { if iface.Flags&net.FlagUp == 0 { // Skip interfaces that are not up continue } ifAddrs, err := iface.Addrs() if err != nil { continue // Ignore this interface if we can't get its addresses } for _, addr := range ifAddrs { var ip net.IP switch v := addr.(type) { case *net.IPNet: ip = v.IP case *net.IPAddr: ip = v.IP default: continue } if ip.IsLoopback() { continue // Skip loopback addresses } if ip.To4() != nil && (ip.IsPrivate() || ip.IsGlobalUnicast()) { // Prefer global unicast or private addresses over link-local preferredIP = ip break } } if preferredIP != nil { // Found a preferred IP, break out of the loop break } } if preferredIP == nil { return "", "", fmt.Errorf("no preferred non-loopback IPv4 address found") } return preferredIP.String(), hostname, nil }