Untitled
package org.stupor.deviceInteractiion; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.springframework.stereotype.Service; import org.stupor.model.FinishedMessageAboutObject; import org.stupor.model.MessageAboutObject; import org.stupor.model.SynchroMessage; import org.stupor.service.UDPMessageProcessor; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Arrays; @Service public class UDPServer { private static final int PORT = 9098; private final UDPMessageProcessor messageProcessor; public UDPServer(UDPMessageProcessor messageProcessor) { this.messageProcessor = messageProcessor; new Thread(this::start).start(); } public static String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02X ", b)); } return sb.toString().trim(); } public void start() { try (DatagramSocket socket = new DatagramSocket(PORT)) { System.out.println("UDP сервер запущен на порту " + PORT); while (true) { byte[] buffer = new byte[1024]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); socket.receive(packet); int length = packet.getLength(); // Копируем ровно те байты, что пришли (без пустоты из конца buffer) byte[] data = Arrays.copyOf(buffer, length); // Для отладки System.out.println("Получены данные: " + Arrays.toString(data)); System.out.println("Полученные данные (Hex): " + bytesToHex(data)); System.out.println("Полный пакет: " + Arrays.toString(data)); /* * Предположим, что первые 4 байта (0..3) — это не «настоящие» данные, * а заголовок (10 02 3A 03). Тогда сам тип сообщения находится в байте [4]. * Если у вас он реально лежит в [7] (как было раньше), * значит надо сдвигать не на 4, а на 7 (или иные значения, в зависимости от протокола). */ // Пример: тип сообщения лежит в data[4] int typeMessage = data[4] & 0xFF; System.out.println("Определённый тип сообщения: " + typeMessage); System.out.println("Ожидаемые типы: 1 (объект), 2 (окончание), 3 (синхро)"); switch (typeMessage) { case 1: { // Парсим сообщение об объекте. // Создадим ByteBuffer c Little Endian, пропустив «заголовочные» байты (4 штуки). ByteBuffer bb = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN); // Ниже — ПРИМЕРНЫЕ смещения! // Если после 4 байт заголовка сразу идёт typeMessage (1 байт), // то далее поля идут так: // [5..8] (4 байта) => numberOfMessages // [9..12] (4 байта) => numberObject // [13..20] (8 байт) => latitude // [21..28] (8 байт) => longitude // [29..32] (4 байта) => altitude // [33..36] (4 байта) => speed // [37..40] (4 байта) => course // [41] (1 байт) => typeTarget // [42..45] (4 байта) => epr // [46] (1 байт) => updateTarget // [47..54] (8 байт) => time // и т.д. // Точные офсеты зависят от реального формата вашего пакета! int typeMessage2 = Byte.toUnsignedInt(bb.get(4)); // байт [4] int numberOfMessages = bb.getInt(5); // байты [5..8] int numberObject = bb.getInt(9); // байты [9..12] double latitude = bb.getDouble(13); // байты [13..20] double longitude = bb.getDouble(21); // байты [21..28] int altitude = bb.getInt(29); // байты [29..32] float speed = bb.getFloat(33); // байты [33..36] float course = bb.getFloat(37); // байты [37..40] int typeTarget = Byte.toUnsignedInt(bb.get(41)); // байт [41] float epr = bb.getFloat(42); // байты [42..45] int updateTarget = Byte.toUnsignedInt(bb.get(46)); // байт [46] double time = bb.getDouble(47); // байты [47..54] // Выводим для проверки System.out.println("Тип сообщения: " + typeMessage2); System.out.println("Счетчик сообщений: " + numberOfMessages); System.out.println("Номер объекта: " + numberObject); System.out.println("Широта: " + latitude); System.out.println("Долгота: " + longitude); System.out.println("Высота: " + altitude); System.out.println("Скорость: " + speed); System.out.println("Курс: " + course); System.out.println("Код типа цели: " + typeTarget); System.out.println("ЭПР: " + epr); System.out.println("Признак новой цели: " + updateTarget); System.out.println("Время: " + time); // Можно собрать свой объект. Либо использовать ваш MessageParser. MessageAboutObject objectMessage = new MessageAboutObject( typeMessage2, numberOfMessages, numberObject, latitude, longitude, altitude, speed, course, typeTarget, epr, updateTarget, time ); // Отправляем дальше в вашу логику messageProcessor.processMessage(objectMessage); break; } case 2: { FinishedMessageAboutObject finishedMessage = MessageParser.parseFinishedMessage(data); System.out.println("Сообщение об окончании: " + finishedMessage); messageProcessor.processMessage(finishedMessage); break; } case 3: { SynchroMessage syncMessage = MessageParser.parseSynchroMessage(data); System.out.println("Синхросообщение: " + syncMessage); messageProcessor.processMessage(syncMessage); break; } default: System.out.println("Неизвестный тип сообщения: " + typeMessage); break; } } } catch (Exception e) { e.printStackTrace(); } } }
Leave a Comment