Использование Nano-Timestamp при построчном чтении из сокетаJAVA

Программисты JAVA общаются здесь
Anonymous
Использование Nano-Timestamp при построчном чтении из сокета

Сообщение Anonymous »

У меня есть программное обеспечение, которое реализует собственный сервер сокетов и предлагает через порт 5555 построчные предложения (например, данные NMEA).

Код: Выделить всё

package org.example;

import java.io.*;
import java.net.*;

public class NMEASocketServer {

static String nmeaSentence = "$WIMWV,357.0,R,5.2,M,A*1A\r\n$WIMWV,123.0,T,5.2,M,A*1A\r\n";

static void main(String[] args) {

try (ServerSocket serverSocket = new ServerSocket(5555)) {
System.out.println("Waiting...");

Socket clientSocket = serverSocket.accept();
System.out.println("Client connected: " + clientSocket.getInetAddress());

PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);

while (true) {
out.write(nmeaSentence);
out.flush();
System.out.print("Sending NMEA sentence: " + nmeaSentence);
Thread.sleep(500);
}
} catch (Exception e) {
System.out.println("Socket-Error: " + e.getMessage());
e.printStackTrace();
}
}
}
Затем у меня есть клиент, который подключается к этому серверу (работающему на той же машине) и потребляет построчные данные. Клиент распечатывает данные в т.ч. текущая временная метка в нано.

Код: Выделить всё

package org.example;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.time.Instant;
import java.time.temporal.ChronoUnit;

public class Main {

private static String getNanoTime() {
return String.valueOf(Instant.now().truncatedTo(ChronoUnit.NANOS));
}

static void main() throws IOException {
Socket socket = new Socket("localhost", 5555);
socket.setTcpNoDelay(true);
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
StringBuilder sb = new StringBuilder();
int ch;
while ((ch = isr.read()) != -1) {
if (ch == '\n') {
System.out.println(getNanoTime() + " " + sb.toString());
sb = new StringBuilder();
} else if (ch != '\r') {
sb.append((char) ch);
}

}
}
}
Вывод, например:

Код: Выделить всё

2026-04-16T18:09:55.375949100Z $WIMWV,357.0,R,5.2,M,A*1A
2026-04-16T18:09:55.376947700Z $WIMWV,123.0,T,5.2,M,A*1A
2026-04-16T18:09:55.877866900Z $WIMWV,357.0,R,5.2,M,A*1A
2026-04-16T18:09:55.877866900Z $WIMWV,123.0,T,5.2,M,A*1A
2026-04-16T18:09:56.378914500Z $WIMWV,357.0,R,5.2,M,A*1A
2026-04-16T18:09:56.379800300Z $WIMWV,123.0,T,5.2,M,A*1A
2026-04-16T18:09:56.880072500Z $WIMWV,357.0,R,5.2,M,A*1A
2026-04-16T18:09:56.880072500Z $WIMWV,123.0,T,5.2,M,A*1A
Итак, нано-временные метки двух предложений, отправленных вместе со стороны сервера, идентичны (например, выходные строки 3 и 4 или 7 и 8). Иногда между ними проходит несколько микросекунд (например, строки 1 и 2 или 5 и 6). Может кто-нибудь объяснить, реалистично ли такое поведение? Можно ли так быстро прочитать из сокета, построить строку и распечатать ее на System.out, чтобы эти две временные метки были идентичны?

Вернуться в «JAVA»