You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

111 lines
2.4 KiB

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
}