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