Untitled
unknown
plain_text
10 months ago
8.7 kB
4
Indexable
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();
}
}
}
Editor is loading...
Leave a Comment