解析二进制响应

时间:2012-04-06 09:38:41

标签: java android sockets

我正在尝试构建一个示例应用程序,它将显示一个概念验证,以便将时间与符合RFC 868的时间服务器同步。

到目前为止,使用Java Socket API,我能够连接和查询服务器并从服务器获得响应,但它不是人类可读的格式。

我得到的回应是:�)6我认为响应是二进制格式的(尽管不确定)。 RFC 868Send the time as a 32 bit binary number

我的问题是: 1)如何解析此响应? 2)除了我的这种方法之外,我想知道是否还有其他推荐的方法来实现这一点。

提前致谢。

2 个答案:

答案 0 :(得分:2)

  

1)如何解析此响应?

从Apache Commons Net库中查看source code of TimeTCPClient

public long getTime() throws IOException {
  DataInputStream input;
  input = new DataInputStream(_input_);
  return (input.readInt() & 0xffffffffL);
}

public Date getDate() throws IOException {
  return new Date((getTime() - SECONDS_1900_TO_1970)*1000L);
}
  

2)除了我的这种方法之外,我想知道是否还有其他推荐方法可以实现这一目标。

使用Apache Commons Net Library,查看API of TimeTCPClient

Apache Commons Net home page,希望这有帮助。

答案 1 :(得分:2)

如RFC中所述,这是自1900-01-01T00:00:00以来的秒数。对于Java将其转换为Long,将基准日期更改为1970-01-01T00:00:00,并乘以1000以获取日期。然后,您可以使用此值创建新日期。

将套接字输入流包装到DataInputStream并读入rfsOffset(我使用常量)。然后你可以做类似的事情:

int rfcOffset = -752253627; // Fri Apr 06 11:00:32 EDT 2012
// Current offsets will be negative convert to long positive value
long offsetSecs = rfcOffset + 4294967296L; 
System.out.println(offsetSecs);
// Adjust time base from 1900 to 1970 and convert to millis
long offsetMillis = ( offsetSecs - 2208988800L)* 1000L; 
System.out.println(offsetMillis);
Date rfcDate = new Date(offsetMillis);
System.out.println(rfcDate.toString());

注意:这仅适用于2036年,时间将关闭几毫秒。

编辑:RFC 868是一种旧协议,不再被认为是同步的好时间源。 NTP是一个很好的时间源,并将返回正确的秒。它可能会在几毫秒内消失,但通常精确到10毫秒。许多硬件时钟漂移很明显,我看到时钟不准确的系统出现了明显的漂移(即使NTP运行().NTP将纠正漂移时钟,但需要几分钟来确定所需的移位。

EDIT2:虽然RFC 868已经过时,但可以将手机上的时间设置为最接近的秒数,而无需后台处理。如果您的手机可以同步到您的提供商发送的信号,则不需要这样做。