DatagramPacket getData()不起作用
问题描述:
我试图使用下面的代码从nist.gov服务器获取时间戳。DatagramPacket getData()不起作用
InetAddress addr = InetAddress.getByName("129.6.15.30");
DatagramSocket s = new DatagramSocket();
System.out.println("Connected to: "+addr.getHostName());
byte[] buf = new byte[4];
DatagramPacket p = new DatagramPacket(buf, buf.length, addr, 37);
s.send(p);
System.out.println("message sent");
DatagramPacket dp = new DatagramPacket(buf, buf.length);
s.receive(dp);
String data = new String(dp.getData(), 0, dp.getLength());
System.out.println("Received: "+data);
当我在Eclipse上运行它时,我在控制台中得到以下结果。
Connected to: time-c.nist.gov
message sent
Received: ÛÏÌ<
好消息是,我连接到正确的服务器并获取数据包。但是,我似乎无法将该数据包的数据转换为该数据的可理解表示。我错过了什么?
答
来自时间协议的响应是网络字节顺序中的32位整数 - 这是而不是的一个字符串。
要阅读它,你需要使用类似DataInputStream
:
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(dp.getData(), 0, dp.getLength()));
int time = dis.readInt();
dis.close();
返回的时间值是自1900年1月1日的秒数,从此获得一个Java Instant
我们需要将无符号整数转换到标准Java'epoch'这是自1970年1月1日以来的秒数:
long secondsSince1Jan1900 = Integer.toUnsignedLong(time);
long differenceBetweenEpochs = 2208988800L;
long secondsSince1Jan1970 = secondsSince1Jan1900 - differenceBetweenEpochs;
Instant instant = Instant.ofEpochSecond(secondsSince1Jan1970);
这肯定有帮助,因为我的新收到的输出是收到:-607100146。现在,想出如何将其转换为标准格式的时间戳。 – MPeal
将转换添加到'Instant' –
谢谢格雷格,因为这工作,我立即得到了后续输出:2016-11-11T18:27:50Z。虽然我感谢你的回答,但我不想只说:“太棒了!这个人帮我做了!”我很好奇的是2208988800之后'L'的意思。我知道2208988800是1/1/1900到1/1/1970之间的秒数,但是什么是L(原谅我,我已经只用了4.5个月的Java编码,有时候这样的小细节也会让我有点逃避)。 – MPeal