angle_dtu/udp_server.go
2025-09-08 11:44:56 +08:00

107 lines
3.2 KiB
Go
Raw 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"
"strconv"
)
// 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()
startClientCleanup()
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()
addClient(remoteAddr)
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 > 0 {
go func(id int, payload string) {
if fErr := ForwardRawData(id, payload); fErr != nil {
Logger.Printf("转发设备 %d 数据失败: %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, 0); err != nil {
Logger.Printf("保存传感器数据失败: %v", err)
}
// 从原始字符串尝试提取设备ID并透传
if m := regexp.MustCompile(`([0-9]+)-\d+`).FindStringSubmatch(rawData); len(m) == 2 {
if id, convErr := strconv.Atoi(m[1]); convErr == nil && id > 0 {
go func(id int, payload string) {
if fErr := ForwardRawData(id, payload); fErr != nil {
Logger.Printf("转发设备 %d 数据失败: %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)
}
updateClientLastSeen(remoteAddr)
}