大量的设备连接到互联网,而设备之间需要通讯以及相互协作,这就要求不同设备之间需要保持时钟同步。然而无论是多么精准的时钟,一旦运行久了后,它指示的时间与真实时间会产生偏差,在假设不同设备启动时时间初始化不同,这就很难保证不同设备之间的时钟频率还能够保持一致。
TCP/IP协议在创建时就已经意识到,不同设备间一旦时钟不同频就可能导致相互协作出现问题。于是就想构造出一套协议让不同设备间相互协商,然后确保设备间在时间上能保持步调一致,而这个任务就落到ICMP协议头上。
发起同步的设备产生一个时间戳,然后利用ICMP消息体和协议规则,将时间戳发送给接收设备,这就是一个timestamp request消息。接收设备收到消息后返回自己的时间戳,这就是timestamp reply 消息。发出者的时间戳和接收者的时间戳就可以让两个设备之间保持时钟同步。
产生ICMP timestamp 消息的应用叫hping,一般来说系统可能不自带,需要我们自行安装,我们macos上安装hping后就可以通过下面命令产生timestamp消息:
sudo hping 192.168.2.1 --icmp --icmp-ts -V
通过wireshark抓包就可以看到消息发送和接收状况:
我们看看timestamp消息的结构:
它其实是我们上次实现ping应用的翻版,只不过多加了几个数据项。其中它的type值域对于request来说要设置成12,对于reply要设置成14,sequence number 和identifier 意义与上一节描述的一样,original timestamp 用于发起者填写自己的当前时间,接下来的两个时间戳由接收者填写,Receive timestamp是接收者收到消息时的时间,Transmit timestamp是接收者回发消息时的时间。
这里可能让人有点出乎意料的是,返回消息中包含两个时间戳而不是一个。这是因为发起者收到返回消息后,它能知道发出消息的接收时间和回应消息的发出时间,这样发起者就能知道消息传达到指定设备需要的时间,从而对当前网络流量有了解,同时指定收到设备的消息处理速度,从而能够根据具体情况决定下面消息发送的速度和流量。
我们看看消息组成的数据格式:
在实践上,即使有这样的协议,不同设备之间的同频依然难以实现。因为ICMP基于IP之上&#