diff --git a/db.go b/db.go index b9dfacd..3c3fd1b 100644 --- a/db.go +++ b/db.go @@ -13,7 +13,6 @@ const SCALING_FACTOR = 1000 // 浮点数到整数的转换因子 // 初始化数据库连接 func InitDB() error { - // 调整这些参数以匹配你的MySQL配置 username := "root" password := "root" // 请替换为你的实际密码 host := "localhost" @@ -29,13 +28,11 @@ func InitDB() error { return err } - // 测试连接 err = db.Ping() if err != nil { return err } - // 设置连接池参数 db.SetMaxOpenConns(10) db.SetMaxIdleConns(5) db.SetConnMaxLifetime(time.Minute * 5) @@ -52,7 +49,6 @@ func CloseDB() { // 保存传感器数据 - 将浮点值转换为整数存储 func SaveSensorData(sensorID int, x, y, z float64) error { - // 转换为整数,乘以1000并四舍五入 xInt := int(x * SCALING_FACTOR) yInt := int(y * SCALING_FACTOR) zInt := int(z * SCALING_FACTOR) @@ -62,20 +58,16 @@ func SaveSensorData(sensorID int, x, y, z float64) error { return err } -// 获取传感器数据 - 从整数转换回浮点数 // 获取传感器数据 - 添加时间范围 func GetSensorData(sensorID int, limit int, startDate time.Time, endDate time.Time) ([]SensorData, error) { - // 基本查询 query := `SELECT id, sensor_id, x_value, y_value, z_value, timestamp as timestamp FROM sensor_data WHERE sensor_id = ?` - // 添加查询条件 var args []interface{} args = append(args, sensorID) - // 添加日期范围 if !startDate.IsZero() { query += " AND timestamp >= ?" args = append(args, startDate) @@ -86,11 +78,9 @@ func GetSensorData(sensorID int, limit int, startDate time.Time, endDate time.Ti args = append(args, endDate) } - // 添加排序和限制 query += " ORDER BY timestamp DESC LIMIT ?" args = append(args, limit) - // 执行查询 rows, err := db.Query(query, args...) if err != nil { return nil, err @@ -108,7 +98,6 @@ func GetSensorData(sensorID int, limit int, startDate time.Time, endDate time.Ti return nil, err } - // 从整数转换回浮点数 data.X = float64(xInt) / SCALING_FACTOR data.Y = float64(yInt) / SCALING_FACTOR data.Z = float64(zInt) / SCALING_FACTOR @@ -121,16 +110,13 @@ func GetSensorData(sensorID int, limit int, startDate time.Time, endDate time.Ti // 获取所有传感器数据 func GetAllSensorData(limit int, startDate time.Time, endDate time.Time) ([]SensorData, error) { - // 基本查询 query := `SELECT id, sensor_id, x_value, y_value, z_value, timestamp as timestamp FROM sensor_data WHERE 1=1` - // 添加查询条件 var args []interface{} - // 添加日期范围 if !startDate.IsZero() { query += " AND timestamp >= ?" args = append(args, startDate) @@ -141,11 +127,9 @@ func GetAllSensorData(limit int, startDate time.Time, endDate time.Time) ([]Sens args = append(args, endDate) } - // 添加排序和限制 query += " ORDER BY timestamp DESC LIMIT ?" args = append(args, limit) - // 执行查询 rows, err := db.Query(query, args...) if err != nil { return nil, err @@ -163,7 +147,6 @@ func GetAllSensorData(limit int, startDate time.Time, endDate time.Time) ([]Sens return nil, err } - // 从整数转换回浮点数 data.X = float64(xInt) / SCALING_FACTOR data.Y = float64(yInt) / SCALING_FACTOR data.Z = float64(zInt) / SCALING_FACTOR @@ -173,6 +156,7 @@ func GetAllSensorData(limit int, startDate time.Time, endDate time.Time) ([]Sens return result, nil } + // 获取所有传感器ID func GetAllSensorIDs() ([]int, error) { query := `SELECT DISTINCT sensor_id FROM sensor_data ORDER BY sensor_id` diff --git a/http_server.go b/http_server.go index e4764d7..1fe378f 100644 --- a/http_server.go +++ b/http_server.go @@ -14,10 +14,8 @@ import ( // 启动HTTP服务器 func StartHTTPServer(address string) error { - // 主页 http.HandleFunc("/", handleIndex) - // API路由 http.HandleFunc("/api/data", handleGetData) http.HandleFunc("/api/sensors", handleGetSensors) http.HandleFunc("/api/clients", handleGetClients) @@ -29,7 +27,6 @@ func StartHTTPServer(address string) error { func handleIndex(w http.ResponseWriter, r *http.Request) { log.Printf("接收到主页请求: %s", r.URL.Path) - // 确保templates目录存在 templatePath := "templates/index.html" absPath, _ := filepath.Abs(templatePath) @@ -62,16 +59,13 @@ func handleGetData(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") - // 获取查询参数 sensorIDStr := r.URL.Query().Get("sensor_id") limitStr := r.URL.Query().Get("limit") startDateStr := r.URL.Query().Get("start_date") endDateStr := r.URL.Query().Get("end_date") - // 默认值 limit := 500 - // 处理传感器ID var sensorID int var err error if sensorIDStr != "" && sensorIDStr != "all" { @@ -83,7 +77,6 @@ func handleGetData(w http.ResponseWriter, r *http.Request) { } } - // 处理限制条数 if limitStr != "" { limit, err = strconv.Atoi(limitStr) if err != nil || limit <= 0 { @@ -93,7 +86,6 @@ func handleGetData(w http.ResponseWriter, r *http.Request) { } } - // 处理日期范围 var startDate, endDate time.Time if startDateStr != "" { startDate, err = time.Parse("2006-01-02T15:04", startDateStr) @@ -113,7 +105,6 @@ func handleGetData(w http.ResponseWriter, r *http.Request) { } } - // 获取数据 var data []SensorData if sensorIDStr == "all" || sensorIDStr == "" { data, err = GetAllSensorData(limit, startDate, endDate) @@ -129,7 +120,6 @@ func handleGetData(w http.ResponseWriter, r *http.Request) { log.Printf("成功获取到 %d 条数据记录", len(data)) - // 返回JSON if err := json.NewEncoder(w).Encode(data); err != nil { log.Printf("错误: 编码JSON失败: %v", err) http.Error(w, "编码JSON失败:"+err.Error(), http.StatusInternalServerError) @@ -141,7 +131,6 @@ func handleGetSensors(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") - // 获取所有传感器ID sensorIDs, err := GetAllSensorIDs() if err != nil { log.Printf("错误: 获取传感器ID失败: %v", err) @@ -151,7 +140,6 @@ func handleGetSensors(w http.ResponseWriter, r *http.Request) { log.Printf("成功获取到 %d 个传感器ID", len(sensorIDs)) - // 返回JSON if err := json.NewEncoder(w).Encode(sensorIDs); err != nil { log.Printf("错误: 编码JSON失败: %v", err) http.Error(w, "编码JSON失败:"+err.Error(), http.StatusInternalServerError) diff --git a/logger.go b/logger.go index 99bbe30..1323815 100644 --- a/logger.go +++ b/logger.go @@ -1,89 +1,79 @@ -// logger.go package main import ( - "fmt" - "io" - "log" - "os" - "path/filepath" - "time" + "fmt" + "io" + "log" + "os" + "path/filepath" + "time" ) -// 日志文件 var ( - logFile *os.File - Logger *log.Logger // 导出Logger供其他包使用 - TCPDataLogger *log.Logger // 专门用于记录TCP数据的日志 + logFile *os.File + Logger *log.Logger // 导出Logger供其他包使用 + TCPDataLogger *log.Logger // 专门用于记录TCP数据的日志 ) // 初始化日志系统 func InitLogger() error { - // 创建logs目录 - logsDir := "logs" - if err := os.MkdirAll(logsDir, 0755); err != nil { - return fmt.Errorf("创建日志目录失败: %v", err) - } - - // 创建当天的日志文件 - today := time.Now().Format("2006-01-02") - logFilePath := filepath.Join(logsDir, fmt.Sprintf("server_%s.log", today)) - - file, err := os.OpenFile(logFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return fmt.Errorf("打开日志文件失败: %v", err) - } - - logFile = file - - // 创建一个多输出的logger,同时写入文件和控制台 - multiWriter := io.MultiWriter(os.Stdout, file) - Logger = log.New(multiWriter, "", log.Ldate|log.Ltime|log.Lshortfile) - - // 创建TCP数据日志文件 - tcpDataFilePath := filepath.Join(logsDir, fmt.Sprintf("tcp_data_%s.log", today)) - tcpDataFile, err := os.OpenFile(tcpDataFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return fmt.Errorf("打开TCP数据日志文件失败: %v", err) - } - - // TCP数据日志同时写入文件和控制台 - tcpDataMultiWriter := io.MultiWriter(os.Stdout, tcpDataFile) - TCPDataLogger = log.New(tcpDataMultiWriter, "TCP_DATA: ", log.Ldate|log.Ltime) - - // 替换标准日志 - log.SetOutput(multiWriter) - log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) - - Logger.Println("日志系统初始化完成") - return nil + logsDir := "logs" + if err := os.MkdirAll(logsDir, 0755); err != nil { + return fmt.Errorf("创建日志目录失败: %v", err) + } + + today := time.Now().Format("2006-01-02") + logFilePath := filepath.Join(logsDir, fmt.Sprintf("server_%s.log", today)) + + file, err := os.OpenFile(logFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return fmt.Errorf("打开日志文件失败: %v", err) + } + + logFile = file + + multiWriter := io.MultiWriter(os.Stdout, file) + Logger = log.New(multiWriter, "", log.Ldate|log.Ltime|log.Lshortfile) + + tcpDataFilePath := filepath.Join(logsDir, fmt.Sprintf("tcp_data_%s.log", today)) + tcpDataFile, err := os.OpenFile(tcpDataFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return fmt.Errorf("打开TCP数据日志文件失败: %v", err) + } + + tcpDataMultiWriter := io.MultiWriter(os.Stdout, tcpDataFile) + TCPDataLogger = log.New(tcpDataMultiWriter, "TCP_DATA: ", log.Ldate|log.Ltime) + + log.SetOutput(multiWriter) + log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) + + Logger.Println("日志系统初始化完成") + return nil } // 关闭日志文件 func CloseLogger() { - if logFile != nil { - logFile.Close() - } + if logFile != nil { + logFile.Close() + } } // 日志轮转,每天创建新的日志文件 func StartLogRotation() { - go func() { - for { - // 等待到明天0点 - now := time.Now() - next := now.Add(24 * time.Hour) - next = time.Date(next.Year(), next.Month(), next.Day(), 0, 0, 0, 0, next.Location()) - duration := next.Sub(now) - - time.Sleep(duration) - - // 重新初始化日志 - Logger.Println("开始日志轮转...") - CloseLogger() - if err := InitLogger(); err != nil { - log.Printf("日志轮转失败: %v", err) - } - } - }() + go func() { + for { + now := time.Now() + next := now.Add(24 * time.Hour) + next = time.Date(next.Year(), next.Month(), next.Day(), 0, 0, 0, 0, next.Location()) + duration := next.Sub(now) + + time.Sleep(duration) + + Logger.Println("开始日志轮转...") + CloseLogger() + if err := InitLogger(); err != nil { + log.Printf("日志轮转失败: %v", err) + } + } + }() } diff --git a/main.go b/main.go index 97528f1..bd3db93 100644 --- a/main.go +++ b/main.go @@ -8,33 +8,27 @@ import ( ) func main() { - // 命令行参数解析 serverType := flag.String("server", "tcp", "服务器类型: tcp 或 udp") tcpPort := flag.String("tcpport", "10002", "TCP服务器端口") udpPort := flag.String("udpport", "10002", "UDP服务器端口") httpPort := flag.String("httpport", "10001", "HTTP服务器端口") flag.Parse() - // 初始化日志 if err := InitLogger(); err != nil { log.Fatalf("初始化日志系统失败: %v", err) } defer CloseLogger() - // 启动日志轮转 StartLogRotation() - // 初始化数据库 err := InitDB() if err != nil { log.Fatalf("初始化数据库失败: %v", err) } defer CloseDB() - fmt.Println("iProbe 斜侧仪监控系统启动中...") var wg sync.WaitGroup - // 根据选择启动TCP或UDP服务器 wg.Add(1) go func() { defer wg.Done() @@ -53,7 +47,6 @@ func main() { } }() - // 启动HTTP服务器 wg.Add(1) go func() { defer wg.Done() diff --git a/tcp_server.go b/tcp_server.go index 91ecdbf..975c04e 100644 --- a/tcp_server.go +++ b/tcp_server.go @@ -1,255 +1,236 @@ -// tcp_server.go package main import ( - "fmt" - "io" - "net" - "regexp" - "strconv" - "strings" - "sync" - "time" + "fmt" + "io" + "net" + "regexp" + "strconv" + "strings" + "sync" + "time" ) // 客户端信息结构 type ClientInfo struct { - IP string // IP地址 - Port string // 端口 - LastSeen time.Time // 最后活跃时间 + IP string // IP地址 + Port string // 端口 + LastSeen time.Time // 最后活跃时间 } // 客户端列表(使用互斥锁保护的映射) var ( - clientsMutex sync.Mutex - clients = make(map[string]*ClientInfo) + clientsMutex sync.Mutex + clients = make(map[string]*ClientInfo) ) // StartTCPServer 启动TCP服务器 func StartTCPServer(address string) error { - listener, err := net.Listen("tcp", address) - if err != nil { - return err - } - - // 启动客户端清理 - startClientCleanup() - - Logger.Printf("TCP服务器已启动,正在监听 %s\n", address) - - for { - conn, err := listener.Accept() - if err != nil { - Logger.Printf("接受连接失败: %v", err) - continue - } - - go handleConnection(conn) - } + listener, err := net.Listen("tcp", address) + if err != nil { + return err + } + + startClientCleanup() + + Logger.Printf("TCP服务器已启动,正在监听 %s\n", address) + + for { + conn, err := listener.Accept() + if err != nil { + Logger.Printf("接受连接失败: %v", err) + continue + } + + go handleConnection(conn) + } } // handleConnection 处理客户端连接 func handleConnection(conn net.Conn) { - defer conn.Close() - - // 获取客户端信息 - remoteAddr := conn.RemoteAddr().String() - Logger.Printf("新的客户端连接: %s", remoteAddr) - - // 添加到在线客户端列表 - addClient(remoteAddr) - - buffer := make([]byte, 1024) - - for { - // 读取数据 - n, err := conn.Read(buffer) - if err != nil { - if err != io.EOF { - Logger.Printf("从客户端读取失败 %s: %v", remoteAddr, err) - } else { - Logger.Printf("客户端断开连接 %s", remoteAddr) - } - removeClient(remoteAddr) - break - } - - // 将字节数据转换为字符串,并记录原始数据 - rawData := string(buffer[:n]) - TCPDataLogger.Printf("从客户端 %s 接收到原始数据: %s", remoteAddr, rawData) - - // 尝试解析数据 - sensorID, x, y, z, err := parseData(rawData) - - if err == nil { - TCPDataLogger.Printf("解析成功 - 客户端: %s, 传感器ID: %d, 值: X=%.3f, Y=%.3f, Z=%.3f", - remoteAddr, sensorID, x, y, z) - - // 保存数据到数据库 - if err := SaveSensorData(sensorID, x, y, z); err != nil { - Logger.Printf("保存传感器数据失败: %v", err) - } - } else { - TCPDataLogger.Printf("无法解析从客户端 %s 接收到的数据: %s, 错误: %v", remoteAddr, rawData, err) - } - - // 发送响应 - resp := "OK\n" - if _, err := conn.Write([]byte(resp)); err != nil { - Logger.Printf("发送响应到客户端 %s 失败: %v", remoteAddr, err) - removeClient(remoteAddr) - break - } - - // 更新客户端最后活跃时间 - updateClientLastSeen(remoteAddr) - } + defer conn.Close() + + remoteAddr := conn.RemoteAddr().String() + Logger.Printf("新的客户端连接: %s", remoteAddr) + + addClient(remoteAddr) + + buffer := make([]byte, 1024) + + for { + n, err := conn.Read(buffer) + if err != nil { + if err != io.EOF { + Logger.Printf("从客户端读取失败 %s: %v", remoteAddr, err) + } else { + Logger.Printf("客户端断开连接 %s", remoteAddr) + } + removeClient(remoteAddr) + break + } + + rawData := string(buffer[:n]) + TCPDataLogger.Printf("从客户端 %s 接收到原始数据: %s", remoteAddr, rawData) + + sensorID, x, y, z, err := parseData(rawData) + + if err == nil { + TCPDataLogger.Printf("解析成功 - 客户端: %s, 传感器ID: %d, 值: X=%.3f, Y=%.3f, Z=%.3f", + remoteAddr, sensorID, x, y, z) + + if err := SaveSensorData(sensorID, x, y, z); err != nil { + Logger.Printf("保存传感器数据失败: %v", err) + } + } else { + TCPDataLogger.Printf("无法解析从客户端 %s 接收到的数据: %s, 错误: %v", remoteAddr, rawData, err) + } + + resp := "OK\n" + if _, err := conn.Write([]byte(resp)); err != nil { + Logger.Printf("发送响应到客户端 %s 失败: %v", remoteAddr, err) + removeClient(remoteAddr) + break + } + + updateClientLastSeen(remoteAddr) + } } // parseData 使用正则表达式解析传感器数据 func parseData(data string) (int, float64, float64, float64, error) { - // 使用正则表达式匹配数据格式 - pattern := regexp.MustCompile(`(\d+):([-]?\d+\.\d+),\s*([-]?\d+\.\d+),\s*([-]?\d+\.\d+)`) - matches := pattern.FindStringSubmatch(data) - - if len(matches) != 5 { - return 0, 0, 0, 0, fmt.Errorf("数据格式不正确: %s", data) - } - - // 解析传感器ID和三个浮点数值 - sensorID, err := strconv.Atoi(matches[1]) - if err != nil { - return 0, 0, 0, 0, fmt.Errorf("解析传感器ID失败: %v", err) - } - - x, err := strconv.ParseFloat(strings.TrimSpace(matches[2]), 64) - if err != nil { - return 0, 0, 0, 0, fmt.Errorf("解析X值失败: %v", err) - } - - y, err := strconv.ParseFloat(strings.TrimSpace(matches[3]), 64) - if err != nil { - return 0, 0, 0, 0, fmt.Errorf("解析Y值失败: %v", err) - } - - z, err := strconv.ParseFloat(strings.TrimSpace(matches[4]), 64) - if err != nil { - return 0, 0, 0, 0, fmt.Errorf("解析Z值失败: %v", err) - } - - return sensorID, x, y, z, nil + pattern := regexp.MustCompile(`(\d+):([-]?\d+\.\d+),\s*([-]?\d+\.\d+),\s*([-]?\d+\.\d+)`) + matches := pattern.FindStringSubmatch(data) + + if len(matches) != 5 { + return 0, 0, 0, 0, fmt.Errorf("数据格式不正确: %s", data) + } + + sensorID, err := strconv.Atoi(matches[1]) + if err != nil { + return 0, 0, 0, 0, fmt.Errorf("解析传感器ID失败: %v", err) + } + + x, err := strconv.ParseFloat(strings.TrimSpace(matches[2]), 64) + if err != nil { + return 0, 0, 0, 0, fmt.Errorf("解析X值失败: %v", err) + } + + y, err := strconv.ParseFloat(strings.TrimSpace(matches[3]), 64) + if err != nil { + return 0, 0, 0, 0, fmt.Errorf("解析Y值失败: %v", err) + } + + z, err := strconv.ParseFloat(strings.TrimSpace(matches[4]), 64) + if err != nil { + return 0, 0, 0, 0, fmt.Errorf("解析Z值失败: %v", err) + } + + return sensorID, x, y, z, nil } // addClient 添加客户端 func addClient(addr string) { - clientsMutex.Lock() - defer clientsMutex.Unlock() - - // 解析地址 - host, port, err := net.SplitHostPort(addr) - if err != nil { - Logger.Printf("解析客户端地址失败 %s: %v", addr, err) - host = addr - port = "unknown" - } - - // 添加或更新客户端 - clients[addr] = &ClientInfo{ - IP: host, - Port: port, - LastSeen: time.Now(), - } - - Logger.Printf("添加新客户端: %s", addr) + clientsMutex.Lock() + defer clientsMutex.Unlock() + + host, port, err := net.SplitHostPort(addr) + if err != nil { + Logger.Printf("解析客户端地址失败 %s: %v", addr, err) + host = addr + port = "unknown" + } + + clients[addr] = &ClientInfo{ + IP: host, + Port: port, + LastSeen: time.Now(), + } + + Logger.Printf("添加新客户端: %s", addr) } // updateClientLastSeen 更新客户端最后活跃时间 func updateClientLastSeen(addr string) { - clientsMutex.Lock() - defer clientsMutex.Unlock() - - if client, exists := clients[addr]; exists { - client.LastSeen = time.Now() - } + clientsMutex.Lock() + defer clientsMutex.Unlock() + + if client, exists := clients[addr]; exists { + client.LastSeen = time.Now() + } } // removeClient 移除客户端 func removeClient(addr string) { - clientsMutex.Lock() - defer clientsMutex.Unlock() - - // 我们只更新最后活跃时间而不实际删除, - // 这样前端可以知道客户端已断开连接 - if client, exists := clients[addr]; exists { - client.LastSeen = time.Now() - Logger.Printf("客户端标记为断开连接: %s", addr) - } + clientsMutex.Lock() + defer clientsMutex.Unlock() + + if client, exists := clients[addr]; exists { + client.LastSeen = time.Now() + Logger.Printf("客户端标记为断开连接: %s", addr) + } } // getAllClients 获取所有客户端信息 func getAllClients() []map[string]interface{} { - clientsMutex.Lock() - defer clientsMutex.Unlock() - - now := time.Now() - result := make([]map[string]interface{}, 0, len(clients)) - - for addr, client := range clients { - // 计算最后活跃时间 - lastSeenDuration := now.Sub(client.LastSeen) - - // 如果超过1天未活跃,则删除 - if lastSeenDuration > 24*time.Hour { - delete(clients, addr) - continue - } - - // 在线状态 - 10分钟内有活动 - isOnline := lastSeenDuration < 10*time.Minute - - result = append(result, map[string]interface{}{ - "address": addr, - "ip": client.IP, - "port": client.Port, - "lastSeen": client.LastSeen, - "isOnline": isOnline, - "lastSeenFormatted": formatDuration(lastSeenDuration), - }) - } - - return result + clientsMutex.Lock() + defer clientsMutex.Unlock() + + now := time.Now() + result := make([]map[string]interface{}, 0, len(clients)) + + for addr, client := range clients { + lastSeenDuration := now.Sub(client.LastSeen) + + if lastSeenDuration > 24*time.Hour { + delete(clients, addr) + continue + } + + isOnline := lastSeenDuration < 10*time.Minute + + result = append(result, map[string]interface{}{ + "address": addr, + "ip": client.IP, + "port": client.Port, + "lastSeen": client.LastSeen, + "isOnline": isOnline, + "lastSeenFormatted": formatDuration(lastSeenDuration), + }) + } + + return result } // formatDuration 格式化持续时间为友好的字符串 func formatDuration(d time.Duration) string { - if d < time.Minute { - return "刚刚" - } else if d < time.Hour { - return fmt.Sprintf("%d分钟前", int(d.Minutes())) - } else if d < 24*time.Hour { - return fmt.Sprintf("%d小时前", int(d.Hours())) - } else { - return fmt.Sprintf("%d天前", int(d.Hours()/24)) - } + if d < time.Minute { + return "刚刚" + } else if d < time.Hour { + return fmt.Sprintf("%d分钟前", int(d.Minutes())) + } else if d < 24*time.Hour { + return fmt.Sprintf("%d小时前", int(d.Hours())) + } else { + return fmt.Sprintf("%d天前", int(d.Hours()/24)) + } } // startClientCleanup 启动清理过期客户端的goroutine func startClientCleanup() { - go func() { - for { - time.Sleep(1 * time.Hour) // 每小时检查一次 - - clientsMutex.Lock() - now := time.Now() - - for addr, client := range clients { - if now.Sub(client.LastSeen) > 24*time.Hour { - delete(clients, addr) - Logger.Printf("移除过期客户端: %s", addr) - } - } - - clientsMutex.Unlock() - } - }() + go func() { + for { + time.Sleep(1 * time.Hour) // 每小时检查一次 + + clientsMutex.Lock() + now := time.Now() + + for addr, client := range clients { + if now.Sub(client.LastSeen) > 24*time.Hour { + delete(clients, addr) + Logger.Printf("移除过期客户端: %s", addr) + } + } + + clientsMutex.Unlock() + } + }() } diff --git a/udp_server.go b/udp_server.go index b7dc6ac..da53dcd 100644 --- a/udp_server.go +++ b/udp_server.go @@ -1,4 +1,3 @@ -// udp_server.go package main import ( @@ -8,20 +7,17 @@ import ( // StartUDPServer 启动UDP服务器 func StartUDPServer(address string) error { - // 解析UDP地址 addr, err := net.ResolveUDPAddr("udp", address) if err != nil { return fmt.Errorf("解析UDP地址失败: %v", err) } - // 创建UDP连接 conn, err := net.ListenUDP("udp", addr) if err != nil { return fmt.Errorf("监听UDP地址失败: %v", err) } defer conn.Close() - // 启动客户端清理 startClientCleanup() Logger.Printf("UDP服务器已启动,正在监听 %s\n", address) @@ -35,31 +31,25 @@ func StartUDPServer(address string) error { continue } - // 处理数据包 go handleUDPPacket(conn, remoteAddr, buffer[:n]) } } // handleUDPPacket 处理UDP数据包 func handleUDPPacket(conn *net.UDPConn, addr *net.UDPAddr, data []byte) { - // 获取客户端信息 remoteAddr := addr.String() - // 添加到在线客户端列表 addClient(remoteAddr) - // 将字节数据转换为字符串,并记录原始数据 rawData := string(data) TCPDataLogger.Printf("从UDP客户端 %s 接收到原始数据: %s", remoteAddr, rawData) - // 尝试解析数据 sensorID, x, y, z, err := parseData(rawData) if err == nil { TCPDataLogger.Printf("解析成功 - UDP客户端: %s, 传感器ID: %d, 值: X=%.3f, Y=%.3f, Z=%.3f", remoteAddr, sensorID, x, y, z) - // 保存数据到数据库 if err := SaveSensorData(sensorID, x, y, z); err != nil { Logger.Printf("保存传感器数据失败: %v", err) } @@ -67,12 +57,10 @@ func handleUDPPacket(conn *net.UDPConn, addr *net.UDPAddr, data []byte) { TCPDataLogger.Printf("无法解析从UDP客户端 %s 接收到的数据: %s, 错误: %v", remoteAddr, rawData, err) } - // 发送响应 resp := "OK\n" if _, err := conn.WriteToUDP([]byte(resp), addr); err != nil { Logger.Printf("发送响应到UDP客户端 %s 失败: %v", remoteAddr, err) } - // 更新客户端最后活跃时间 updateClientLastSeen(remoteAddr) }