angle_dtu/udp_server.go
2025-09-08 19:16:07 +08:00

107 lines
3.4 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"fmt"
"net"
"regexp"
)
// StartUDPServer 启动UDP服务器
func StartUDPServer(address string) error {
addr, err := net.ResolveUDPAddr("udp", address)
if err != nil {
return fmt.Errorf("解析UDP地址失败: %v", err)
}
conn, err := net.ListenUDP("udp", addr)
if err != nil {
return fmt.Errorf("监听UDP地址失败: %v", err)
}
defer conn.Close()
// 已移除客户端在线追踪;改由 DB 的 last_seen 统计在线
Logger.Printf("UDP服务器已启动正在监听 %s\n", address)
buffer := make([]byte, 1024)
for {
n, remoteAddr, err := conn.ReadFromUDP(buffer)
if err != nil {
Logger.Printf("从UDP客户端读取失败: %v", err)
continue
}
go handleUDPPacket(conn, remoteAddr, buffer[:n])
}
}
// handleUDPPacket 处理UDP数据包
func handleUDPPacket(conn *net.UDPConn, addr *net.UDPAddr, data []byte) {
remoteAddr := addr.String()
// 已移除客户端在线追踪
rawData := string(data)
TCPDataLogger.Printf("从UDP客户端 %s 接收到原始数据: %s", remoteAddr, rawData)
// 尝试解析批量数据
readings, err := parseBatchData(rawData)
if err == nil && len(readings) > 0 {
// 批量数据解析成功
TCPDataLogger.Printf("批量解析成功 - UDP客户端: %s, 传感器数量: %d", remoteAddr, len(readings))
// 保存所有传感器数据
if err := SaveBatchSensorData(readings); err != nil {
Logger.Printf("保存批量传感器数据失败: %v", err)
}
// 尝试提取设备ID并透传原始数据
if deviceID := ExtractDeviceIDFromBatchRaw(rawData); deviceID != "" {
Logger.Printf("准备转发 deviceID=%s 原始长度=%d", deviceID, len(rawData))
go func(id string, payload string) {
if fErr := ForwardRawData(id, payload); fErr != nil {
Logger.Printf("转发设备 %s 数据失败: %v", id, fErr)
}
}(deviceID, rawData)
}
// 记录第一个传感器的数据(用于兼容现有日志格式)
firstSensor := readings[0]
TCPDataLogger.Printf("解析成功 - UDP客户端: %s, 传感器ID: %d, 值: X=%.3f, Y=%.3f, Z=%.3f, 温度=%.1f°C",
remoteAddr, firstSensor.SensorID, firstSensor.X, firstSensor.Y, firstSensor.Z, firstSensor.Temperature)
} else {
// 尝试传统解析方法
sensorID, x, y, z, temperature, parseErr := parseData(rawData)
if parseErr == nil {
TCPDataLogger.Printf("解析成功 - UDP客户端: %s, 传感器ID: %d, 值: X=%.3f, Y=%.3f, Z=%.3f, 温度=%.1f°C",
remoteAddr, sensorID, x, y, z, temperature)
if err := SaveSensorData(sensorID, x, y, z, temperature, ""); err != nil {
Logger.Printf("保存传感器数据失败: %v", err)
}
// 从原始字符串尝试提取设备ID并透传
if m := regexp.MustCompile(`([A-Za-z0-9]+)-\d+`).FindStringSubmatch(rawData); len(m) == 2 {
id := m[1]
Logger.Printf("准备转发 deviceID=%s 原始长度=%d", id, len(rawData))
go func(id string, payload string) {
if fErr := ForwardRawData(id, payload); fErr != nil {
Logger.Printf("转发设备 %s 数据失败: %v", id, fErr)
}
}(id, rawData)
}
} else {
TCPDataLogger.Printf("无法解析从UDP客户端 %s 接收到的数据: %s, 错误: %v", remoteAddr, rawData, parseErr)
}
}
resp := "OK\n"
if _, err := conn.WriteToUDP([]byte(resp), addr); err != nil {
Logger.Printf("发送响应到UDP客户端 %s 失败: %v", remoteAddr, err)
}
// 已移除客户端在线追踪
}