From c1cfb25990587b6c0283fdf695f625d3c512fcc6 Mon Sep 17 00:00:00 2001 From: godo Date: Thu, 5 Sep 2024 18:42:58 +0800 Subject: [PATCH] change udp --- godo/cmd/main.go | 7 +- godo/localchat/file.go | 444 +++++++++++++++++++------------------- godo/localchat/info.go | 29 ++- godo/localchat/linux.go | 180 ++++++++-------- godo/localchat/send.go | 70 ++++++ godo/localchat/udp.go | 118 ++++++---- godo/localchat/windows.go | 182 ++++++++-------- 7 files changed, 565 insertions(+), 465 deletions(-) create mode 100644 godo/localchat/send.go diff --git a/godo/cmd/main.go b/godo/cmd/main.go index 71806c8..9ae64ec 100644 --- a/godo/cmd/main.go +++ b/godo/cmd/main.go @@ -5,7 +5,6 @@ import ( "godo/deps" "godo/files" "godo/libs" - "godo/localchat" "godo/store" "godo/sys" "godo/webdav" @@ -78,10 +77,10 @@ func OsStart() { fileRouter.HandleFunc("/unzip", files.HandleUnZip).Methods(http.MethodGet) fileRouter.HandleFunc("/watch", files.WatchHandler).Methods(http.MethodGet) - localchatRouter := router.PathPrefix("/localchat").Subrouter() + //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.HandlerFile).Methods(http.MethodPost) + // localchatRouter.HandleFunc("/message", localchat.HandleMessage).Methods(http.MethodPost) + // localchatRouter.HandleFunc("/file", localchat.HandlerFile).Methods(http.MethodPost) // localchatRouter.HandleFunc("/check", localchat.CheckUserHanlder).Methods(http.MethodGet) // 注册 WebDAV 路由 diff --git a/godo/localchat/file.go b/godo/localchat/file.go index e9ddc03..2c522ea 100644 --- a/godo/localchat/file.go +++ b/godo/localchat/file.go @@ -1,224 +1,224 @@ package localchat -import ( - "encoding/json" - "fmt" - "godo/libs" - "io" - "log" - "net" - "net/http" - "os" - "path/filepath" - "time" -) - -const ( - fileSize = 1024 // 每个数据包的大小 -) - -type FileChunk struct { - ChunkIndex int `json:"chunk_index"` - Data []byte `json:"data"` - Checksum uint32 `json:"checksum"` - Timestamp time.Time `json:"timestamp"` - Filename string `json:"filename"` -} - -// 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) - if err := decoder.Decode(&msg); err != nil { - http.Error(w, "Invalid request body", http.StatusBadRequest) - return - } - defer r.Body.Close() - toIp := msg.IP - preferredIP, err := GetLocalIP() - if err != nil { - http.Error(w, "Failed to get preferred IP", http.StatusInternalServerError) - return - } - msg.IP = preferredIP - msg.Type = "file" - basePath, err := libs.GetOsDir() - if err != nil { - libs.HTTPError(w, http.StatusInternalServerError, err.Error()) - return - } - filePath := filepath.Join(basePath, msg.Message.(string)) - // 处理单个文件或整个文件夹 - if fileInfo, err := os.Stat(filePath); err == nil { - if fileInfo.IsDir() { - handleDirectory(filePath, toIp, msg) - } else { - handleFile(filePath, toIp, msg) - } - } else { - http.Error(w, "Failed to stat path", http.StatusInternalServerError) - return - } -} - -func handleFile(filePath string, toIp string, message UdpMessage) { - // 打开文件 - file, err := os.Open(filePath) - if err != nil { - log.Fatalf("Failed to open file: %v", err) - } - defer file.Close() - - // 获取文件大小 - fileInfo, err := file.Stat() - if err != nil { - log.Fatalf("Failed to get file info: %v", err) - } - fileSize := fileInfo.Size() - - // 计算需要发送的数据包数量 - numChunks := (fileSize + fileSize - 1) / fileSize - - // 发送文件 - SendFile(file, int(numChunks), toIp, message) -} - -func handleDirectory(dirPath string, toIp string, message UdpMessage) { - err := filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if !info.IsDir() { - handleFile(path, toIp, message) - } - return nil - }) - if err != nil { - log.Fatalf("Failed to walk directory: %v", err) - } -} -func SendFile(file *os.File, numChunks int, toIp string, message UdpMessage) { - // 逐块读取文件并发送 - for i := 0; i < numChunks; i++ { - var chunkData [fileSize]byte - n, err := file.Read(chunkData[:]) - if err != nil && err != io.EOF { - log.Fatalf("Failed to read file chunk: %v", err) - } - - // 创建文件块 - chunk := FileChunk{ - ChunkIndex: i, - Data: chunkData[:n], - Checksum: calculateChecksum(chunkData[:n]), - Timestamp: time.Now(), - Filename: filepath.Base(file.Name()), - } - message.Message = chunk - // 将文件块转换为 JSON 格式 - data, err := json.Marshal(message) - if err != nil { - log.Fatalf("Failed to marshal chunk: %v", err) - } - - // 发送文件块 - addr, err := net.ResolveUDPAddr("udp4", toIp) - if err != nil { - log.Fatalf("Failed to resolve UDP address: %v", err) - } - - conn, err := net.DialUDP("udp4", nil, addr) - if err != nil { - log.Fatalf("Failed to dial UDP address: %v", err) - } - defer conn.Close() - - _, err = conn.Write(data) - if err != nil { - log.Printf("Failed to write data: %v", err) - } - - fmt.Printf("发送文件块 %d 到 %s 成功\n", i, toIp) - } -} -func RecieveFile(msg UdpMessage) { - chunk := msg.Message.(FileChunk) - - // 验证校验和 - calculatedChecksum := calculateChecksum(chunk.Data) - if calculatedChecksum != chunk.Checksum { - fmt.Printf("Checksum mismatch for chunk %d from %s\n", chunk.ChunkIndex, msg.IP) - return - } - - baseDir, err := libs.GetOsDir() - if err != nil { - log.Printf("Failed to get OS directory: %v", err) - return - } - - // 创建接收文件的目录 - receiveDir := filepath.Join(baseDir, "C", "Users", "Reciv", time.Now().Format("2006-01-02")) - if !libs.PathExists(receiveDir) { - err := os.MkdirAll(receiveDir, 0755) - if err != nil { - log.Printf("Failed to create receive directory: %v", err) - return - } - } - - // 确定文件路径 - filePath := filepath.Join(receiveDir, chunk.Filename) - - // 如果文件不存在,则创建新文件 - if _, err := os.Stat(filePath); os.IsNotExist(err) { - file, err := os.Create(filePath) - if err != nil { - log.Printf("Failed to create file: %v", err) - return - } - defer file.Close() - } - - // 打开或追加到现有文件 - file, err := os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY, 0644) - if err != nil { - log.Printf("Failed to open file: %v", err) - return - } - defer file.Close() - - // 写入数据 - _, err = file.Write(chunk.Data) - if err != nil { - log.Printf("Failed to write data to file: %v", err) - return - } - - fmt.Printf("接收到文件块 %d 从 %s 成功\n", chunk.ChunkIndex, msg.IP) -} -func calculateChecksum(data []byte) uint32 { - checksum := uint32(0) - for _, b := range data { - checksum += uint32(b) - } - return checksum -} +// import ( +// "encoding/json" +// "fmt" +// "godo/libs" +// "io" +// "log" +// "net" +// "net/http" +// "os" +// "path/filepath" +// "time" +// ) + +// const ( +// fileSize = 1024 // 每个数据包的大小 +// ) + +// type FileChunk struct { +// ChunkIndex int `json:"chunk_index"` +// Data []byte `json:"data"` +// Checksum uint32 `json:"checksum"` +// Timestamp time.Time `json:"timestamp"` +// Filename string `json:"filename"` +// } + +// // 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) +// if err := decoder.Decode(&msg); err != nil { +// http.Error(w, "Invalid request body", http.StatusBadRequest) +// return +// } +// defer r.Body.Close() +// toIp := msg.IP +// preferredIP, err := GetLocalIP() +// if err != nil { +// http.Error(w, "Failed to get preferred IP", http.StatusInternalServerError) +// return +// } +// msg.IP = preferredIP +// msg.Type = "file" +// basePath, err := libs.GetOsDir() +// if err != nil { +// libs.HTTPError(w, http.StatusInternalServerError, err.Error()) +// return +// } +// filePath := filepath.Join(basePath, msg.Message.(string)) +// // 处理单个文件或整个文件夹 +// if fileInfo, err := os.Stat(filePath); err == nil { +// if fileInfo.IsDir() { +// handleDirectory(filePath, toIp, msg) +// } else { +// handleFile(filePath, toIp, msg) +// } +// } else { +// http.Error(w, "Failed to stat path", http.StatusInternalServerError) +// return +// } +// } + +// func handleFile(filePath string, toIp string, message UdpMessage) { +// // 打开文件 +// file, err := os.Open(filePath) +// if err != nil { +// log.Fatalf("Failed to open file: %v", err) +// } +// defer file.Close() + +// // 获取文件大小 +// fileInfo, err := file.Stat() +// if err != nil { +// log.Fatalf("Failed to get file info: %v", err) +// } +// fileSize := fileInfo.Size() + +// // 计算需要发送的数据包数量 +// numChunks := (fileSize + fileSize - 1) / fileSize + +// // 发送文件 +// SendFile(file, int(numChunks), toIp, message) +// } + +// func handleDirectory(dirPath string, toIp string, message UdpMessage) { +// err := filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error { +// if err != nil { +// return err +// } +// if !info.IsDir() { +// handleFile(path, toIp, message) +// } +// return nil +// }) +// if err != nil { +// log.Fatalf("Failed to walk directory: %v", err) +// } +// } +// func SendFile(file *os.File, numChunks int, toIp string, message UdpMessage) { +// // 逐块读取文件并发送 +// for i := 0; i < numChunks; i++ { +// var chunkData [fileSize]byte +// n, err := file.Read(chunkData[:]) +// if err != nil && err != io.EOF { +// log.Fatalf("Failed to read file chunk: %v", err) +// } + +// // 创建文件块 +// chunk := FileChunk{ +// ChunkIndex: i, +// Data: chunkData[:n], +// Checksum: calculateChecksum(chunkData[:n]), +// Timestamp: time.Now(), +// Filename: filepath.Base(file.Name()), +// } +// message.Message = chunk +// // 将文件块转换为 JSON 格式 +// data, err := json.Marshal(message) +// if err != nil { +// log.Fatalf("Failed to marshal chunk: %v", err) +// } + +// // 发送文件块 +// addr, err := net.ResolveUDPAddr("udp4", toIp) +// if err != nil { +// log.Fatalf("Failed to resolve UDP address: %v", err) +// } + +// conn, err := net.DialUDP("udp4", nil, addr) +// if err != nil { +// log.Fatalf("Failed to dial UDP address: %v", err) +// } +// defer conn.Close() + +// _, err = conn.Write(data) +// if err != nil { +// log.Printf("Failed to write data: %v", err) +// } + +// fmt.Printf("发送文件块 %d 到 %s 成功\n", i, toIp) +// } +// } +// func RecieveFile(msg UdpMessage) { +// chunk := msg.Message.(FileChunk) + +// // 验证校验和 +// calculatedChecksum := calculateChecksum(chunk.Data) +// if calculatedChecksum != chunk.Checksum { +// fmt.Printf("Checksum mismatch for chunk %d from %s\n", chunk.ChunkIndex, msg.IP) +// return +// } + +// baseDir, err := libs.GetOsDir() +// if err != nil { +// log.Printf("Failed to get OS directory: %v", err) +// return +// } + +// // 创建接收文件的目录 +// receiveDir := filepath.Join(baseDir, "C", "Users", "Reciv", time.Now().Format("2006-01-02")) +// if !libs.PathExists(receiveDir) { +// err := os.MkdirAll(receiveDir, 0755) +// if err != nil { +// log.Printf("Failed to create receive directory: %v", err) +// return +// } +// } + +// // 确定文件路径 +// filePath := filepath.Join(receiveDir, chunk.Filename) + +// // 如果文件不存在,则创建新文件 +// if _, err := os.Stat(filePath); os.IsNotExist(err) { +// file, err := os.Create(filePath) +// if err != nil { +// log.Printf("Failed to create file: %v", err) +// return +// } +// defer file.Close() +// } + +// // 打开或追加到现有文件 +// file, err := os.OpenFile(filePath, os.O_APPEND|os.O_WRONLY, 0644) +// if err != nil { +// log.Printf("Failed to open file: %v", err) +// return +// } +// defer file.Close() + +// // 写入数据 +// _, err = file.Write(chunk.Data) +// if err != nil { +// log.Printf("Failed to write data to file: %v", err) +// return +// } + +// fmt.Printf("接收到文件块 %d 从 %s 成功\n", chunk.ChunkIndex, msg.IP) +// } +// func calculateChecksum(data []byte) uint32 { +// checksum := uint32(0) +// for _, b := range data { +// checksum += uint32(b) +// } +// return checksum +// } diff --git a/godo/localchat/info.go b/godo/localchat/info.go index 3341e44..87f61e4 100644 --- a/godo/localchat/info.go +++ b/godo/localchat/info.go @@ -1,23 +1,18 @@ package localchat -import ( - "fmt" - "os" -) - -// 获取自己的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) - } +// // 获取自己的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 -} +// return preferredIP, hostname, nil +// } // func GetLocalIP() (string, error) { // addrs, err := net.Interfaces() diff --git a/godo/localchat/linux.go b/godo/localchat/linux.go index e4db650..b128009 100644 --- a/godo/localchat/linux.go +++ b/godo/localchat/linux.go @@ -3,106 +3,106 @@ package localchat -import ( - "encoding/json" - "log" - "net" -) +// import ( +// "encoding/json" +// "log" +// "net" +// ) -func SendBroadcast(broadcastAddr string, message UdpMessage) error { +// 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 - } +// 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 - } +// // 使用本地地址进行连接 +// 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() +// 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 +// // 获取本地 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 - } +// 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 - } +// _, 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 -} +// 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() +// // 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) - } +// // 获取本地 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 - } +// // 开始监听多播消息 +// 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) - } -} +// 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" -} +// func GetBroadcastAddr() string { +// //return libs.GetUdpAddr() +// return "224.0.0.251:20249" +// } diff --git a/godo/localchat/send.go b/godo/localchat/send.go new file mode 100644 index 0000000..89121b6 --- /dev/null +++ b/godo/localchat/send.go @@ -0,0 +1,70 @@ +package localchat + +// import ( +// "encoding/json" +// "fmt" +// "godo/libs" +// "log" +// "net" +// "strings" +// ) + +// // SendToIP 向指定的 IP 地址发送 UDP 消息 +// func SendToIP(message UdpMessage) error { +// toIp := message.IP +// port := GetBroadcastPort() +// addr, err := net.ResolveUDPAddr("udp4", fmt.Sprintf("%s:%s", toIp, port)) +// if err != nil { +// log.Printf("Failed to resolve UDP address %s:%s: %v", toIp, port, 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", toIp, err) +// 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) +// return err +// } + +// _, err = conn.WriteToUDP(data, addr) +// if err != nil { +// log.Printf("Failed to write to UDP address %s: %v", toIp, err) +// return err +// } + +// log.Printf("发送 UDP 消息到 %s 成功", toIp) +// return nil +// } + +// // 获取 OnlineUsers 的最新状态 +// func GetOnlineUsers() map[string]UdpMessage { +// return OnlineUsers +// } +// func GetLocalIP() (string, error) { +// return libs.GetIPAddress() +// } +// func GetBroadcastPort() string { +// addr := GetBroadcastAddr() +// return addr[strings.LastIndex(addr, ":")+1:] +// } diff --git a/godo/localchat/udp.go b/godo/localchat/udp.go index d3a0796..4721c23 100644 --- a/godo/localchat/udp.go +++ b/godo/localchat/udp.go @@ -2,25 +2,26 @@ package localchat import ( "encoding/json" - "fmt" - "godo/libs" "log" "net" "os" - "strings" "time" ) type UdpMessage struct { - Type string `json:"type"` - IP string `json:"ip"` - Hostname string `json:"hostname"` - Message interface{} `json:"message"` + Hostname string `json:"hostname"` + Type string `json:"type"` + Time time.Time `json:"time"` + IP string `json:"ip"` + Message any `json:"message"` +} +type UdpAddress struct { + Hostname string `json:"hostname"` + IP string `json:"ip"` } -var OnlineUsers = make(map[string]UdpMessage) +var OnlineUsers []UdpAddress -// SendBroadcast 发送广播消息 func init() { go InitBroadcast() go ListenForBroadcast() @@ -41,25 +42,18 @@ func InitBroadcast() { Message: "", } //发送多播消息 - //broadcastAddr := GetBroadcastAddr() - err = SendBroadcast("224.0.0.251:20249", message) - if err != nil { - log.Println("Failed to send broadcast message:", err) - } - err = SendBroadcast("255.255.255.255:20249", message) + broadcastAddr := GetBroadcastAddr() + err = SendBroadcast(broadcastAddr, message) if err != nil { log.Println("Failed to send broadcast message:", err) } } } +func SendBroadcast(broadcastAddr string, message UdpMessage) error { -// SendToIP 向指定的 IP 地址发送 UDP 消息 -func SendToIP(message UdpMessage) error { - toIp := message.IP - port := GetBroadcastPort() - addr, err := net.ResolveUDPAddr("udp4", fmt.Sprintf("%s:%s", toIp, port)) + addr, err := net.ResolveUDPAddr("udp4", broadcastAddr) if err != nil { - log.Printf("Failed to resolve UDP address %s:%s: %v", toIp, port, err) + log.Printf("Failed to resolve UDP address %s: %v", broadcastAddr, err) return err } @@ -72,43 +66,85 @@ func SendToIP(message UdpMessage) error { conn, err := net.ListenUDP("udp4", localAddr) if err != nil { - log.Printf("Failed to listen on UDP address %s: %v", toIp, err) + log.Printf("Failed to listen on UDP address %s: %v", broadcastAddr, err) 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) + 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", toIp, err) + log.Printf("Failed to write to UDP address %s: %v", broadcastAddr, err) return err } - log.Printf("发送 UDP 消息到 %s 成功", toIp) + log.Printf("发送消息到 %s 成功", broadcastAddr) return nil } -// 获取 OnlineUsers 的最新状态 -func GetOnlineUsers() map[string]UdpMessage { - return OnlineUsers +// 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 := libs.GetIPAddress() + // 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 + // } + // 从 remoteAddr 获取 IP 地址 + ip := remoteAddr.IP.String() + if !contains(OnlineUsers, ip) { + OnlineUsers = append(OnlineUsers, UdpAddress{Hostname: udpMsg.Hostname, IP: ip}) + log.Printf("在线用户: %v", OnlineUsers) + } + log.Printf("Received message from %s: %s", remoteAddr, udpMsg.Hostname) + } } -func GetLocalIP() (string, error) { - return libs.GetIPAddress() +func contains(slice []UdpAddress, element string) bool { + for _, v := range slice { + if v.IP == element { + return true + } + } + return false +} +func GetOnlineUsers() []UdpAddress { + return OnlineUsers } -func GetBroadcastPort() string { - addr := GetBroadcastAddr() - return addr[strings.LastIndex(addr, ":")+1:] +func GetBroadcastAddr() string { + return "224.0.0.251:20249" } diff --git a/godo/localchat/windows.go b/godo/localchat/windows.go index 897ece0..1802cf6 100644 --- a/godo/localchat/windows.go +++ b/godo/localchat/windows.go @@ -1,106 +1,106 @@ -//go:build windows -// +build windows +// //go:build windows +// // +build windows package localchat -import ( - "encoding/json" - "log" - "net" -) +// import ( +// "encoding/json" +// "log" +// "net" +// ) -func SendBroadcast(broadcastAddr string, message UdpMessage) error { +// 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 - } +// 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 - } +// // 使用本地地址进行连接 +// 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() +// 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 +// // 获取本地 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 - } +// 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 - } +// _, 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 -} +// 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) - } +// // 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 - } +// 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) - } -} +// 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" -} +// func GetBroadcastAddr() string { +// //return libs.GetUdpAddr() +// return "255.255.255.255:20249" +// }