我正在寻找一种简单的时钟同步协议,它很容易实现,占用空间小,并且在没有互联网连接的情况下也可以工作,这样它就可以在封闭的实验室网络中使用。需要说明的是,我要找的不是可以用来对事件进行排序的东西(比如矢量时钟),而是可以让不同节点上的进程根据本地时钟同步它们的操作的东西。据我所知,这需要一个可以考虑时钟漂移的解决方案。可以假定存在TCP/IP或类似的相对低延迟的流连接。
发布于 2011-05-19 13:38:18
免责声明:无论如何我都不是NTP专家。只是一个业余爱好者在周末找乐子。
我知道您说过您不想要NTP实现,因为您的环境中可能没有可用的Internet NTP服务器。
但是,简化的NTP查找可能很容易实现,如果您有本地NTP服务器,则可以实现良好的同步。
下面是操作步骤:
回顾RFC 5905
您将看到NTP v4数据包如下所示:
H110轮询(8 bits)
H116根分散(32 bits)
H122原始时间戳(64位)(64 bits)
摘要不是必需的,因此形成有效的客户端请求非常容易。按照RFC中的指导,使用LI = '00',VN = '100‘(十进制4),Mode = '011’(十进制3)。
使用C#来说明:
byte[] ntpData = new byte[48]
Array.Clear(ntpData, 0, ntpData.Length);
ntpData[0] = 0x23; // LI = 00, VN = 100, Mode = 011
打开到目标服务器的套接字并将其发送过来。
int ntpPort = 123;
IPEndPoint target = new IPEndPoint(Dns.GetHostEntry(serverDnsName).AddressList[0], ntpPort);
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
s.Connect(target);
s.Send(ntpData);
在响应中,当前时间将在传输时间戳中(字节40 - 48)。时间戳是64位无符号定点数字。整数部分是前32位,小数部分是最后32位。它表示从1900年1月1日0h开始的秒数。
s.Receive(ntpData);
s.Close();
ulong intPart = 0;
ulong fractPart = 0;
for (int i = 0; i < 4; i++)
intPart = (intPart << 8) | ntpData[40 + i];
for (int i = 4; i < 8; i++)
fractPart = (fractPart << 8) | ntpData[40 + i];
要以(大致)秒的粒度更新时钟,可以使用:# of use 0hJan-1-1900= intPart + (fractPart / 2^32)。(我说大致是因为没有考虑网络延迟,我们在这里进行四舍五入)
ulong seconds = intPart + (fractPart / 4294967296);
TimeSpan ts = TimeSpan.FromTicks((long)seconds * TimeSpan.TicksPerSecond);
DateTime now = new DateTime(1900, 1, 1);
now = DateTime.SpecifyKind(now, DateTimeKind.Utc);
now += ts;
" now“现在是具有当前时间的DateTime,单位为UTC。
虽然这可能不能回答您的问题,但希望它能让NTP不那么不透明。=)
发布于 2011-05-19 21:42:48
仅基于维基百科的文章,我就能够非常快速和轻松地实现精确时间协议的精简版本。如果你所感兴趣的是使它们彼此同步,而不是让它们与外部世界同步,那么你应该能够以最小的努力获得毫秒级的精度。
该协议的基本内容包括:
如果您需要更好的稳定性,您可以实现锁相环或线性回归或类似的东西,以更好地控制您的抖动,并避免由于网络滞后而导致的大幅摆动。该协议还规定了许多更复杂的特性,但如果您想实现它们,则取决于“足够好”的程度。
发布于 2011-05-19 06:11:11
ntp是适合这项工作的工具。你不需要互联网连接,只需多花105美元和几个小时的生活,你甚至可以在没有互联网连接的情况下获得绝对时间基准的GPS同步,尽管这对你来说似乎并不重要。
忽略GPS同步的略微增加的复杂性,您可以使用一些配置文件行(每个客户端四行,服务器五行)与所选系统的时钟同步。在我的系统上,ntpd二进制文件是505kB。您还可以使用ntpdate,它可以定期运行以调整系统时钟(客户端上的零行配置,而不是使用正确的参数调用ntpdate应用程序)。这个二进制文件是80kb。有一个SNTP协议,它允许嵌入式应用程序占用更小的空间(与正常的ntp服务器对话)。还有一种称为chrony的备用NTP实现。
还有一个叫做rdate的程序(通常只在旧系统上运行,虽然source是可用的),它的工作方式有点像ntpdate,但精确度要低得多。您还需要一个RFC 868服务器,通常在inetd中提供。
唯一的另一种选择是已经提到的精确时间协议。
https://stackoverflow.com/questions/5642946
复制相似问题