0

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

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

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

我的问题是:

  1. 如何解析此响应?
  2. 除了我的这种方法之外,我想知道是否还有其他推荐的方法可以实现这一目标。

提前致谢。

4

2 回答 2

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 running()。NTP 会纠正漂移的时钟,但需要几分钟来确定所需的班次。

EDIT2:虽然 RFC 868 很旧,但将手机上的时间设置为最接近的秒数可能就足够了,而无需后台进程。如果您的手机可以同步到您的提供商发送的信号,则不需要这样做。

于 2012-04-06T15:17:47.113 回答
2

1)我如何解析这个响应?

查看来自 Apache Commons Net 库的 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,查看TimeTCPClient 的 API

Apache Commons Net 主页,希望对您有所帮助。

于 2012-04-06T11:32:06.900 回答