python里使用socket实现时间同步

来源:互联网 发布:淘宝油画卖家 编辑:程序博客网 时间:2024/06/08 12:16

在这里通过一个最简单的时间协议来学习socket的使用,最古老的时间协议是RFC868,它的定义如下:

RFC文档中文翻译计划(http://www.china-pub.com/compters/emook/aboutemook.htm)


E-mail:ouyang@china-pub.com


译者:顾国飞(ggfei ggfei@263.net )


译文发布时间:2001-4-8


版权:本中文翻译文档版权归中国互动出版网所有。可以用于非商业用途自由转载,但必须保留本文档的翻译及版权信息。


Network Working Group J. Postel - ISI


Request for Comments: 868 K. Harrenstien - SRI


May 1983


RFC868 时间协议


(RFC868 Time Protocol)


本RFC规范了一个ARPA Internet community上的标准。在ARPA Internet上的所有主机应当采用和实现这个标准。


此协议提供了一个独立于站点的,机器可读的日期和时间信息。时间服务返回的是以秒数,是从1900年1月1日午夜到现在的秒数,天哪,也不小呢。


设计这个协议的一个重要目的在于,网络上的许多主机并没有时间的观念,在分布式的系统上,我们可以想一想,北京的时间和东京的时间如何分呢?主机的时间往往可以人为改变,而且因为机器时钟内的误差而变得不一致,因此需要使用时间服务器通过选举方式得到网络时间,让服务器有一个准确的时间观念。不要小看时间,这对于一些以时间为标准的分布运行的程序简单是太重要了。


这个协议可以工作在TCP和UDP协议下。下面是通过TCP协议工作的时间协议的工作过程:这里S代表服务器,C代表客户。


S: 检测端口37


U: 连接到端口37


S: 以32位二进制数发送时间


U: 接收时间


U: 关闭连接


S: 关闭连接


服务器在端口37上监听连接。当连接建立后,服务器返回一个32位的时间值,然后关闭连接。这个过程也不难,如果服务器不能决定现在是什么时间,服务器会拒绝连接或不发送任何数据而直接关闭连接。


下面我们看看使用UDP协议的情况:这里S代表服务器,C代表客户。


S: 检测端口37


U: 发送一个空数据报到端口37


S: 接收这个空数据报


S: 发送包含32位二进制数(用于表示时间)的数据报


U: 接收时间数据报


服务器在端口37上监听数据包。当一个数据包来后,服务器返回一个包含32位的时间的数据包。这个过程也不难,如果服务器不能决定现在是什么时间,服务器会抛弃接收到的数据报而不作出任何应答。


* 时间


时间是由32位表示的,是自1900年1月1日0时到当前的秒数,我们可以计算一下,这个协议只能表示到2036年就不能用了。(但是我们也知道计算机发展速度这么快,可能到时候就会有更好的协议代替这个协议,或者有已经想出有效的解决办法了。)


下面是


些例子:


the time 2,208,988,800 corresponds to 00:00 1 Jan 1970 GMT,


2,398,291,200 corresponds to 00:00 1 Jan 1976 GMT,


2,524,521,600 corresponds to 00:00 1 Jan 1980 GMT,


2,629,584,000 corresponds to 00:00 1 May 1983 GMT,


以及 -1,297,728,000 corresponds to 00:00 17 Nov 1858 GMT.


RFC868-Time Protocol RFC868 时间协议


1


1


中文文档翻译计划


下面的客户端实现时间协议,从时间服务器获取当前时间返回,并解释打印出来,其实就可以利用这么简单的协议来同步你的树莓派电脑的时间。协议比较简单主要接收4个字节即可。

# File: socket-example-1.pyimport socketimport struct, time# serverHOST = "time.nist.gov"PORT = 37# reference time (in seconds since 1900-01-01 00:00:00)TIME1970 = 2208988800 # 1970-01-01 00:00:00# connect to servers = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect((HOST, PORT))# read 4 bytes, and convert to time valuet = s.recv(4)t = struct.unpack("!I", t)[0]t = int(t - TIME1970)s.close()# print resultsprint("server time is", time.ctime(t))print("local clock is", int(time.time()) - t, "seconds off")
输出结果如下:


======= RESTART: D:/work/csdn/python_Game1/example/socket-example-1.py =======
server time is Fri Sep  1 18:31:50 2017
local clock is -269 seconds off
>>> 

Python游戏开发入门

http://edu.csdn.net/course/detail/5690

你也能动手修改C编译器

http://edu.csdn.net/course/detail/5582

纸牌游戏开发

http://edu.csdn.net/course/detail/5538 

五子棋游戏开发

http://edu.csdn.net/course/detail/5487
RPG游戏从入门到精通
http://edu.csdn.net/course/detail/5246
WiX安装工具的使用
http://edu.csdn.net/course/detail/5207
俄罗斯方块游戏开发
http://edu.csdn.net/course/detail/5110
boost库入门基础
http://edu.csdn.net/course/detail/5029
Arduino入门基础
http://edu.csdn.net/course/detail/4931
Unity5.x游戏基础入门
http://edu.csdn.net/course/detail/4810
TensorFlow API攻略
http://edu.csdn.net/course/detail/4495
TensorFlow入门基本教程
http://edu.csdn.net/course/detail/4369
C++标准模板库从入门到精通 
http://edu.csdn.net/course/detail/3324
跟老菜鸟学C++
http://edu.csdn.net/course/detail/2901
跟老菜鸟学python
http://edu.csdn.net/course/detail/2592
在VC2015里学会使用tinyxml库
http://edu.csdn.net/course/detail/2590
在Windows下SVN的版本管理与实战 
http://edu.csdn.net/course/detail/2579
Visual Studio 2015开发C++程序的基本使用 
http://edu.csdn.net/course/detail/2570
在VC2015里使用protobuf协议
http://edu.csdn.net/course/detail/2582
在VC2015里学会使用MySQL数据库
http://edu.csdn.net/course/detail/2672



原创粉丝点击