mirror of https://gitee.com/godoos/godoos.git
10 changed files with 261 additions and 405 deletions
@ -0,0 +1,103 @@ |
|||
package localchat |
|||
|
|||
import ( |
|||
"net" |
|||
"net/http" |
|||
"strconv" |
|||
|
|||
"godo/libs" |
|||
) |
|||
|
|||
func HandleAddr(w http.ResponseWriter, r *http.Request) { |
|||
addr := r.URL.Query().Get("addr") |
|||
if addr == "" { |
|||
libs.ErrorMsg(w, "addr is empty") |
|||
return |
|||
} |
|||
|
|||
udpAddr := libs.GetUdpAddr() |
|||
if addr == udpAddr { |
|||
libs.ErrorMsg(w, "addr is same as current addr") |
|||
return |
|||
} |
|||
|
|||
// 检查是否为多播地址
|
|||
if !IsValidMulticastAddr(addr) { |
|||
libs.ErrorMsg(w, "addr is not a valid multicast address") |
|||
return |
|||
} |
|||
// 验证可访问性
|
|||
if IsMulticastAddrAccessible(addr) { |
|||
save := libs.ReqBody{ |
|||
Value: addr, |
|||
Name: "udpAddr", |
|||
} |
|||
libs.SetConfig(save) |
|||
libs.SuccessMsg(w, nil, "addr is a valid multicast address and accessible") |
|||
} else { |
|||
libs.ErrorMsg(w, "addr is a valid multicast address but not accessible") |
|||
} |
|||
} |
|||
|
|||
// 检查是否为多播地址
|
|||
func IsValidMulticastAddr(addr string) bool { |
|||
host, port, err := net.SplitHostPort(addr) |
|||
if err != nil { |
|||
return false |
|||
} |
|||
|
|||
ip := net.ParseIP(host) |
|||
if ip == nil || !isMulticastIP(ip) { |
|||
return false |
|||
} |
|||
|
|||
_, err = strconv.Atoi(port) |
|||
return err == nil |
|||
} |
|||
|
|||
// 检查 IP 是否为多播地址
|
|||
func isMulticastIP(ip net.IP) bool { |
|||
if ip.To4() != nil { |
|||
return ip[0]&0xF0 == 0xE0 // 检查 IPv4 多播地址范围 224.0.0.0 - 239.255.255.255
|
|||
} |
|||
return ip[0]&0xF0 == 0xE0 // 检查 IPv6 多播地址范围 FF00::/8
|
|||
} |
|||
|
|||
// 验证多播地址的可访问性
|
|||
func IsMulticastAddrAccessible(addr string) bool { |
|||
host, port, err := net.SplitHostPort(addr) |
|||
if err != nil { |
|||
return false |
|||
} |
|||
|
|||
udpAddr, err := net.ResolveUDPAddr("udp4", net.JoinHostPort(host, port)) |
|||
if err != nil { |
|||
return false |
|||
} |
|||
|
|||
conn, err := net.ListenMulticastUDP("udp4", nil, udpAddr) |
|||
if err != nil { |
|||
return false |
|||
} |
|||
defer conn.Close() |
|||
|
|||
// 发送一条测试消息
|
|||
testMsg := []byte("Test message") |
|||
_, err = conn.WriteToUDP(testMsg, udpAddr) |
|||
if err != nil { |
|||
return false |
|||
} |
|||
|
|||
// 接收一条测试消息
|
|||
buffer := make([]byte, 1024) |
|||
n, _, err := conn.ReadFromUDP(buffer) |
|||
if err != nil { |
|||
return false |
|||
} |
|||
|
|||
if n > 0 && string(buffer[:n]) == "Test message" { |
|||
return true |
|||
} |
|||
|
|||
return false |
|||
} |
@ -1,62 +0,0 @@ |
|||
package localchat |
|||
|
|||
// // 获取自己的IP地址和主机名
|
|||
// func GetMyIPAndHostname() (string, string, error) {
|
|||
// hostname, err := os.Hostname()
|
|||
// if err != nil {
|
|||
// return "", "", fmt.Errorf("failed to get hostname: %w", err)
|
|||
// }
|
|||
// preferredIP, err := GetLocalIP()
|
|||
// if err != nil {
|
|||
// return "", "", fmt.Errorf("failed to get IP address: %w", err)
|
|||
// }
|
|||
|
|||
// 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
|
|||
// }
|
|||
// }
|
|||
|
|||
// if preferredIP == nil {
|
|||
// return "", fmt.Errorf("no preferred non-loopback IPv4 address found")
|
|||
// }
|
|||
// return preferredIP.String(), nil
|
|||
// }
|
@ -1,108 +0,0 @@ |
|||
//go:build !windows
|
|||
// +build !windows
|
|||
|
|||
package localchat |
|||
|
|||
// import (
|
|||
// "encoding/json"
|
|||
// "log"
|
|||
// "net"
|
|||
// )
|
|||
|
|||
// func SendBroadcast(broadcastAddr string, message UdpMessage) error {
|
|||
|
|||
// addr, err := net.ResolveUDPAddr("udp4", broadcastAddr)
|
|||
// if err != nil {
|
|||
// log.Printf("Failed to resolve UDP address %s: %v", broadcastAddr, err)
|
|||
// return err
|
|||
// }
|
|||
|
|||
// // 使用本地地址进行连接
|
|||
// localAddr, err := net.ResolveUDPAddr("udp4", "0.0.0.0:0")
|
|||
// if err != nil {
|
|||
// log.Printf("Failed to resolve local UDP address: %v", err)
|
|||
// return err
|
|||
// }
|
|||
|
|||
// conn, err := net.ListenUDP("udp4", localAddr)
|
|||
// if err != nil {
|
|||
// log.Printf("Failed to listen on UDP address %s: %v", broadcastAddr, err)
|
|||
// return err
|
|||
// }
|
|||
// defer conn.Close()
|
|||
|
|||
// // 获取本地 IP 地址
|
|||
// localIP, err := GetLocalIP()
|
|||
// log.Printf("本地 IP 地址: %s", localIP)
|
|||
// 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", broadcastAddr, err)
|
|||
// return err
|
|||
// }
|
|||
|
|||
// _, err = conn.WriteToUDP(data, addr)
|
|||
// if err != nil {
|
|||
// log.Printf("Failed to write to UDP address %s: %v", broadcastAddr, err)
|
|||
// return err
|
|||
// }
|
|||
|
|||
// log.Printf("发送消息到 %s 成功", broadcastAddr)
|
|||
// return nil
|
|||
// }
|
|||
|
|||
// // ListenForBroadcast 监听多播消息
|
|||
// func ListenForBroadcast() {
|
|||
// broadcastAddr := GetBroadcastAddr()
|
|||
// addr, err := net.ResolveUDPAddr("udp4", broadcastAddr)
|
|||
// if err != nil {
|
|||
// log.Fatalf("Failed to resolve UDP address: %v", err)
|
|||
// }
|
|||
// // 使用 ListenMulticastUDP 创建多播连接
|
|||
// conn, err := net.ListenMulticastUDP("udp4", nil, addr)
|
|||
// if err != nil {
|
|||
// log.Fatalf("Failed to listen on UDP address: %v", err)
|
|||
// }
|
|||
// defer conn.Close()
|
|||
|
|||
// // 获取本地 IP 地址
|
|||
// localIP, err := GetLocalIP()
|
|||
// if err != nil {
|
|||
// log.Printf("Failed to get local IP address: %v", err)
|
|||
// }
|
|||
|
|||
// // 开始监听多播消息
|
|||
// buffer := make([]byte, 1024)
|
|||
// for {
|
|||
// n, remoteAddr, err := conn.ReadFromUDP(buffer)
|
|||
// if err != nil {
|
|||
// log.Printf("Error reading from UDP: %v", err)
|
|||
// continue
|
|||
// }
|
|||
|
|||
// var udpMsg UdpMessage
|
|||
// err = json.Unmarshal(buffer[:n], &udpMsg)
|
|||
// if err != nil {
|
|||
// log.Printf("Error unmarshalling JSON: %v", err)
|
|||
// continue
|
|||
// }
|
|||
// if udpMsg.IP == localIP {
|
|||
// continue
|
|||
// }
|
|||
// OnlineUsers[udpMsg.IP] = udpMsg
|
|||
// if udpMsg.Type == "file" {
|
|||
// RecieveFile(udpMsg)
|
|||
// }
|
|||
// log.Printf("Received message from %s: %s", remoteAddr, udpMsg.Hostname)
|
|||
// }
|
|||
// }
|
|||
|
|||
// func GetBroadcastAddr() string {
|
|||
// //return libs.GetUdpAddr()
|
|||
// return "224.0.0.251:20249"
|
|||
// }
|
@ -0,0 +1,71 @@ |
|||
package localchat |
|||
|
|||
import ( |
|||
"encoding/json" |
|||
"log" |
|||
"net" |
|||
"os" |
|||
"time" |
|||
) |
|||
|
|||
func InitBroadcast() { |
|||
ticker := time.NewTicker(5 * time.Second) // 每 5 秒发送一次广播消息
|
|||
defer ticker.Stop() |
|||
|
|||
for range ticker.C { |
|||
hostname, err := os.Hostname() |
|||
if err != nil { |
|||
log.Printf("Failed to get hostname: %v", err) |
|||
continue |
|||
} |
|||
message := UdpMessage{ |
|||
Type: "online", |
|||
Hostname: hostname, |
|||
Message: "", |
|||
Time: time.Now(), |
|||
} |
|||
//发送多播消息
|
|||
broadcastAddr := GetBroadcastAddr() |
|||
err = SendBroadcast(broadcastAddr, message) |
|||
if err != nil { |
|||
log.Println("Failed to send broadcast message:", err) |
|||
} |
|||
} |
|||
} |
|||
func SendBroadcast(broadcastAddr string, message UdpMessage) error { |
|||
|
|||
addr, err := net.ResolveUDPAddr("udp4", broadcastAddr) |
|||
if err != nil { |
|||
log.Printf("Failed to resolve UDP address %s: %v", broadcastAddr, err) |
|||
return err |
|||
} |
|||
|
|||
// 使用本地地址进行连接
|
|||
localAddr, err := net.ResolveUDPAddr("udp4", "0.0.0.0:0") |
|||
if err != nil { |
|||
log.Printf("Failed to resolve local UDP address: %v", err) |
|||
return err |
|||
} |
|||
|
|||
conn, err := net.ListenUDP("udp4", localAddr) |
|||
if err != nil { |
|||
log.Printf("Failed to listen on UDP address %s: %v", broadcastAddr, err) |
|||
return err |
|||
} |
|||
defer conn.Close() |
|||
|
|||
data, err := json.Marshal(message) |
|||
if err != nil { |
|||
log.Printf("Failed to marshal JSON for %s: %v", broadcastAddr, err) |
|||
return err |
|||
} |
|||
|
|||
_, err = conn.WriteToUDP(data, addr) |
|||
if err != nil { |
|||
log.Printf("Failed to write to UDP address %s: %v", broadcastAddr, err) |
|||
return err |
|||
} |
|||
|
|||
log.Printf("发送消息到 %s 成功", broadcastAddr) |
|||
return nil |
|||
} |
@ -1,106 +0,0 @@ |
|||
// //go:build windows
|
|||
// // +build windows
|
|||
|
|||
package localchat |
|||
|
|||
// import (
|
|||
// "encoding/json"
|
|||
// "log"
|
|||
// "net"
|
|||
// )
|
|||
|
|||
// func SendBroadcast(broadcastAddr string, message UdpMessage) error {
|
|||
|
|||
// addr, err := net.ResolveUDPAddr("udp4", broadcastAddr)
|
|||
// if err != nil {
|
|||
// log.Printf("Failed to resolve UDP address %s: %v", broadcastAddr, err)
|
|||
// return err
|
|||
// }
|
|||
|
|||
// // 使用本地地址进行连接
|
|||
// localAddr, err := net.ResolveUDPAddr("udp4", "0.0.0.0:0")
|
|||
// if err != nil {
|
|||
// log.Printf("Failed to resolve local UDP address: %v", err)
|
|||
// return err
|
|||
// }
|
|||
|
|||
// conn, err := net.ListenUDP("udp4", localAddr)
|
|||
// if err != nil {
|
|||
// log.Printf("Failed to listen on UDP address %s: %v", broadcastAddr, err)
|
|||
// return err
|
|||
// }
|
|||
// defer conn.Close()
|
|||
|
|||
// // 获取本地 IP 地址
|
|||
// localIP, err := GetLocalIP()
|
|||
// log.Printf("本地 IP 地址: %s", localIP)
|
|||
// 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", broadcastAddr, err)
|
|||
// return err
|
|||
// }
|
|||
|
|||
// _, err = conn.WriteToUDP(data, addr)
|
|||
// if err != nil {
|
|||
// log.Printf("Failed to write to UDP address %s: %v", broadcastAddr, err)
|
|||
// return err
|
|||
// }
|
|||
|
|||
// log.Printf("发送消息到 %s 成功", broadcastAddr)
|
|||
// return nil
|
|||
// }
|
|||
|
|||
// // ListenForBroadcast 监听广播消息
|
|||
// func ListenForBroadcast() {
|
|||
// // 使用本地地址监听
|
|||
// localAddr, err := net.ResolveUDPAddr("udp4", ":20249")
|
|||
// if err != nil {
|
|||
// log.Fatalf("Failed to resolve local UDP address: %v", err)
|
|||
// }
|
|||
|
|||
// conn, err := net.ListenUDP("udp4", localAddr)
|
|||
// if err != nil {
|
|||
// log.Fatalf("Failed to listen on UDP address: %v", err)
|
|||
// }
|
|||
// defer conn.Close()
|
|||
// // 获取本地 IP 地址
|
|||
// localIP, err := GetLocalIP()
|
|||
// if err != nil {
|
|||
// log.Printf("Failed to get local IP address: %v", err)
|
|||
// }
|
|||
// // 开始监听广播消息
|
|||
// buffer := make([]byte, 1024)
|
|||
// for {
|
|||
// n, remoteAddr, err := conn.ReadFromUDP(buffer)
|
|||
// if err != nil {
|
|||
// log.Printf("Error reading from UDP: %v", err)
|
|||
// continue
|
|||
// }
|
|||
|
|||
// var udpMsg UdpMessage
|
|||
// err = json.Unmarshal(buffer[:n], &udpMsg)
|
|||
// if err != nil {
|
|||
// log.Printf("Error unmarshalling JSON: %v", err)
|
|||
// continue
|
|||
// }
|
|||
// if udpMsg.IP == localIP {
|
|||
// continue
|
|||
// }
|
|||
// OnlineUsers[udpMsg.IP] = udpMsg
|
|||
// if udpMsg.Type == "file" {
|
|||
// RecieveFile(udpMsg)
|
|||
// }
|
|||
// log.Printf("Received message from %s: %s", remoteAddr, udpMsg.Hostname)
|
|||
// }
|
|||
// }
|
|||
|
|||
// func GetBroadcastAddr() string {
|
|||
// //return libs.GetUdpAddr()
|
|||
// return "255.255.255.255:20249"
|
|||
// }
|
Loading…
Reference in new issue