Структура данных содержит ровно две строки (R и T), завершаемые переносом строки \r\n, которые отправляются последовательно. После задержки по времени ок. полсекунды отправляются следующие две строки. Я могу проверить это, используя, например. Шпаклевка. Таким образом, выходные данные Putty похожи на поток данных, в котором всегда принимается связка из двух строк, разделенных задержкой:
$WIMWV,357.0,R,5.2,M,A*1A\r\n
$WIMWV,123.0,T,5.2,M,A*1A\r\n
//time delay ~0.5s
$WIMWV,357.0,R,5.2,M,A*1A\r\n
$WIMWV,123.0,T,5.2,M,A*1A\r\n
//time delay ~0.5s
and so on ...
Выглядит отлично! Теперь я хотел бы использовать этот поток данных на основе собственного Java-сервиса. Процедура чтения из сокета выделена в поток. Вот минимальный пример:
Main.java:
public class Main {
public static void main(String[] args) throws InterruptedException {
Receiver receiver = new Receiver(args[0], Integer.parseInt(args[1]));
Thread t = new Thread(receiver);
t.setDaemon(true);
t.start();
while(true) {
//Do something else in main app ...
Thread.sleep(1000);
}
}
}
12:40:22.354 INFO o.e.R -- Time: 2026-04-17T12:40:22.354808600Z, Message: $WIMWV,171.8,R,0.3,M,A*2C
12:40:22.354 INFO o.e.R -- Time: 2026-04-17T12:40:22.354808600Z, Message: $WIMWV,175.1,T,0.7,M,A*23
12:40:22.354 INFO o.e.R -- Time: 2026-04-17T12:40:22.354808600Z, Message: $WIMWV,153.7,R,0.2,M,A*22
12:40:22.354 INFO o.e.R -- Time: 2026-04-17T12:40:22.354808600Z, Message: $WIMWV,172.3,T,0.8,M,A*29
12:40:23.359 INFO o.e.R -- Time: 2026-04-17T12:40:23.359554800Z, Message: $WIMWV,156.3,R,0.3,M,A*22
12:40:23.359 INFO o.e.R -- Time: 2026-04-17T12:40:23.359554800Z, Message: $WIMWV,172.3,T,0.9,M,A*28
12:40:23.359 INFO o.e.R -- Time: 2026-04-17T12:40:23.359554800Z, Message: $WIMWV,148.2,R,0.4,M,A*2B
12:40:23.359 INFO o.e.R -- Time: 2026-04-17T12:40:23.359554800Z, Message: $WIMWV,166.5,T,1.0,M,A*23
12:40:24.348 INFO o.e.R -- Time: 2026-04-17T12:40:24.348462800Z, Message: $WIMWV,143.4,R,0.5,M,A*27
12:40:24.348 INFO o.e.R -- Time: 2026-04-17T12:40:24.348462800Z, Message: $WIMWV,162.8,T,1.1,M,A*2B
12:40:24.348 INFO o.e.R -- Time: 2026-04-17T12:40:24.348462800Z, Message: $WIMWV,124.6,R,0.5,M,A*24
12:40:24.348 INFO o.e.R -- Time: 2026-04-17T12:40:24.348462800Z, Message: $WIMWV,155.4,T,1.0,M,A*22
Это означает, что я всегда получаю связку из четырех строк с одной и той же нано-временной меткой - даже временная карта логгера идентична. В результате временные метки половины данных каким-то образом смещаются (по сравнению с выводом Putty). Может ли кто-нибудь объяснить такое поведение? Имеет ли это какое-либо отношение к каким-либо буферам сокета? Есть ли какие-либо параметры для сокета, которые мне нужно установить?
Цель состоит в том, чтобы получить поток данных точно так же, как Putty, включая временные задержки. Я хотел бы пометить предложения системным временем, поскольку этот тип данных NMEA не включает в себя собственную временную метку; поэтому мне нужна задержка.
Дополнение (версии Java и зависимости):
У меня есть внешний датчик погоды, который периодически передает построчные данные NMEA: [code]$WIMWV,357.0,R,5.2,M,A*1A\r\n$WIMWV,123.0,T,5.2,M,A*1A\r\n [/code] Структура данных содержит ровно [b]две[/b] строки (R и T), завершаемые переносом строки \r\n, которые отправляются последовательно. После задержки по времени ок. полсекунды отправляются следующие две строки. Я могу проверить это, используя, например. Шпаклевка. Таким образом, выходные данные Putty похожи на поток данных, в котором всегда принимается связка из двух строк, разделенных задержкой: [code]$WIMWV,357.0,R,5.2,M,A*1A\r\n $WIMWV,123.0,T,5.2,M,A*1A\r\n //time delay ~0.5s $WIMWV,357.0,R,5.2,M,A*1A\r\n $WIMWV,123.0,T,5.2,M,A*1A\r\n //time delay ~0.5s and so on ... [/code] Выглядит отлично! Теперь я хотел бы использовать этот поток данных на основе собственного Java-сервиса. Процедура чтения из сокета выделена в поток. Вот минимальный пример: Main.java: [code]public class Main { public static void main(String[] args) throws InterruptedException {
Receiver receiver = new Receiver(args[0], Integer.parseInt(args[1])); Thread t = new Thread(receiver); t.setDaemon(true); t.start();
while(true) { //Do something else in main app ... Thread.sleep(1000); } } } [/code] Receiver.java: [code]package org.example;
while (running) { try { log.info("Try to connect to {}:{}", hostname, port); socket = new Socket(hostname, port); socket.setTcpNoDelay(true);
InputStreamReader isr = new InputStreamReader(socket.getInputStream()); StringBuilder line = new StringBuilder(); int ch; while ((ch = isr.read()) != -1) { if (ch == '\n') { log.info("Time: {}, Message: {}", getNanoTime(), line.toString()); // Do something with line.toString() line = new StringBuilder(); } else if (ch != '\r') { // CR ignorieren line.append((char) ch); } }
//Time delay for reconnect try { Thread.sleep(10000); } catch (InterruptedException e) { log.error("InterruptedException at: {}", e.toString()); } } log.warn("TCPLineReceiver stopped for {}:{}", hostname, port); } } [/code] Теперь вывод в консоль/регистратор выглядит следующим образом: [code]12:40:22.354 INFO o.e.R -- Time: 2026-04-17T12:40:22.354808600Z, Message: $WIMWV,171.8,R,0.3,M,A*2C 12:40:22.354 INFO o.e.R -- Time: 2026-04-17T12:40:22.354808600Z, Message: $WIMWV,175.1,T,0.7,M,A*23 12:40:22.354 INFO o.e.R -- Time: 2026-04-17T12:40:22.354808600Z, Message: $WIMWV,153.7,R,0.2,M,A*22 12:40:22.354 INFO o.e.R -- Time: 2026-04-17T12:40:22.354808600Z, Message: $WIMWV,172.3,T,0.8,M,A*29 12:40:23.359 INFO o.e.R -- Time: 2026-04-17T12:40:23.359554800Z, Message: $WIMWV,156.3,R,0.3,M,A*22 12:40:23.359 INFO o.e.R -- Time: 2026-04-17T12:40:23.359554800Z, Message: $WIMWV,172.3,T,0.9,M,A*28 12:40:23.359 INFO o.e.R -- Time: 2026-04-17T12:40:23.359554800Z, Message: $WIMWV,148.2,R,0.4,M,A*2B 12:40:23.359 INFO o.e.R -- Time: 2026-04-17T12:40:23.359554800Z, Message: $WIMWV,166.5,T,1.0,M,A*23 12:40:24.348 INFO o.e.R -- Time: 2026-04-17T12:40:24.348462800Z, Message: $WIMWV,143.4,R,0.5,M,A*27 12:40:24.348 INFO o.e.R -- Time: 2026-04-17T12:40:24.348462800Z, Message: $WIMWV,162.8,T,1.1,M,A*2B 12:40:24.348 INFO o.e.R -- Time: 2026-04-17T12:40:24.348462800Z, Message: $WIMWV,124.6,R,0.5,M,A*24 12:40:24.348 INFO o.e.R -- Time: 2026-04-17T12:40:24.348462800Z, Message: $WIMWV,155.4,T,1.0,M,A*22 [/code] Это означает, что я всегда получаю связку из [b]четырех[/b] строк с одной и той же нано-временной меткой - даже временная карта логгера идентична. В результате временные метки половины данных каким-то образом смещаются (по сравнению с выводом Putty). Может ли кто-нибудь объяснить такое поведение? Имеет ли это какое-либо отношение к каким-либо буферам сокета? Есть ли какие-либо параметры для сокета, которые мне нужно установить? Цель состоит в том, чтобы получить поток данных точно так же, как Putty, включая временные задержки. Я хотел бы пометить предложения системным временем, поскольку этот тип данных NMEA не включает в себя собственную временную метку; поэтому мне нужна задержка. Дополнение (версии Java и зависимости): [code] 17 ${version.java} ${version.java} UTF-8 1.5.32 2.0.17 3.15.0 3.6.2 3.5.0
[/code] Я использовал OpenJDK 17.0.18 и Maven 3.9.14