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();
|
}
|
}
|