From 83e422b2463b95185562bdb7ba6fc919a2c8f855 Mon Sep 17 00:00:00 2001 From: godo Date: Thu, 5 Sep 2024 16:04:17 +0800 Subject: [PATCH] change udpinfo --- godo/cmd/main.go | 2 +- godo/libs/dir.go | 13 +++++- godo/libs/info.go | 29 ++++++++++++-- godo/localchat/file.go | 20 +++++++++- godo/localchat/info.go | 90 +++++++++++++++++++++--------------------- godo/localchat/udp.go | 54 +++++++++++-------------- 6 files changed, 126 insertions(+), 82 deletions(-) diff --git a/godo/cmd/main.go b/godo/cmd/main.go index 2421663..71806c8 100644 --- a/godo/cmd/main.go +++ b/godo/cmd/main.go @@ -81,7 +81,7 @@ func OsStart() { localchatRouter := router.PathPrefix("/localchat").Subrouter() // localchatRouter.HandleFunc("/sse", localchat.SseHandler).Methods(http.MethodGet) localchatRouter.HandleFunc("/message", localchat.HandleMessage).Methods(http.MethodPost) - localchatRouter.HandleFunc("/file", localchat.FileHandler).Methods(http.MethodPost) + localchatRouter.HandleFunc("/file", localchat.HandlerFile).Methods(http.MethodPost) // localchatRouter.HandleFunc("/check", localchat.CheckUserHanlder).Methods(http.MethodGet) // 注册 WebDAV 路由 diff --git a/godo/libs/dir.go b/godo/libs/dir.go index 4eb89f7..2dd2ed1 100644 --- a/godo/libs/dir.go +++ b/godo/libs/dir.go @@ -29,6 +29,11 @@ func InitServer() error { Value: info, } SetConfig(osInfo) + udpAddr := ReqBody{ + Name: "udpAddr", + Value: "224.0.0.251:20249", + } + SetConfig(udpAddr) } return nil @@ -51,7 +56,13 @@ func GetOsDir() (string, error) { } return osDir.(string), nil } - +func GetUdpAddr() string { + udp, ok := GetConfig("udpAddr") + if !ok { + return "224.0.0.251:20249" + } + return udp.(string) +} func GetAppDir() (string, error) { homeDir, err := os.UserHomeDir() if err != nil { diff --git a/godo/libs/info.go b/godo/libs/info.go index f9709c3..eb538c8 100644 --- a/godo/libs/info.go +++ b/godo/libs/info.go @@ -9,6 +9,8 @@ import ( "net" "os" "runtime" + "strconv" + "strings" ) // UserOsInfo 定义系统信息结构体 @@ -60,17 +62,38 @@ func GenerateSystemInfo() UserOsInfo { // GetIPAddress 获取本机IP地址 func GetIPAddress() (string, error) { ips, err := GetValidIPAddresses() - //log.Printf("ips: %v", ips) if err != nil { return "", err } + + // 优先选择 192.168 开头的 IP 地址,并且第三个数字最小 + var bestIP string + minThirdOctet := 256 // 初始化为最大值,表示还没有找到合适的 IP 地址 + for _, ipStr := range ips { ip := net.ParseIP(ipStr) if ip != nil && ip.To4() != nil && ip.String()[:7] == "192.168" { - return ipStr, nil + octets := strings.Split(ip.String(), ".") + if len(octets) == 4 { + thirdOctet, _ := strconv.Atoi(octets[2]) + if thirdOctet < minThirdOctet { + minThirdOctet = thirdOctet + bestIP = ipStr + } + } } } - return "", fmt.Errorf("no valid IP addresses found") + + // 如果没有找到 192.168 开头的 IP 地址,则选择第一个有效的全局单播 IP 地址 + if bestIP == "" && len(ips) > 0 { + bestIP = ips[0] + } + + if bestIP == "" { + return "", fmt.Errorf("no valid IP addresses found") + } + + return bestIP, nil } // GetValidIPAddresses 获取所有有效 IP 地址 diff --git a/godo/localchat/file.go b/godo/localchat/file.go index be81e82..e9ddc03 100644 --- a/godo/localchat/file.go +++ b/godo/localchat/file.go @@ -25,7 +25,25 @@ type FileChunk struct { Filename string `json:"filename"` } -func FileHandler(w http.ResponseWriter, r *http.Request) { +// HandleMessage 处理 HTTP 请求 +func HandleMessage(w http.ResponseWriter, r *http.Request) { + var msg UdpMessage + decoder := json.NewDecoder(r.Body) + if err := decoder.Decode(&msg); err != nil { + http.Error(w, "Invalid request body", http.StatusBadRequest) + return + } + defer r.Body.Close() + err := SendToIP(msg) + if err != nil { + http.Error(w, "Failed to send message", http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusOK) + fmt.Fprintln(w, "Text message send successfully") +} + +func HandlerFile(w http.ResponseWriter, r *http.Request) { // 初始化多播地址 var msg UdpMessage decoder := json.NewDecoder(r.Body) diff --git a/godo/localchat/info.go b/godo/localchat/info.go index aa57652..3341e44 100644 --- a/godo/localchat/info.go +++ b/godo/localchat/info.go @@ -2,7 +2,6 @@ package localchat import ( "fmt" - "net" "os" ) @@ -19,49 +18,50 @@ func GetMyIPAndHostname() (string, string, error) { return preferredIP, hostname, nil } -func GetLocalIP() (string, error) { - 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 - } - } +// func GetLocalIP() (string, error) { +// addrs, err := net.Interfaces() +// if err != nil { +// return "", fmt.Errorf("failed to get network interfaces: %w", err) +// } - if preferredIP == nil { - return "", fmt.Errorf("no preferred non-loopback IPv4 address found") - } - return preferredIP.String(), nil -} +// 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(), nil +// } diff --git a/godo/localchat/udp.go b/godo/localchat/udp.go index 75ae6b1..73998c2 100644 --- a/godo/localchat/udp.go +++ b/godo/localchat/udp.go @@ -3,18 +3,14 @@ package localchat import ( "encoding/json" "fmt" + "godo/libs" "log" "net" - "net/http" "os" + "strings" "time" ) -const ( - BroadcastIP = "255.255.255.255" - BroadcastPort = 20249 -) - type UdpMessage struct { Type string `json:"type"` IP string `json:"ip"` @@ -22,7 +18,6 @@ type UdpMessage struct { Message interface{} `json:"message"` } -var broadcastAddr = fmt.Sprintf("%s:%d", BroadcastIP, BroadcastPort) var OnlineUsers = make(map[string]UdpMessage) // SendBroadcast 发送广播消息 @@ -54,6 +49,7 @@ func InitBroadcast() { } func SendBroadcast(message UdpMessage) error { + broadcastAddr := GetBroadcastAddr() addr, err := net.ResolveUDPAddr("udp4", broadcastAddr) if err != nil { log.Printf("Failed to resolve UDP address %s: %v", broadcastAddr, err) @@ -101,13 +97,13 @@ func SendBroadcast(message UdpMessage) error { // ListenForBroadcast 监听广播消息 func ListenForBroadcast() { - // 使用本地地址监听 - localAddr, err := net.ResolveUDPAddr("udp4", fmt.Sprintf(":%d", BroadcastPort)) + broadcastAddr := GetBroadcastAddr() + addr, err := net.ResolveUDPAddr("udp4", broadcastAddr) if err != nil { - log.Fatalf("Failed to resolve local UDP address: %v", err) + log.Fatalf("Failed to resolve UDP address: %v", err) } - - conn, err := net.ListenUDP("udp4", localAddr) + // 使用 ListenMulticastUDP 创建多播连接 + conn, err := net.ListenMulticastUDP("udp4", nil, addr) if err != nil { log.Fatalf("Failed to listen on UDP address: %v", err) } @@ -148,9 +144,10 @@ func ListenForBroadcast() { // SendToIP 向指定的 IP 地址发送 UDP 消息 func SendToIP(message UdpMessage) error { toIp := message.IP - addr, err := net.ResolveUDPAddr("udp4", fmt.Sprintf("%s:%d", toIp, BroadcastPort)) + port := GetBroadcastPort() + addr, err := net.ResolveUDPAddr("udp4", fmt.Sprintf("%s:%s", toIp, port)) if err != nil { - log.Printf("Failed to resolve UDP address %s:%d: %v", toIp, BroadcastPort, err) + log.Printf("Failed to resolve UDP address %s:%s: %v", toIp, port, err) return err } @@ -167,12 +164,15 @@ func SendToIP(message UdpMessage) error { return err } defer conn.Close() + // 获取本地 IP 地址 localIP, err := GetLocalIP() if err != nil { log.Printf("Failed to get local IP address: %v", err) + return err } message.IP = localIP + data, err := json.Marshal(message) if err != nil { log.Printf("Failed to marshal JSON for %s: %v", toIp, err) @@ -193,21 +193,13 @@ func SendToIP(message UdpMessage) error { func GetOnlineUsers() map[string]UdpMessage { return OnlineUsers } - -// HandleMessage 处理 HTTP 请求 -func HandleMessage(w http.ResponseWriter, r *http.Request) { - var msg UdpMessage - decoder := json.NewDecoder(r.Body) - if err := decoder.Decode(&msg); err != nil { - http.Error(w, "Invalid request body", http.StatusBadRequest) - return - } - defer r.Body.Close() - err := SendToIP(msg) - if err != nil { - http.Error(w, "Failed to send message", http.StatusInternalServerError) - return - } - w.WriteHeader(http.StatusOK) - fmt.Fprintln(w, "Text message send successfully") +func GetLocalIP() (string, error) { + return libs.GetIPAddress() +} +func GetBroadcastAddr() string { + return libs.GetUdpAddr() +} +func GetBroadcastPort() string { + addr := GetBroadcastAddr() + return addr[strings.LastIndex(addr, ":")+1:] }