826220679@qq.com
2025-08-07 4d6cd980c5c69e4d9d150669c89734642297e0cd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package udptcp;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.*;
import dell_targets.Dell_differentialBaseStation;
import dell_targets.Dell_tag;
import targets.DifferentialBaseStation;
import targets.LocationTag;
 
public class TCPDiffDataReceiver {
    private static final int PORT = 7002;
    private static final Map<String, Socket> deviceConnections = new ConcurrentHashMap<>();
    private static final ExecutorService executor = Executors.newCachedThreadPool();
 
    public static void main(String[] args) {
        // Æô¶¯É豸Á¬½Ó¼àÌýÆ÷
        new Thread(TCPDiffDataReceiver::listenForDeviceConnections).start();
        
        // Æô¶¯²î·Ö»ùÕ¾Êý¾Ý´¦ÀíÆ÷
        new Thread(TCPDiffDataReceiver::processDifferentialData).start();
    }
 
    // ¼àÌýÉ豸Á¬½Ó
    private static void listenForDeviceConnections() {
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("TCP Differential Server started on port " + PORT);
            
            while (true) {
                Socket deviceSocket = serverSocket.accept();
                String deviceId = "device_" + UUID.randomUUID(); // Êµ¼ÊÓ¦´ÓÉ豸»ñÈ¡ID
                deviceConnections.put(deviceId, deviceSocket);
            }
        } catch (Exception e) {
            System.err.println("Device connection listener crashed: " + e.getMessage());
        }
    }
 
    // ´¦Àí²î·Ö»ùÕ¾Êý¾Ý
    private static void processDifferentialData() {
        while (true) {
            try {
                // 1. »ñÈ¡ËùÓвî·Ö»ùÕ¾
                List<DifferentialBaseStation> baseStations = Dell_differentialBaseStation.getAllBaseStations();
                
                // 2. ´¦Àíÿ¸ö»ùÕ¾µÄÊý¾Ý
                for (DifferentialBaseStation station : baseStations) {
                    // Ä£Äâ½ÓÊÕÊý¾Ý
                    byte[] diffData = receiveDataFromBaseStation(station);
                    station.setReceivenum(station.getReceivenum() + 1); // ¸üнÓÊÕ¼ÆÊý
                    
                    // 3. »ñÈ¡ÔÚÏßÉ豸
                    List<LocationTag> onlineDevices = Dell_tag.getlocationTags().stream()
                        .filter(tag -> "1".equals(tag.getOnlineStatus()))
                        .toList();
                    
                    // 4. ×ª·¢Êý¾Ýµ½É豸
                    forwardToDevices(station, diffData, onlineDevices);
                }
                
                // Ã¿Ãë´¦ÀíÒ»´Î
                Thread.sleep(1000);
            } catch (Exception e) {
                System.err.println("Differential data processing error: " + e.getMessage());
            }
        }
    }
 
    // ×ª·¢Êý¾Ýµ½É豸
    private static void forwardToDevices(DifferentialBaseStation station, 
                                       byte[] data, 
                                       List<LocationTag> devices) throws SQLException {
        if (devices.isEmpty()) return;
 
        // µ¥»ùÕ¾Çé¿ö£º¹ã²¥µ½ËùÓÐÉ豸
        if (devices.size() == 1) {
            broadcastData(data);
            return;
        }
 
        // ¶à»ùÕ¾Çé¿ö£ºÑ¡Ôñ×î½üµÄ»ùÕ¾
        for (LocationTag device : devices) {
            DifferentialBaseStation nearestStation = findNearestBaseStation(
                device, 
                Dell_differentialBaseStation.getAllBaseStations()
            );
            
            if (nearestStation.getId().equals(station.getId())) {
                sendToDevice(device.getDeviceNumber(), data);
            }
        }
    }
 
    // ²éÕÒ×î½üµÄ»ùÕ¾
    private static DifferentialBaseStation findNearestBaseStation(LocationTag device, 
                                                                List<DifferentialBaseStation> stations) {
        return stations.stream()
            .min(Comparator.comparingDouble(station -> 
                calculateDistance(
                    Double.parseDouble(device.getLatitude()),
                    Double.parseDouble(device.getLongitude()),
                    Double.parseDouble(station.getLatitude()),
                    Double.parseDouble(station.getLongitude())
                ))
            .orElse(null);
    }
 
    // ¼ÆËã¾àÀ루Haversine¹«Ê½£©
    private static double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
        final int R = 6371; // µØÇò°ë¾¶(km)
        double dLat = Math.toRadians(lat2 - lat1);
        double dLon = Math.toRadians(lon2 - lon1);
        double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
                   Math.cos(Math.toRadians(lat1)) * 
                   Math.cos(Math.toRadians(lat2)) *
                   Math.sin(dLon/2) * Math.sin(dLon/2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
        return R * c;
    }
 
    // ¹ã²¥Êý¾Ýµ½ËùÓÐÉ豸
    private static void broadcastData(byte[] data) {
        deviceConnections.forEach((id, socket) -> {
            executor.execute(() -> sendData(socket, data));
        });
    }
 
    // ·¢ËÍÊý¾Ýµ½Ìض¨É豸
    private static void sendToDevice(String deviceId, byte[] data) {
        Socket socket = deviceConnections.get(deviceId);
        if (socket != null) {
            executor.execute(() -> sendData(socket, data));
        }
    }
 
    // Êµ¼Ê·¢ËÍÊý¾Ý
    private static void sendData(Socket socket, byte[] data) {
        try {
            socket.getOutputStream().write(data);
            socket.getOutputStream().flush();
        } catch (Exception e) {
            System.err.println("Data sending failed: " + e.getMessage());
        }
    }
 
    // Ä£Äâ»ùÕ¾Êý¾Ý½ÓÊÕ
    private static byte[] receiveDataFromBaseStation(DifferentialBaseStation station) {
        return ("Data from " + station.getDeviceNumber()).getBytes();
    }
}