2016-11-11 33 views
0

我试图使用下面的代码从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: ÛÏÌ< 

好消息是,我连接到正确的服务器并获取数据包。但是,我似乎无法将该数据包的数据转换为该数据的可理解表示。我错过了什么?

回答

0

来自时间协议的响应是网络字节顺序中的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); 
+0

这肯定有帮助,因为我的新收到的输出是收到:-607100146。现在,想出如何将其转换为标准格式的时间戳。 – MPeal

+0

将转换添加到'Instant' –

+0

谢谢格雷格,因为这工作,我立即得到了后续输出:2016-11-11T18:27:50Z。虽然我感谢你的回答,但我不想只说:“太棒了!这个人帮我做了!”我很好奇的是2208988800之后'L'的意思。我知道2208988800是1/1/1900到1/1/1970之间的秒数,但是什么是L(原谅我,我已经只用了4.5个月的Java编码,有时候这样的小细节也会让我有点逃避)。 – MPeal