6.4ICMP时间戳请求与应答ICMP时间戳请求允许系统向另一个系统查询当前的时间。返回的建议值是自午夜开始计算的毫秒数,协调的统一时间(CoordinatedUniversalTime,UTC)(早期的参考手册认为UTC是格林尼治时间)。这种ICMP报文的好处是它提供了毫秒级的分辨率,而利用其他方法从别的主机获取的时间(如某些Unix系统提供的rdate命令)只能提供秒级的分辨率。由于返回的时间是从午夜开始计算的,因此调用者必须通过其他方法获知当时的日期,这是它的一个缺陷。ICMP时间戳请求和应答报文格式如图6-6所示。图6-6ICMP时间戳请求和应答报文请求端填写发起时间戳,然后发送报文。应答系统收到请求报文时填写接收时间戳,在发送应答时填写发送时间戳。但是,实际上,大多数的实现把后面两个字段都设成相同的值(提供三个字段的原因是可以让发送方分别计算发送请求的时间和发送应答的时间)。6.4.1举例我们可以写一个简单程序(取名为icmptime),给某个主机发送ICMP时间戳请求,并打印出返回的应答。它在我们的小互联网上运行结果如下:程序打印出ICMP报文中的三个时间戳:发起时间戳(orig)、接收时间戳(recv)以及发送时间戳(xmit)。正如我们在这个例子以及下面的例子中所看到的那样,所有的主机把接收时间戳和发送时间戳都设成相同的值。我们还能计算出往返时间(rtt),它的值是收到应答时的时间值减去发送请求时的时间值。difference的值是接收时间戳值减去发起时间戳值。这些值之间的关系如图6-7所示。图6-7icmptime程序输出的值之间的关系如果我们相信RTT的值,并且相信RTT的一半用于请求报文的传输,另一半用于应答报文的传输,那么为了使本机时钟与查询主机的时钟一致,本机时钟需要进行调整,调整值是difference减去RTT的一半。在前面的例子中,bsdi的时钟比sun的时钟要慢7ms和8ms。由于时间戳的值是自午夜开始计算的毫秒数,即UTC,因此它们的值始终小于86400000(24×60×60×1000)。这些例子都是在下午4:00以前运行的,并且在一个比UTC慢7个小时的时区,因此它们的值比82800000(2300小时)要大是有道理的。如果对主机bsdi重复运行该程序数次,我们发现接收时间戳和发送时间戳的最后一位数总是0。这是因为该版本的软件(0.9.4版)只能提供10ms的时间分辨率(说明参见附录B)。如果对主机svr4运行该程序两次,我们发现SVR4时间戳的最后三位数始终为0:类型(13或14)代码(0)标识符检验和序列号20字节发起时间戳接收时间戳传送时间戳发起请求接收传送应答由于某种原因,SVR4在ICMP时间戳中不提供毫秒级的分辨率。这样,对秒以下的时间差调整将不起任何作用。如果我们对子网140.252.1上的其他主机运行该程序,结果表明其中一台主机的时钟与sun相差3.7秒,而另一个主机时钟相差近75秒:另一个令人感兴趣的例子是路由器gateway(一个Cisco路由器)。它表明,当系统返回一个非标准时间戳值时(不是自午夜开始计算的毫秒数,UTC),它就用32bit时间戳中的高位来表示。我们的程序证明了一点,在尖括号中打印出了接收和发送的时间戳值(在关闭高位之后)。另外,不能计算发起时间戳和接收时间戳之间的时间差,因为它们的单位不一致。如果我们在这台主机上运行该程序数次,会发现时间戳值显然具有毫秒级的分辨率,而且是从某个起始点开始计算的毫秒数,但是起始点并不是午夜UTC(例如,可能是从路由器引导时开始计数的毫秒数)。作为最后一个例子,我们来比较sun主机和另一个已知是准确的系统时钟—一个NTPstratum1服务器(下面我们会更多地讨论NTP,网络时间协议)。如果我们把difference的值减去RTT的一半,结果表明sun主机上的时钟要快38.5~51.5ms。6.4.2另一种方法还可以用另一种方法来获得时间和日期。1)在1.12节中描述了日期服务程序和时间服务程序。前者是以人们可读的格式返回当前的时间和日期,是一行ASCII字符。可以用telnet命令来验证这个服务:另一方面,时间服务程序返回的是一个32bit的二制进数值,表示自UTC,1900年1月1日午夜起算的秒数。这个程序是以秒为单位提供的日期和时间(前面我们提过的rdate命令使用的是TCP时间服务程序)。2)严格的计时器使用网络时间协议(NTP),该协议在RFC1305中给出了描述[Mills1992]。这个协议采用先进的技术来保证LAN或WAN上的一组系统的时钟误差在毫秒级以内。对计算机精确时间感兴趣的读者应该阅读这份RFC文档。3)开放软件基金会(OSF)的分布式计算环境(DCE)定义了分布式时间服务(DTS),它也提供计算机之间的时钟同步。文献[Rosenberg,KenneyandFisher1992]提供了该服务的其他细节描述。4)伯克利大学的Unix系统提供守护程序timed(8),来同步局域网上的系统时钟。不像NTP和DTS,timed不在广域网范围内工作。前三行是Telnet客户的输出这是日期时间服务器的输出这也是Telnet客户的输出